AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: База знаний и проекты
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 02.12.2005, 17:01   #22  
kvan is offline
kvan
Moderator
Аватар для kvan
Дети Юза
 
775 / 49 (3) +
Регистрация: 07.08.2002
Адрес: Donetsk
раньше говорили RTFM а теперь тыкают носом в MSDN ...
__________________
С уважением, kvan.
Старый 02.12.2005, 18:39   #23  
kvan is offline
kvan
Moderator
Аватар для kvan
Дети Юза
 
775 / 49 (3) +
Регистрация: 07.08.2002
Адрес: Donetsk
PHP код:
static void ReturnCode_Job(Args _args)
{
COM    wsh             = new COM('WScript.Shell');
int        returnCode1 = -1;
int        returnCode2 = -1;
int        errorCode1 = -1;
int        errorCode2 = -1;
;
 
    
returnCode1 wsh.Run('winrar.exe e -y C:\\1.zip C:\\1\\'1true);
    
errorCode1 WinAPI::getLastError();
 
    
returnCode2 wsh.Run('winrar.exe e -y C:\\2.zip C:\\2\\'1true);
    
errorCode2 WinAPI::getLastError();
 
    
info(strFmt('1.zip: ReturnCode = %1, ErrorCode = %2'returnCode1errorCode1));
    
info(strFmt('2.zip: ReturnCode = %1, ErrorCode = %2'returnCode2errorCode2));
 
    
wsh.finalize();
 
return;

Результаты:
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  
db is offline
db
Роман Долгополов (RDOL)
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
 
393 / 692 (24) +++++++
Регистрация: 01.04.2004
Адрес: Москва
Цитата:
Сообщение от AndyD
2 db

И каким образом это дает ответ на мой вопрос?
Ой Ткнул на ссылку, не проверив содержимое. Думал что там версия, которая уже возвращает код завершения процесса. Исправляюсь тут

PHP код:
static int shellExecute(str commandLineint _waitTime = -1int _creationFlags 0int cmdShow 4)
{
    
#WinAPI
    
Dll             kernel32                    = new Dll("kernel32.dll");
    
DllFunction     createProcess             = new DllFunction(kernel32"CreateProcessA");
    
DllFunction     waitForSingleObject         = new DllFunction(kernel32"WaitForSingleObject");
    
DllFunction     terminateProcess            = new DllFunction(kernel32"TerminateProcess");
    
DllFunction     openProcess                 = new DllFunction(kernel32"OpenProcess");
    
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:: WORD);
    
createProcess.arg(ExtTypes:: WORDExtTypes::STRING,
                     
ExtTypes:: WORDExtTypes:: WORD,
                     
ExtTypes:: WORDExtTypes:: WORD,
                     
ExtTypes:: WORDExtTypes:: WORD,
                     
ExtTypes::POINTERExtTypes::POINTER);
    
waitForSingleObject.returns(ExtTypes:: WORD);
    
waitForSingleObject.arg(ExtTypes::WORDExtTypes:: WORD);
    
terminateProcess.returns(ExtTypes:: Word);
    
terminateProcess.arg(ExtTypes:: WordExtTypes:: Word);
    
openProcess.returns(ExtTypes:: WORD);
    
openProcess.arg(ExtTypes:: WORDExtTypes:: WORDExtTypes:: WORD);
    
getExitCodeProcess.returns(ExtTypes:: WORD);
    
getExitCodeProcess.arg(ExtTypes:: WordExtTypes::Pointer);
    
strartupInformation.dWord(44cmdShow);
    try
    {
        if (! 
createProcess.call(0commandLine000_creationFlags00strartupInformationprocessInformation))
        {
            throw 
error(strfmt("Ошибка при запуске приложения \"%1\""commandLine));
        }
        
hProcess    processInformation.dWord(0);
        
hThread     processInformation.dWord(4);
        
dwProcessId processInformation.dWord(8);
        if (
waitForSingleObject.call(hProcess_waitTime) == #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(hProcessexitCode))
            {
                throw 
error("Ошибка при получении кода завершения приложения");
            }
        }
    }
    catch (
Exception::Error)
    {
        
cleanup();
        throw 
Exception::Error;
    }
    
cleanup();
    return 
exitCode.dWord(0);

Про коды возрата уже ответил kvan, он же привел другой вариант запуска приложения. Выбирайте любой
За это сообщение автора поблагодарили: SHiSHok (1).
Старый 02.12.2005, 19:50   #25  
kvan is offline
kvan
Moderator
Аватар для kvan
Дети Юза
 
775 / 49 (3) +
Регистрация: 07.08.2002
Адрес: Donetsk
А значение константы PROCESS_ALL_ACCESS ?
__________________
С уважением, kvan.
Старый 02.12.2005, 20:03   #26  
db is offline
db
Роман Долгополов (RDOL)
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
 
393 / 692 (24) +++++++
Регистрация: 01.04.2004
Адрес: Москва
Цитата:
Сообщение от kvan
А значение константы PROCESS_ALL_ACCESS ?
PHP код:
#DEFINE.GENERIC_READ(0x80000000)
#DEFINE.GENERIC_WRITE(0x40000000)
#DEFINE.GENERIC_EXECUTE(0x20000000)
#DEFINE.GENERIC_ALL(0x10000000)
#DEFINE.DELETE(0x00010000)
#DEFINE.INVALID_HANDLE(-1)
#DEFINE.STATUS_WAIT_0         (0x00000000)
#DEFINE.STATUS_ABANDONED_WAIT_0(0x00000080)
#DEFINE.STATUS_USER_APC        (0x000000C0)
#DEFINE.STATUS_TIMEOUT         (0x00000102)
#DEFINE.CB_RESETCONTENT        (0x014B)
#DEFINE.DEBUG_PROCESS             (0x00000001)
#DEFINE.DEBUG_ONLY_THIS_PROCESS     (0x00000002)
#DEFINE.CREATE_SUSPENDED            (0x00000004)
#DEFINE.DETACHED_PROCESS            (0x00000008)
#DEFINE.CREATE_NEW_CONSOLE         (0x00000010)
#DEFINE.NORMAL_PRIORITY_CLASS     (0x00000020)
#DEFINE.IDLE_PRIORITY_CLASS         (0x00000040)
#DEFINE.HIGH_PRIORITY_CLASS         (0x00000080)
#DEFINE.REALTIME_PRIORITY_CLASS     (0x00000100)
#DEFINE.CREATE_NEW_PROCESS_GROUP    (0x00000200)
#DEFINE.CREATE_UNICODE_ENVIRONMENT (0x00000400)
#DEFINE.CREATE_SEPARATE_WOW_VDM     (0x00000800)
#DEFINE.CREATE_SHARED_WOW_VDM     (0x00001000)
#DEFINE.CREATE_FORCEDOS             (0x00002000)
#DEFINE.CREATE_DEFAULT_ERROR_MODE (0x04000000)
#DEFINE.CREATE_NO_WINDOW            (0x08000000)
#define.CTRL_C_EVENT        (0)
#define.CTRL_BREAK_EVENT    (1)
#define.CTRL_CLOSE_EVENT    (2)
#define.CTRL_LOGOFF_EVENT (5)
#define.CTRL_SHUTDOWN_EVENT (6)
#define.DELETE                         (0x00010000)
#define.READ_CONTROL                     (0x00020000)
#define.WRITE_DAC                        (0x00040000)
#define.WRITE_OWNER                     (0x00080000)
#define.SYNCHRONIZE                     (0x00100000)
#define.STANDARD_RIGHTS_REQUIRED         (0x000F0000)
#define.STANDARD_RIGHTS_READ             (READ_CONTROL)
#define.STANDARD_RIGHTS_WRITE            (READ_CONTROL)
#define.STANDARD_RIGHTS_EXECUTE         (READ_CONTROL)
#define.STANDARD_RIGHTS_ALL             (0x001F0000)
#define.SPECIFIC_RIGHTS_ALL             (0x0000FFFF)
 
#define.PROCESS_TERMINATE         (0x0001)
#define.PROCESS_CREATE_THREAD     (0x0002)
#define.PROCESS_SET_SESSIONID     (0x0004)
#define.PROCESS_VM_OPERATION     (0x0008)
#define.PROCESS_VM_READ         (0x0010)
#define.PROCESS_VM_WRITE         (0x0020)
#define.PROCESS_DUP_HANDLE        (0x0040)
#define.PROCESS_CREATE_PROCESS    (0x0080)
#define.PROCESS_SET_QUOTA         (0x0100)
#define.PROCESS_SET_INFORMATION (0x0200)
#define.PROCESS_QUERY_INFORMATION (0x0400)
#define.PROCESS_ALL_ACCESS        (#STANDARD_RIGHTS_REQUIRED | #SYNCHRONIZE | 0xFFF) 
Допишите в свой WinAPI макрос. Здесь констант с избытком, надеюсь не забыл больше ничего. Пятница и дырява голова в общем
За это сообщение автора поблагодарили: kornix (2).
Старый 02.12.2005, 20:53   #27  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
2 db, kvan

Спасибо за развернутые ответы.

Но, в общем-то, мой вопрос был риторическим и относился он именно к winapi::ShellExecute(). Так что ваши предложения я бы адресовал все-таки автору ветки

Кроме того, структура архива может быть тоже интересна и что-бы получить эту информацию уже надо обращаться к функциям работы с архивами.
__________________
Axapta v.3.0 sp5 kr2
Старый 24.10.2009, 17:20   #28  
SHiSHok is offline
SHiSHok
Участник
Аватар для SHiSHok
Дети Юза
 
219 / 103 (4) +++++
Регистрация: 28.07.2005
Адрес: Донецк
Причесал, пофиксил и протестировал 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  
McArrow is offline
McArrow
Участник
 
45 / 38 (2) +++
Регистрация: 18.05.2009
ммм. Если научиться использовать pipes, то для полного контроля за исполнением можно перенаправлять стандартный вывод туда, а затем его разбирать, используя, например, регулярные выражения через .Net. Как вариант, можно перенаправлять стандартный вывод во временный файл. Пока смущает функция WinApi PeekNamedPipe, через некоторые её параметры передаются указатели, как с ними работать из аксапты я не знаю.

Последний раз редактировалось McArrow; 25.10.2009 в 02:11.
Старый 12.11.2010, 18:26   #30  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,701 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от SHiSHok Посмотреть сообщение
Причесал, пофиксил и протестировал ax3sp3
(* добавил _currentDirectory, исправил определения ф-ций)
Судя по тому, что никто не сообщил об ошибках, то этой функцией не пользуются А мне вот понадобилась и сразу напоролся на парочку ошибок

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  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
2. Не понял как быть, если currentDirectory не указано. Пустую строку createProcess принять не может. Предполагается, что если директория не указана, то надо передать NULL, но как это "разрулить" в данном случае - не понятно...
Можно так
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  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,701 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Вопрос, вопрос... Да, была идея менять определение типа аргумента в createProcess, но мне показалось это слишком громоздким решением. Впрочем, если другого способа нет, то можно и так
Старый 03.02.2011, 06:38   #33  
offenmeier is offline
offenmeier
HAI; CAN HAS STDIO?
Аватар для offenmeier
Соотечественники
 
77 / 36 (2) +++
Регистрация: 17.02.2005
Адрес: Auckland, NZ
такой ещё вариант: я запаковывал файлы отчётов (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();
}
после WaitForExit() у процесса можно и спросить, с каким кодом он там завершился, насколько я помню, давно делал.
__________________
our sharp bitter vitriol is not that of the vulgar.
За это сообщение автора поблагодарили:  (2).
Старый 25.02.2011, 14:48   #34  
SHiSHok is offline
SHiSHok
Участник
Аватар для SHiSHok
Дети Юза
 
219 / 103 (4) +++++
Регистрация: 28.07.2005
Адрес: Донецк
спасибо, исправил ошибки. небольшое уточнение:

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, архивирование, законченный пример, полезное, программирование, разархивировать

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Программное сохранение автоотчета в архив печати. Dima_Dima DAX: Программирование 3 29.07.2009 17:36
axaptapedia: Autozip for Dax 4.0 Blog bot DAX Blogs 0 30.04.2008 16:05
Как скачать и разархивировать файл Arahnid DAX: Программирование 10 16.11.2007 16:22
Архив technet.damgaard.com ? Torin DAX: Прочие вопросы 9 10.06.2005 20:30

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 16:44.