Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ShellExecute, REGSVR32.EXE 
V
    Опции темы
lv151
Дата 27.1.2010, 17:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 916
Регистрация: 11.2.2008

Репутация: 1
Всего: 2



Привет.
Запускаю
int res = (int)ShellExecute(NULL, NULL, "REGSVR32.EXE", path, NULL, SW_SHOWNORMAL);

Допустим что DLL-ки нет по такому пути. Выскакивает ShowMessage о том, что невозможно загрузить библиотеку, 
но res = 42, как будто ShellExecute отработал нормально.

Как обработатать эту ошибку?

PM MAIL   Вверх
artsb
Дата 27.1.2010, 18:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 5
Всего: 64



Цитата(lv151 @  27.1.2010,  17:35 Найти цитируемый пост)
Как обработатать эту ошибку?

ИМХО никак. Функция то ведь действительно отработала нормально. Всё запустила что нужно. А вот REGSVR32.EXE не нашла dll'ку указанную в параметрах, а следовательно она и генерирует ошибку.
Единственное, может попробовать создавать процесс через CreateProcess. А после его отработки получать код завершения:
Код

int res;
GetExitCodeProcess(ProcessHandle, &res);

обычно, при успешном завершении возвращается 0. Если вернулось STILL_ACTIVE - процесс ещё работает. Подробности - GetExitCodeProcess.

Это сообщение отредактировал(а) artsb - 28.1.2010, 12:59


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
GoldFinch
Дата 27.1.2010, 18:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 2
Всего: 26



Цитата(artsb @  27.1.2010,  18:06 Найти цитируемый пост)
Если вернулось STILL_ACTIVE - процесс ещё работает.

надо сразу вызывать
WaitForSingleObject(processInformation.hProcess,-1);
чтобы подождать его завершения
PM MAIL ICQ   Вверх
artsb
Дата 27.1.2010, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 5
Всего: 64



Цитата(GoldFinch @  27.1.2010,  18:35 Найти цитируемый пост)
WaitForSingleObject(processInformation.hProcess,-1)

А если он повиснет по каким-нибудь причинам, то прога тоже повиснет. Поэтому лучше в цикле ждать небольшой промежуток времени раз пять:
Код

for(int i=0; i<5; i++) {
 WaitForSingleObject(processInformation.hProcess, 1000); // ждём секунду
 if(i == 4) {
  // что-то долго процесс не завершается...
  // предпринимаем меры
 }
}

Что типа этого. Только время нужно своё подобрать.


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
GoldFinch
Дата 27.1.2010, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 2
Всего: 26



artsb, так запускай ожидание в отдельном потоке, и пусть себе виснет.
полюбому такие вещи должны быть развязаны с пользовательским интрефейсом

если запускаемый процесс повис - юзер это заметит, и например убьет повисший процесс, тогда ожидание закончится
или можно предусмотреть в нашей программе кнопку [убить процесс]

Добавлено через 1 минуту и 25 секунд
а ждать четыре раза по 1 сек в цикле - это бред)
PM MAIL ICQ   Вверх
artsb
Дата 27.1.2010, 19:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 5
Всего: 64



Цитата(GoldFinch @  27.1.2010,  18:48 Найти цитируемый пост)
юзер это заметит, и например убьет повисший процесс

не все такие умные smile

Цитата(GoldFinch @  27.1.2010,  18:48 Найти цитируемый пост)
а ждать четыре раза по 1 сек в цикле - это бред) 

а вот и нет. Зависит от задачи. Это я просто пример привёл. А устраивать ожидание до бесконечности (даже в отдельном потоке) нужно лишь в том случае, если есть 100-процентная уверенность, что процесс рано или поздно завершится.


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
GremlinProg
Дата 27.1.2010, 20:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



чтобы особенно ничего не менять, можно использовать ShellExecuteEx
дескриптор процесса тут: SHELLEXECUTEINFO::hProcess

если надо скрыть окна запускаемого процесса, можно попробовать передать в ShellExecute дескриптор какого-нить своего скрытого окна или вообще поиграться с SHELLEXECUTEINFO::DUMMYUNIONNAME::hMonitor


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
lv151
Дата 28.1.2010, 11:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 916
Регистрация: 11.2.2008

