02.12.2005, 17:01 | #22 |
Moderator
|
раньше говорили RTFM а теперь тыкают носом в MSDN ...
__________________
С уважением, kvan. |
|
02.12.2005, 18:39 | #23 |
Moderator
|
PHP код:
1.zip: ReturnCode = 0, ErrorCode = 0 2.zip: ReturnCode = 6, ErrorCode = 0 1.zip - нормальный архив 2.zip - битый архив (нераспаковывается) P.S. Значения ErrorCode приведены для сравнения.
__________________
С уважением, kvan. Последний раз редактировалось kvan; 02.12.2005 в 18:45. |
|
|
За это сообщение автора поблагодарили: Ace of Database (5). |
02.12.2005, 19:38 | #24 |
Роман Долгополов (RDOL)
|
Цитата:
Сообщение от AndyD
2 db
И каким образом это дает ответ на мой вопрос? PHP код:
|
|
|
За это сообщение автора поблагодарили: SHiSHok (1). |
02.12.2005, 19:50 | #25 |
Moderator
|
А значение константы PROCESS_ALL_ACCESS ?
__________________
С уважением, kvan. |
|
02.12.2005, 20:03 | #26 |
Роман Долгополов (RDOL)
|
Цитата:
Сообщение от kvan
А значение константы PROCESS_ALL_ACCESS ?
PHP код:
|
|
|
За это сообщение автора поблагодарили: kornix (2). |
02.12.2005, 20:53 | #27 |
Участник
|
2 db, kvan
Спасибо за развернутые ответы. Но, в общем-то, мой вопрос был риторическим и относился он именно к winapi::ShellExecute(). Так что ваши предложения я бы адресовал все-таки автору ветки Кроме того, структура архива может быть тоже интересна и что-бы получить эту информацию уже надо обращаться к функциям работы с архивами.
__________________
Axapta v.3.0 sp5 kr2 |
|
24.10.2009, 17:20 | #28 |
Участник
|
Причесал, пофиксил и протестировал 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); }
__________________
--- SHiSHok Последний раз редактировалось SHiSHok; 24.10.2009 в 17:23. |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
25.10.2009, 01:32 | #29 |
Участник
|
ммм. Если научиться использовать pipes, то для полного контроля за исполнением можно перенаправлять стандартный вывод туда, а затем его разбирать, используя, например, регулярные выражения через .Net. Как вариант, можно перенаправлять стандартный вывод во временный файл. Пока смущает функция WinApi PeekNamedPipe, через некоторые её параметры передаются указатели, как с ними работать из аксапты я не знаю.
Последний раз редактировалось McArrow; 25.10.2009 в 02:11. |
|
12.11.2010, 18:26 | #30 |
Участник
|
Цитата:
1. Некорректно задано значение для strartupInformation. В указанном синтаксисе значение параметра _cmdShow будет просто проигнорировано. Необходимо так X++: strartupInformation.dWord(0, 68); // Общая длина. Впрочем, можно и не указывать strartupInformation.dWord(44, 1); // Учитывать значение параметра _cmdShow strartupInformation.dWord(48, _cmdShow); 2. Не понял как быть, если currentDirectory не указано. Пустую строку createProcess принять не может. Предполагается, что если директория не указана, то надо передать NULL, но как это "разрулить" в данном случае - не понятно... 3. Если длина команды _commandLine очень велика, то в случае превышения отведенного на обработку времени при попытке отобразить этот текст в infolog Axapta просто вылетает. Поэтому для сообщения об ошибке следует обрезать текст команды до нескольких первых символов. Например, не более 100. |
|
|
За это сообщение автора поблагодарили: SHiSHok (1). |
12.11.2010, 20:16 | #31 |
Участник
|
Цитата:
X++: anytype currentDirectoryValue; ; createProcess.arg( ExtTypes:: DWORD, // in LPCTSTR lpApplicationName, ... _currentDirectory ? ExtTypes::STRING : ExtTypes::Dword, // in LPCTSTR lpCurrentDirectory, ... if (currentDirectory) currentDirectoryValue = _currentDirectory; else currentDirectoryValue = 0; if (! createProcess.call(0, _commandLine, 0, 0, 0, _creationFlags, 0, currentDirectoryValue, strartupInformation, processInformation)) throw error(strfmt("Ошибка при запуске приложения \"%1\"", _commandLine));
__________________
Axapta v.3.0 sp5 kr2 |
|
13.11.2010, 11:41 | #32 |
Участник
|
Вопрос, вопрос... Да, была идея менять определение типа аргумента в createProcess, но мне показалось это слишком громоздким решением. Впрочем, если другого способа нет, то можно и так
|
|
03.02.2011, 06:38 | #33 |
HAI; CAN HAS STDIO?
|
такой ещё вариант: я запаковывал файлы отчётов (PDF) в архив и отсылал клиенту в пакетной обработке.
использовал как архиватор Info-ZIP, он свободно распространяется и для частного и для бизнес-использования. для запуска использовал System.Diagnostics.Process, потому что задолбался переписывать методы из WinApi толком в WinApiServer (AX 2009) в классе это выглядело так: X++: void packPDF() { str zipExePath = "\"C:\\Program Files\\Info-ZIP\\zip.exe\""; str parameters; str quote = "\""; System.Diagnostics.Process processZIP; str enquote(str _parm) { _parm = quote + _parm + quote; return _parm; } ; parameters = ""; parameters += "-j "; // do not create folder node parameters += "-9 "; // mid level of packing parameters += "-m "; // move to archive (delete after packing) parameters += enquote(zipFile) + " "; // new zip file name parameters += enquote(folderPath + "*.pdf"); // all pdf files please new InteropPermission(InteropKind::ClrInterop).assert(); processZIP = System.Diagnostics.Process::Start(zipExePath, parameters); processZIP.WaitForExit(); CodeAccessPermission::revertAssert(); }
__________________
our sharp bitter vitriol is not that of the vulgar. |
|
|
За это сообщение автора поблагодарили: (2). |
25.02.2011, 14:48 | #34 |
Участник
|
спасибо, исправил ошибки. небольшое уточнение:
typedef struct _STARTUPINFO { DWORD cb; LPTSTR lpReserved; LPTSTR lpDesktop; LPTSTR lpTitle; DWORD dwX; DWORD dwY; DWORD dwXSize; DWORD dwYSize; DWORD dwXCountChars; DWORD dwYCountChars; DWORD dwFillAttribute; DWORD dwFlags; WORD wShowWindow; WORD cbReserved2; LPBYTE lpReserved2; HANDLE hStdInput; HANDLE hStdOutput; HANDLE hStdError; } STARTUPINFO, *LPSTARTUPINFO; таким образом имеем: X++: // strartupInformation.dWord(44, _cmdShow); strartupInformation.dWord(44, 1); // Учитывать значение параметра _cmdShow strartupInformation.Word(48, _cmdShow);
__________________
--- SHiSHok |
|
Теги |
winapi, zip, архивирование, законченный пример, полезное, программирование, разархивировать |
|
Похожие темы | ||||
Тема | Ответов | |||
Программное сохранение автоотчета в архив печати. | 3 | |||
axaptapedia: Autozip for Dax 4.0 | 0 | |||
Как скачать и разархивировать файл | 10 | |||
Архив technet.damgaard.com ? | 9 |
Опции темы | Поиск в этой теме |
Опции просмотра | |
|