25.08.2003, 13:38 | #1 |
Участник
|
Запуск приложения с ожиданием его завершения...
На форуме уже была инфа по ShellExecute. НО !!! Таким образом программу можно запускать только АСИНХРОННО от Аксапты А мне требуеться дождаться завершения внешней программы и ТОЛЬКО после этого продолжить выполнение кода в Аксапте. Вариант типа команды pause после shellexecute неприемлем - выполнение происходить без участия пользователя.
В WinApi (не Аксапта, а MS Win) есть функции CreateProcess и WaitForSingleObject. Вопрос - как с их помощью (в смысле желателен код на X++) запустить внешнее приложение. Или хотя бы ссылку на документацию (по Axapta !!!) где описываеться использование ExtTypes, DLL и тому подобное. |
|
25.08.2003, 14:17 | #2 |
Участник
|
int RunWait()
{ COM wsh = new COM("WScript.Shell"); return wsh.Run("calc.exe" , 1, TRUE); } также смотри ветку: Исполнение методов класса на стороне сервера (AOS)? |
|
25.08.2003, 14:35 | #3 |
Участник
|
попробовал, вроде работает.
А задача была следующая - с помощью внешней программы периодически выгружать инфу в DBF и затем обрабатывать, используя данные из Аксапты. Кроме внешней проги ничего не может преобразовать набор исходных данных в DBF. |
|
25.08.2003, 16:09 | #4 |
NavAx
|
2 snp123
http://www.axforum.info/forums/showt...=8699#post8699 И еще рекомендую посмотреть help по DTS в MS SQL. |
|
25.08.2003, 16:49 | #5 |
Moderator
|
Еще есть API функция WaitForSingleObject, предназначенная как раз для таких целей. Но не уверен, что в Аксапте для нее есть обертка. Если нет - придется писать.
Хотя, если вариант SnowMan с Windows Script Host работает - наверное лучше использовать его. Просто есть подозрение, что не на всех ОС это будет работать. |
|
26.08.2003, 07:00 | #6 |
Участник
|
2 raz: проблема не в том, что есть данные в DBF и их нужно закидывать в Axapta.
Проблема в том, что только некоторая оригинальная прога может преобразовать из внутреннего формата данных в нормальный DBF. Кстати, а что я смогу найти в доке по DTS ? 2 андре: использоваться программа конвертации будет только на MS win2000 или MS WinXP. |
|
26.08.2003, 09:10 | #7 |
NavAx
|
2 snp123
Просто DTS позволяет перегонять данные и запускать разные задачи (в том числе и внешние). Возможно есть вариант дать команду SQL и он выполнит неоходимый Job, который мог бы, например, запустить внешнюю программу, потом результаты ее работы загрузить в SQL, а в Аксапте надо было бы только дождатся появления данных, забрать их через ODBC. |
|
26.08.2003, 11:53 | #8 |
Участник
|
доки у меня нет но покопаться в дтс попробую вдруг что интересное получиться...
|
|
26.01.2010, 13:42 | #9 |
Участник
|
Ай нид хелп. Выполнение run с третьим параметром равным "true" не ждет завершения отработки:
X++: wsh = new COM('WScript.Shell'); wsh.Run(strFmt("winrar.exe e -y -o+ %1 %2",fileName,temppath), 0, true); wsh.finalize(); fullFileName = SysTreeNode::duplicatePathDelimiters(< >); if(!winapi::fileExists_RU(fullFileName)) throw error("Нема файлка!"); Не подскажете как быть? P.S. Выполняю на Windows XP. Axapta 3.0 |
|
26.01.2010, 15:01 | #10 |
Участник
|
Попробуйте вот это.
X++: static void shellExecuteWait(str commandLine, int _waitTime = -1, int cmdShow = 4) { // Ожидание завершения работы приложения commandLine. #WinAPI #DEFINE.STATUS_TIMEOUT(0x00000102) Dll kernel32 = new Dll("kernel32.dll"); DllFunction createProcess = new DllFunction(kernel32, "CreateProcessA"); DllFunction waitForSingleObject = new DllFunction(kernel32, "WaitForSingleObject"); DllFunction closeHandle = new DllFunction(kernel32, "CloseHandle"); DllFunction terminateProcess = new DllFunction(kernel32, "TerminateProcess"); Binary strartupInformation = new binary(68); Binary processInformation = new binary(16); int hProcess; createProcess.returns(ExtTypes:: DWORD); createProcess.arg(ExtTypes:: DWORD, ExtTypes:: STRING, ExtTypes:: DWORD, ExtTypes:: DWORD, ExtTypes:: DWORD, ExtTypes:: DWORD, ExtTypes:: DWORD, ExtTypes:: DWORD, ExtTypes:: POINTER, ExtTypes:: POINTER); waitForSingleObject.returns(ExtTypes:: DWORD); waitForSingleObject.arg(ExtTypes:: DWORD, ExtTypes:: DWORD); closeHandle.returns(ExtTypes:: DWORD); closeHandle.arg(ExtTypes:: DWORD); terminateProcess.returns(ExtTypes:: DWord); terminateProcess.arg(ExtTypes:: DWord, ExtTypes:: DWord); strartupInformation.dWord(44, cmdShow); if (!createProcess.call(0, commandLine, 0, 0, 0, 0, 0, 0, strartupInformation, processInformation)) { throw error(strfmt("Ошибка при запуске приложения \"%1\"", commandLine)); } hProcess = processInformation.dWord(0); if (waitForSingleObject.call(hProcess, _waitTime) == #STATUS_TIMEOUT) { terminateProcess.call(hProcess, 1); throw error(strfmt("Приложение \"%1\" закрыто, так как не завершилось за отведенное ему время", commandLine)); } closeHandle.call(hProcess); } |
|
|
За это сообщение автора поблагодарили: konfet (1), tricky (1). |
26.01.2010, 15:17 | #11 |
Участник
|
Спасибо, работает.
Но только вот так X++: MyTestGlobal::shellExecuteWait(strFmt("C:\\Progra~1\\WinRAR\\WinRAR.exe e -y -o+ %1 %2",fileName,temppath)); X++: MyTestGlobal::shellExecuteWait(strFmt("WinRAR.exe e -y -o+ %1 %2",fileName,temppath)); |
|
26.01.2010, 22:46 | #12 |
Administrator
|
Цитата:
1. Предположить что Winrar всегда будет стоять в Program Files. Путь к Program Files можно определить из переменной окружения %ProgramFiles% (cmd.exe echo %ProgramFiles%). Это поможет в случае установки Windows на разные диски. 2. В реестре (Windows 2008 Server, Vista) есть ветка HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\WinRAR.exe, у которой есть значение по умолчанию - полный путь к Exe-шнику и значение Path - соответственно - путь только к каталогу. Можно проанализировать эту ветку на предмет получения пути. В общем случае - можно поискать в реестре по ключевому слову WinRAR чтобы понять где какая информация хранится. Но в случае реестра есть маленькая ложка дегтя. Структура реестра в Vista / Server 2008 немного отличается от предыдущих версий Windows и есть риски "не найти в ожидаемом месте" информацию в реестре для разных ОС.
__________________
Возможно сделать все. Вопрос времени |
|
|
За это сообщение автора поблагодарили: tricky (1). |
27.01.2010, 11:39 | #13 |
Участник
|
Или не много поставить по другому задачу ...
1. пользоваться не WinRar.exe, а просто rar.exe 2. его не нужно инсталировать и его можно просто скопировать в известную нам папку (например с:\temp , а тут варианты ... 2.1. копировать из известного места в сети 2.2. можно сделать поле в настроечной таблице типа контейнер. В это поле загрузить rar.exe. при вызове процедуры архивирования - проверять есть ли в указанном месте rar.exe ... и дальше понятно. по моему немного проще чем анализировать реестр и вообще аксой напрямую лазить по реестру |
|
|
За это сообщение автора поблагодарили: sukhanchik (2), tricky (1). |
Теги |
shellexecute, winapi, запуск |
|
|