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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 24.10.2009, 17:20   #1  
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).
Старый 12.11.2010, 18:26   #2  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,726 / 1208 (44) ++++++++
Регистрация: 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   #3  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2499 (89) +++++++++
Регистрация: 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
Теги
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, время: 03:07.