|
Вопрос # 3 779/ вопрос открыт / |
|
Здравствуйте, уважаемые эксперты!
Мне необходимо из своей программы запустить приложение CyberLink PowerDVD. Пытаюсь я это сделать с помощью функции CreateProcess как показано в приложении. Результат - ничего и GetLastError выдает ошибку 998. Попытка запуска из командной строки тоже ни к чему не приводит. В чем может быть проблема?
Приложение: Переключить в обычный режим- procedure TForm1.startBluRayPlayer;
- var
- // http://www.delphirus.com/modules.php?name=News&file=article&sid=32
- applicationPath: PChar;
- stringOfParametrs: PChar;
- ProcessSecurityAttributes: TSecurityAttributes;
- ThreadSecurityAttributes: TSecurityAttributes;
- bInheritHandles: LongBool; // ôëàã
íàñëåäîâàíèÿ
òåêóùåãî
ïðîöåññà
- CreationFlags: Longword; // ôëàãè
ñïîñîáîâ
ñîçäàíèÿ
ïðîöåññà
- Environment: Pointer; //
óêàçàòåëü
íà áëîê
ñðåäû
- CurrentDirectory: PChar; // òåêóùèé
äèñê è
êàòàëîã
- StartupInfo:TStartupInfo; //
ñòðóêòóðà
STARTUPINFO
- ProcessInformation: TProcessInformation; //
ñòðóêòóðà
PROCESS_INFORMATION
-
- res: boolean;
- Error: integer;
- begin
- applicationPath := 'C:Program FilesCyberLinkPowerDVDPowerDVD.exe';
- stringOfParametrs := nil;
- bInheritHandles := false;
- CreationFlags := NORMAL_PRIORITY_CLASS;
- Environment := nil;
- CurrentDirectory := nil;
-
- StartupInfo.cb := SizeOf(TStartUpInfo);
- StartupInfo.lpReserved := nil;
- StartupInfo.dwX := 100;
- StartupInfo.dwY := 100;
- StartupInfo.dwXSize := 500;
- StartupInfo.dwXSize := 350;
- StartupInfo.cbReserved2 := 0;
- StartupInfo.lpReserved2 := nil;
-
- res := CreateProcess(applicationPath, stringOfParametrs, {ProcessSecurityAttributes} nil,
- {ThreadSecurityAttributes} nil, bInheritHandles, CreationFlags, Environment,
- CurrentDirectory, StartupInfo, ProcessInformation);
-
- if (res) then
- begin
- WaitForInputIdle(ProcessInformation.hProcess, INFINITE);
- CloseHandle(ProcessInformation.hThread); //
çàêðûâàåì
äåñêðèïòîð
ïðîöåññà
- CloseHandle(ProcessInformation.hProcess); //
çàêðûâàåì
äåñêðèïòîð
ïîòîêà
- end
- else
- Error := GetLastError;
- Memo1.Lines.Add(IntToStr(Error));
- end;
 |