Репутация: 1
Всего: 2



thx all.
PM MAIL   Вверх
lv151
Дата 28.1.2010, 12:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 916
Регистрация: 11.2.2008

Репутация: 1
Всего: 2



Как сделать так, чтобы выскакивал ShowMessage об успешной регистрации dll-ки,
ползаю по описание функции, но не нахожу параметра.
Код

SHELLEXECUTEINFO info;
memset(&info, 0, sizeof(SHELLEXECUTEINFO));

info.cbSize = sizeof(SHELLEXECUTEINFO);
info.fMask = SEE_MASK_FLAG_NO_UI;
info.lpVerb = _T ("open");
info.lpFile = szDllPath;
info.nShow = SW_SHOW;



    

PM MAIL   Вверх
artsb
Дата 28.1.2010, 13:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 5
Всего: 64



Цитата(lv151 @  28.1.2010,  12:41 Найти цитируемый пост)
но не нахожу параметра.

его и нет smile

Цитата(lv151 @  28.1.2010,  12:41 Найти цитируемый пост)
Как сделать так, чтобы выскакивал ShowMessage

Схематически:
Код

SHELLEXECUTEINFO info;
// ...
if(ShellExecuteEx(info)) {
 // используя WaitForSingleObject дожидаемся завершения процесса
 // первым параметром будет info.hProcess
 int res;
 GetExitCodeProcess(info.hProcess, &res);
 if(res == 0)
  ShowMessage("Success!");
}


Добавлено через 2 минуты и 43 секунды
Но повторюсь, что обычно при успехе возвращается 0, но не всегда так бывает.

Это сообщение отредактировал(а) artsb - 28.1.2010, 13:05


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
xvr
Дата 28.1.2010, 14:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(lv151 @ 27.1.2010,  17:35)
Запускаю
int res = (int)ShellExecute(NULL, NULL, "REGSVR32.EXE", path, NULL, SW_SHOWNORMAL);

Если нужен ИМЕННО regsvr32, то проще его не запускать, а выполнить его работу самому. Он делает тривиальную вещь - грузит указанный dll, извлекает из него адрес функции DllRegisterServer (кажется так) и запускает ее. 5 строчек кода  smile 

PM MAIL   Вверх
jonie
Дата 29.1.2010, 12:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 7
Всего: 118



а нахрена самому вызывать regsvr32, если тоже что он делает можно сделать руками самому, вызвав экспортируемые функции?


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
lv151
Дата 8.2.2010, 11:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 916
Регистрация: 11.2.2008

Репутация: 1
Всего: 2



У меня почему то info.hProcess = 0 ?
PM MAIL   Вверх
artsb
Дата 8.2.2010, 12:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 5
Всего: 64



Что-то мой хрустальный шар барахлит.  smile  Можешь дать кусочек кода?


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
lv151
Дата 8.2.2010, 13:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 916
Регистрация: 11.2.2008

Репутация: 1
Всего: 2



Код

   SHELLEXECUTEINFO info;
    memset(&info, 0, sizeof(SHELLEXECUTEINFO));

    info.cbSize = sizeof(SHELLEXECUTEINFO);
    info.fMask = SEE_MASK_FLAG_NO_UI;
    info.lpVerb = _T ("open");
    info.lpFile = "REGSVR32.EXE";
    info.lpParameters = szDll;
    info.nShow = SW_SHOW;

    BOOL res = ShellExecuteEx(&info);
    WaitForSingleObject(info.hProcess, INFINITE);
    
    DWORD resProc = 0;    
    GetExitCodeProcess(info.hProcess, &resProc);

    if (res == FALSE || resProc != 0)
   {
    LPVOID lpMsgBuf;        

    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
                                  FORMAT_MESSAGE_FROM_SYSTEM | 
                  FORMAT_MESSAGE_IGNORE_INSERTS,
                  NULL,
                                  GetLastError(),
                   MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
                                  (LPTSTR) &lpMsgBuf,
                  0,
                  NULL);
        
    MessageBox(NULL, (LPCSTR)lpMsgBuf, "Error", MB_OK|MB_ICONSTOP);

    LocalFree(lpMsgBuf);
    
        return result;
    }


Отрабатывает всё нормально.
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0707 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.