Причесал, пофиксил и протестировал ax3sp3
(* добавил _currentDirectory, исправил определения ф-ций)
X++:
server client static int shellExecuteWait(str _commandLine, int _waitTimeMilliseconds = -1, int _cmdShow = 4, str _currentDirectory, int _creationFlags = 0)
{
#WinAPI
Dll kernel32 = new Dll("kernel32.dll");
DllFunction createProcess = new DllFunction(kernel32, "CreateProcessA");
DllFunction openProcess = new DllFunction(kernel32, "OpenProcess");
DllFunction waitForSingleObject = new DllFunction(kernel32, "WaitForSingleObject");
DllFunction terminateProcess = new DllFunction(kernel32, "TerminateProcess");
DllFunction getExitCodeProcess = new DllFunction(kernel32, "GetExitCodeProcess");
Binary strartupInformation = new binary(68);
Binary processInformation = new binary(16);
Binary exitCode = new binary(4);
int hProcess;
int hThread;
int hProcessTerminate;
int dwProcessId;
void cleanup()
{;
WinApi::closeHandle(hProcessTerminate);
WinApi::closeHandle(hProcess);
WinApi::closeHandle(hThread);
}
createProcess.returns(ExtTypes:: DWORD);// BOOL WINAPI CreateProcess(...
createProcess.arg( ExtTypes:: DWORD, // in LPCTSTR lpApplicationName,
ExtTypes::STRING, // in_out LPTSTR lpCommandLine,
ExtTypes:: DWORD, // in LPSECURITY_ATTRIBUTES lpProcessAttributes,
ExtTypes:: DWORD, // in LPSECURITY_ATTRIBUTES lpThreadAttributes,
ExtTypes:: DWORD, // in BOOL bInheritHandles,
ExtTypes:: DWORD, // in DWORD dwCreationFlags,
ExtTypes:: DWORD, // in LPVOID lpEnvironment,
ExtTypes::STRING, // in LPCTSTR lpCurrentDirectory,
ExtTypes::POINTER, // in LPSTARTUPINFO lpStartupInfo,
ExtTypes::POINTER); // out LPPROCESS_INFORMATION lpProcessInformation
openProcess.returns(ExtTypes:: DWORD);
openProcess.arg(ExtTypes:: DWORD, ExtTypes:: DWORD, ExtTypes:: DWORD);
waitForSingleObject.returns(ExtTypes:: DWORD);
waitForSingleObject.arg(ExtTypes::DWORD, // in HANDLE hHandle,
ExtTypes:: DWORD); // in DWORD dwMilliseconds
terminateProcess.returns(ExtTypes:: DWord);
terminateProcess.arg(ExtTypes:: DWord, ExtTypes:: DWord);
getExitCodeProcess.returns(ExtTypes:: DWORD);
getExitCodeProcess.arg(ExtTypes:: DWord, ExtTypes::Pointer);
strartupInformation.dWord(44, _cmdShow);
try
{
if (! createProcess.call(0, _commandLine, 0, 0, 0, _creationFlags, 0, _currentDirectory, strartupInformation, processInformation))
throw error(strfmt("Ошибка при запуске приложения \"%1\"", _commandLine));
hProcess = processInformation.dWord(0);
hThread = processInformation.dWord(4);
dwProcessId = processInformation.dWord(8);
if ( waitForSingleObject.call(hProcess, _waitTimeMilliseconds) == #STATUS_TIMEOUT)
{
setprefix("Принудительное завершение приложения");
setprefix(_commandLine);
hProcessTerminate = openProcess.call(#PROCESS_ALL_ACCESS, 0, dwProcessId);
if (! hProcessTerminate)
throw error("Отказано в доступе");
if (! terminateProcess.call(hProcessTerminate, -1))
throw error("Ошибка при завершении приложения");
throw error("Приложение закрыто, так как не завершилось за отведенное ему время");
}
else
{
if (! getExitCodeProcess.call(hProcess, exitCode))
throw error("Ошибка при получении кода завершения приложения");
}
}
catch (Exception::Error)
{
cleanup();
throw Exception::Error;
}
cleanup();
return exitCode.dWord(0);
}