Вопрос задал: AlexMPEI (статус: 1-ый класс)
Вопрос отправлен: 16 февраля 2010, 12:23
Состояние вопроса: открыт, ответов: 0.
|
Мини-форум вопроса
Всего сообщений: 9; последнее сообщение — 16 февраля 2010, 16:57; участников в обсуждении: 3.
|
Егор (статус: 10-ый класс), 16 февраля 2010, 13:34 [#1]:
а в гугле не пробовал набрать что-нить типа "GetLastError 998"?
Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.
— Donald E. Knuth.
|
|
Егор (статус: 10-ый класс), 16 февраля 2010, 13:37 [#2]:
ну, или CreateProcess GetLastError 998
Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.
— Donald E. Knuth.
|
|
Alexey6522 (статус: 1-ый класс), 16 февраля 2010, 14:36 [#3]:
CreateProcess обычно используется для создания процесса под другой учетной записью, а для запуска программ лучше всего использовать WinExec('путь_имя_файла', SW_NORMAL) или если нужно открыть папку с нужной директорией ShellExecute(Handle,'explore', 'c:\Program Files\Borland', nil,nil,SW_RESTORE);
|
|
AlexMPEI (статус: 1-ый класс), 16 февраля 2010, 14:47 [#4]:
998 - NO_ACCESS
добавил очистку
FillChar(StartUpInfo, SizeOf(TStartUpInfo), 0);
теперь CreateProcess возвращает true, но приложение по прежнему не запускается
|
|
Alexey6522 (статус: 1-ый класс), 16 февраля 2010, 15:20 [#5]:
Чувак, я ж тебе написал как проще всего запустить приложение!!!!
|
|
AlexMPEI (статус: 1-ый класс), 16 февраля 2010, 15:34 [#6]:
Я прочитал и попробовал. WinExec('путь_имя_файла', SW_NORMAL) сработал. CreateProcess тоже заработал, если выставить bInheritHandles в true.
Теперь проблема в том что если просто закрыть PowerDVD, то процесс остается в памяти и повторный запуск невозможен, хотя окно закрыто. Как с этим правильно поступить?
то Alexey6522: я не игнорю твои ответы, чувак, я проверяю все на практике + форум подглючивает - сообщения могут вклиниваться каким-то образом, когда я отправил ответ Егору твоего сообщения еще небыло, но потом оно вклинилось по времени.
|
|
Alexey6522 (статус: 1-ый класс), 16 февраля 2010, 16:00 [#7]:
вот что я нашел
uses
AccCtrl, AclAPI;
function GetOSVersion: Cardinal;
var
OSVersionInfo: TOSVersionInfo;
begin
Result:= 0;
FillChar(OSVersionInfo, Sizeof(OSVersionInfo), 0);
OSVersionInfo.dwOSVersionInfoSize:= SizeOf(OSVersionInfo);
if GetVersionEx(OSVersionInfo) then
begin
if OSVersionInfo.dwPlatformId = VER_PLATFORM_WIN32_NT then
begin
if OSVersionInfo.dwMajorVersion = 5 then
begin
if OSVersionInfo.dwMinorVersion = 0 then
Result:= 50
else if OSVersionInfo.dwMinorVersion = 2 then
Result:= 52
else if OSVersionInfo.dwMinorVersion = 1 then
Result:= 51
end;
if OSVersionInfo.dwMajorVersion = 6 then
begin
if OSVersionInfo.dwMinorVersion = 0 then
Result:= 60
else if OSVersionInfo.dwMinorVersion = 1 then
Result:= 61;
end;
end;
end;
end;
function RunAsSystem(ApplicationName: String): Boolean;
var
lpStartupInfo: TStartupInfo;
lpProcessInformation: TProcessInformation;
ppSecurityDescriptor: PPSecurity_Descriptor;
ppDacl: PACL;
hProcess, hToken: Cardinal;
begin
Result:= False;
if (GetOSVersion > 50) and (GetOSVersion < 60) then
hProcess:= OpenProcess(PROCESS_QUERY_INFORMATION, False, 4)
else
hProcess:= OpenProcess(PROCESS_QUERY_INFORMATION, False, 8);
if hProcess <> 0 then
begin
try
OpenProcessToken(hProcess, MAXIMUM_ALLOWED, hToken);
if hToken <> 0 then
begin
if GetSecurityInfo(hToken, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, nil, nil, @ppDacl, nil,
ppSecurityDescriptor) = ERROR_SUCCESS then
begin
if SetSecurityInfo(hToken, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, nil, nil, nil, nil) = ERROR_SUCCESS
then
begin
CloseHandle(hToken);
OpenProcessToken(hProcess, MAXIMUM_ALLOWED, hToken);
if hToken <> 0 then
begin
try
if ImpersonateLoggedOnUser(hToken) then
begin
ZeroMemory(@lpStartupInfo, SizeOf(lpStartupInfo));
lpStartupInfo.cb:= SizeOf(lpStartupInfo);
if CreateProcessAsUser(hToken, PChar(ApplicationName), '', nil, nil, False, CREATE_DEFAULT_ERROR_MODE,
nil, nil, lpStartupInfo, lpProcessInformation) then
Result:= True;
RevertToSelf;
end;
SetSecurityInfo(hToken, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, nil, nil, ppDacl, nil);
finally
CloseHandle(hToken);
end;
end;
end;
end;
end;
finally
CloseHandle(hProcess);
end;
end;
end;
использование функции
RunAsSystem('C:\Windows\run.exe');
У тебя не хватает closehandel
|
|
Alexey6522 (статус: 1-ый класс), 16 февраля 2010, 16:02 [#8]:
Попробуй добавить CloseHandle(HWND:THWND)
|
|
AlexMPEI (статус: 1-ый класс), 16 февраля 2010, 16:57 [#9]:
Спасибо, Алексей. Я уже решил использовать твою WinExec. а с процессом я справляюсь путем его убийства перед запуском очередной копии, используя функцию убийства процесса по имени exe.
function TForm1.KillTask(ExeFileName: string): Integer;
const
PROCESS_TERMINATE = $0001;
var
ContinueLoop: BOOL;
FSnapshotHandle: THandle;
FProcessEntry32: TProcessEntry32;
begin
Result := 0;
FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
while Integer(ContinueLoop) <> 0 do
begin
if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) =
UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFile) =
UpperCase(ExeFileName))) then
Result := Integer(TerminateProcess(
OpenProcess(PROCESS_TERMINATE,
BOOL(0),
FProcessEntry32.th32ProcessID),
0));
ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
end;
CloseHandle(FSnapshotHandle);
end;
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|