AXForum  
Go Back   AXForum > Microsoft Dynamics AX > DAX: База знаний и проекты
All
Forgotten Your Password?
Register Forum Rules FAQ Members List Today's Posts Search

 
 
Thread Tools Search this Thread Display Modes
Old 02.12.2005, 16:23   #21  
belugin is offline
belugin
Участник
belugin's Avatar
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Join Date: 16.01.2004
Blog Entries: 5
http://msdn.microsoft.com/library/de...l/wsmthrun.asp
Old 02.12.2005, 17:01   #22  
kvan is offline
kvan
Moderator
kvan's Avatar
Дети Юза
 
775 / 49 (3) +
Join Date: 07.08.2002
Location: Donetsk
раньше говорили RTFM а теперь тыкают носом в MSDN ...
__________________
С уважением, kvan.
Old 02.12.2005, 18:39   #23  
kvan is offline
kvan
Moderator
kvan's Avatar
Дети Юза
 
775 / 49 (3) +
Join Date: 07.08.2002
Location: Donetsk
PHP Code:
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.

Last edited by kvan; 02.12.2005 at 18:45.
This post has been rated by: Ace of Database (5).
Old 02.12.2005, 19:38   #24  
db is offline
db
Роман Долгополов (RDOL)
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
 
393 / 692 (24) +++++++
Join Date: 01.04.2004
Location: Москва
Quote:
Originally Posted by AndyD
2 db

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

PHP Code:
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, он же привел другой вариант запуска приложения. Выбирайте любой
This post has been rated by: SHiSHok (1).
Old 02.12.2005, 19:50   #25  
kvan is offline
kvan
Moderator
kvan's Avatar
Дети Юза
 
775 / 49 (3) +
Join Date: 07.08.2002
Location: Donetsk
А значение константы PROCESS_ALL_ACCESS ?
__________________
С уважением, kvan.
Old 02.12.2005, 20:03   #26  
db is offline
db
Роман Долгополов (RDOL)
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
 
393 / 692 (24) +++++++
Join Date: 01.04.2004
Location: Москва
Quote:
Originally Posted by kvan
А значение константы PROCESS_ALL_ACCESS ?
PHP Code:
#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 макрос. Здесь констант с избытком, надеюсь не забыл больше ничего. Пятница и дырява голова в общем
This post has been rated by: kornix (2).
Old 02.12.2005, 20:53   #27  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2494 (89) +++++++++
Join Date: 20.08.2005
2 db, kvan

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

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

Кроме того, структура архива может быть тоже интересна и что-бы получить эту информацию уже надо обращаться к функциям работы с архивами.
__________________
Axapta v.3.0 sp5 kr2
Old 24.10.2009, 17:20   #28  
SHiSHok is offline
SHiSHok
Участник
SHiSHok's Avatar
Дети Юза
 
219 / 103 (4) +++++
Join Date: 28.07.2005
Location: Донецк
Причесал, пофиксил и протестировал 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

Last edited by SHiSHok; 24.10.2009 at 17:23.
This post has been rated by: mazzy (2).
Old 25.10.2009, 01:32   #29  
McArrow is offline
McArrow
Участник
 
45 / 38 (2) +++
Join Date: 18.05.2009
ммм. Если научиться использовать pipes, то для полного контроля за исполнением можно перенаправлять стандартный вывод туда, а затем его разбирать, используя, например, регулярные выражения через .Net. Как вариант, можно перенаправлять стандартный вывод во временный файл. Пока смущает функция WinApi PeekNamedPipe, через некоторые её параметры передаются указатели, как с ними работать из аксапты я не знаю.

Last edited by McArrow; 25.10.2009 at 02:11.
Old 12.11.2010, 18:26   #30  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,720 / 1207 (44) ++++++++
Join Date: 13.01.2004
Blog Entries: 3
Quote:
Originally Posted by SHiSHok View Post
Причесал, пофиксил и протестировал 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.
This post has been rated by: SHiSHok (1).
Old 12.11.2010, 20:16   #31  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2494 (89) +++++++++
Join Date: 20.08.2005
Quote:
Originally Posted by Владимир Максимов View Post
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
Old 13.11.2010, 11:41   #32  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,720 / 1207 (44) ++++++++
Join Date: 13.01.2004
Blog Entries: 3
Вопрос, вопрос... Да, была идея менять определение типа аргумента в createProcess, но мне показалось это слишком громоздким решением. Впрочем, если другого способа нет, то можно и так
Old 03.02.2011, 06:38   #33  
offenmeier is offline
offenmeier
HAI; CAN HAS STDIO?
offenmeier's Avatar
Соотечественники
 
77 / 36 (2) +++
Join Date: 17.02.2005
Location: 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.
This post has been rated by:  (2).
Old 25.02.2011, 14:48   #34  
SHiSHok is offline
SHiSHok
Участник
SHiSHok's Avatar
Дети Юза
 
219 / 103 (4) +++++
Join Date: 28.07.2005
Location: Донецк
спасибо, исправил ошибки. небольшое уточнение:

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

 

Similar Threads
Thread Thread Starter Forum Replies Last Post
Программное сохранение автоотчета в архив печати. 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

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Рейтинг@Mail.ru
All times are GMT +3. The time now is 04:35.
Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Contacts E-mail, Advertising.