есть софт, который вполне корректно работает если его запустить изпод командного интерпретатора (находясь в его папке), и который падает со внутренней ошибкой (немогу пока понять то ли особенность софта, то ли вида его запуска вкупе с ОС) при любом другом способе запуска: пробовал батником с указанием параметра chdir, с обычным CreateProcess, с CreateProcess и заполнением параметра lpCurrentDirectory - нивкакую. какая может быть разница в запуске софта батником, CreateProcess и cmd.ехе? как полностью сэмулить запуск консоли если вариант CreateProcess ('command.com /c' + commandline) тоже не выдал нужного результата?
При запуске процесса из консоли cmd передает ему собственные хэндлы strin, stdout и stderr, чтобы вес вводимый/выводимый в программе текст показывался в том же окне, а не в новой консоли. Используется та же CreateProcess, но cmd добавляет флаг "Запускать в том же окне". Других отличий не знаю.
Если процесс консольный - то создавать без флага CREATE_NEW_CONSOLE. Если ГУИ - то сначала AllocConsole. p.S>Не может быть такого что процесс проверяет имя родительского процесса? CreateProcessA("cmd.exe /c proc.exe");
Есть еще такая тема... В каких-то из вариантов GetCommandLine возвращает строку с самим .exe-шников, а в каких-то - без. Так что если парсер командлайна писал идиот, то прога может падать на парсинге. Если она конечно вообще смотрит на командлайн)
сервис банально стартовал только если парентом его стартующего бинаря был explorer.exe CreateProcessA("cmd.exe /c proc.exe"); пробовал, не работает. программа стартует от имени моего софта, а не консоли\експлорера. Вопрос, как в своем софте при вызове CreateProcess сэмулировать (желительно без инжектов, создания ярлыков и эмуляции нажатия на клаву) что его парент explorer.exe, а не мой софт? NtCreateProcess(Explorer_Handle), как именно, или еще какие идеи?
loleg >как в своем софте при вызове CreateProcess сэмулировать что его парент explorer.exe, а не мой софт? Использовать атрибут PROC_THREAD_ATTRIBUTE_PARENT_PROCESS в структуре STARTUPINFOEX при вызове CreateProcess. Нужно иметь хендл "псевдо-родительного" процесса, открытый с соответствующими правами. От псевдо-родителя наследуются хендлы, джоб и всё такое. Vista+. proteus00 Как насчёт немного дебаггера? Ну или перед этим попробовать ShellExecuteEx – окей, всё так или иначе придёт к CreateProcess, но всё же? Или опять-таки пользовать вариант с PROC_THREAD_ATTRIBUTE_PARENT_PROCESS.
Sol_Ksacap, набросал код, но в чем-то косяк Код (Text): #include "stdafx.h" #include "windows.h" #include "winbase.h" #include "crtdbg.h" int _tmain(int argc, _TCHAR* argv[]) { STARTUPINFOEX sieStartupInfo = {0}; DWORD sizeToAlloc; DWORD sizeOfBuffer; HANDLE hParProcess; sizeToAlloc = 0x1000; WCHAR szCmdLine[] = L"calc"; PROCESS_INFORMATION piInfo = {0}; DWORD pid = 3396; //pid of the desired parrent process hParProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pid); BOOL bRet = InitializeProcThreadAttributeList(NULL, 1, 0, &sizeToAlloc); _ASSERT(FALSE == bRet); _ASSERT(0 < sizeToAlloc); if ((FALSE != bRet) || (0 == sizeToAlloc)) goto cleanup; //allocate memory sieStartupInfo.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeToAlloc); _ASSERT(NULL != sieStartupInfo.lpAttributeList); if (NULL == sieStartupInfo.lpAttributeList) goto cleanup; sizeOfBuffer = sizeToAlloc; //initialize the attribute list bRet = InitializeProcThreadAttributeList(sieStartupInfo.lpAttributeList, 1, 0, &sizeOfBuffer); _ASSERT(TRUE == bRet); _ASSERT(sizeOfBuffer == sizeToAlloc); if (FALSE == bRet) goto cleanup; bRet = UpdateProcThreadAttribute(sieStartupInfo.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &hParProcess, sizeof(hParProcess), NULL, NULL); _ASSERT(TRUE == bRet); if(FALSE == bRet) goto cleanup; //launch process PROCESS_INFORMATION pi = {0}; bRet = CreateProcess(NULL, (LPWSTR)szCmdLine, NULL, NULL, FALSE, EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, (LPSTARTUPINFO)&sieStartupInfo, &piInfo); WaitForSingleObject( piInfo.hProcess, INFINITE ); CloseHandle( piInfo.hProcess ); CloseHandle( piInfo.hThread ); CloseHandle( hParProcess ); cleanup: return 0; }