|
Как убрать "подвешивание" вызывающего приложения при вызове другого через Shell?
|
|||
---|---|---|---|
#18+
Пример кода: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Смысл кода: если logbook.exe запущен то окно запущенного экземпляра просто выводится наверх если НЕТ, то logbook.exe запускается через Shell Есть проблемка. Если например logbook.exe запускается ощутимо долго (3 секунды к примеру - ну скажем listview c 4000 записей), то вызывающее приложение стормозит пока logbook.exe не запустится. Если вызывающее приложение например проигрывает wav-файл, то проигрывание будет прервано на время запуска вызываемого, фигня, но по ушам ездит. Как полечить? Второй неприятный эффект в таком же духе. Например посылаю SendMessage (data) в вызываемое приложение. Если в процедура обработки в вызываемом приложении требует какого-то времени, то опять же в вызывающем приложении будет подвисание. Как лечить? PostMessage вместо SendMessage? Ну, если ответа не требуется? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2013, 16:43 |
|
Как убрать "подвешивание" вызывающего приложения при вызове другого через Shell?
|
|||
---|---|---|---|
#18+
Используйте асинхронный запуск. Скажем, через WSHShell.Run. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2013, 17:02 |
|
Как убрать "подвешивание" вызывающего приложения при вызове другого через Shell?
|
|||
---|---|---|---|
#18+
AkinaИспользуйте асинхронный запуск. Скажем, через WSHShell.Run.или через ShellExecute ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2013, 17:08 |
|
Как убрать "подвешивание" вызывающего приложения при вызове другого через Shell?
|
|||
---|---|---|---|
#18+
Дмитрий77Если например logbook.exe запускается ощутимо долго (3 секунды к примеру - ну скажем listview c 4000 записей), то вызывающее приложение стормозит пока logbook.exe не запустится. А разве не "the Shell function runs other programs asynchronously"? Если запускаемая программа в начале сжирает ресурсы процессора, тогда, наверное, нужно как-то понижать её приоритетность. Но если почему-то Shell долго формирует task ID, то можно попробовать сформировать BAT-файл и уже его запускать шеллом. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2013, 17:09 |
|
Как убрать "подвешивание" вызывающего приложения при вызове другого через Shell?
|
|||
---|---|---|---|
#18+
bat-файл с вызовом через call решит проблему ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2013, 17:11 |
|
Как убрать "подвешивание" вызывающего приложения при вызове другого через Shell?
|
|||
---|---|---|---|
#18+
AkinaWSHShell.Run. Никогда не использовал и не люблю такие штуки Shocker.Proили через ShellExecute Да, уже об этом подумал. Можно попробовать Но ShellExecute это не то же самое что Shell? Небось также ждет результата. Нет? Konst_Onebat-файл с вызовом через call решит проблему Вот не хотелось бы лепить эти методы (хоть и проверенные временем) в свою "культурную" программу. start тоже бы не хотелось М.б. тупо cmd? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2013, 17:16 |
|
Как убрать "подвешивание" вызывающего приложения при вызове другого через Shell?
|
|||
---|---|---|---|
#18+
DoEvents мож куда воткнуть? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2013, 17:20 |
|
Как убрать "подвешивание" вызывающего приложения при вызове другого через Shell?
|
|||
---|---|---|---|
#18+
ZVIесли почему-то Shell долго формирует task IDИменно. Konst_Onebat-файл с вызовом через call решит проблемуУгу. Но некрасиво. Да и технология древняя дюже - BAT/CMD... чё тогда не VBS/JS, скажем? а если VBS - то какая нафиг разница, через Call или через WSHShell.Run? Дмитрий77AkinaWSHShell.Run. Никогда не использовал и не люблю такие штуки Shocker.Proили через ShellExecute Да, уже об этом подумал.Т.е. либо одна крайность, либо другая, а вот серединку - ни-ни... ну можно и так. Дмитрий77DoEvents мож куда воткнуть? *ROFL* ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2013, 17:29 |
|
Как убрать "подвешивание" вызывающего приложения при вызове другого через Shell?
|
|||
---|---|---|---|
#18+
doevents воткнуть внутрь shell - это конечно забавно, но все варианты уже предложили, выбирай ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2013, 17:31 |
|
Как убрать "подвешивание" вызывающего приложения при вызове другого через Shell?
|
|||
---|---|---|---|
#18+
Дмитрий77М.б. тупо cmd? Тупо cmd Код: vbnet 1. 2.
"решает" проблему, но при этом cmd тупо висит до закрытия logbook.exe. Не есть гуд. А использовать start /w или bat тупо не хочу. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2013, 17:32 |
|
Как убрать "подвешивание" вызывающего приложения при вызове другого через Shell?
|
|||
---|---|---|---|
#18+
Akinaчё тогда не VBS/JS, скажем? VBS/J могут быть отключены админом, а BAT не отключают ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2013, 17:33 |
|
Как убрать "подвешивание" вызывающего приложения при вызове другого через Shell?
|
|||
---|---|---|---|
#18+
Дмитрий77А использовать start /w или bat тупо не хочу. Вместо BAT можно сделать свою легкую EXE , которая быстро отпустит Shell и будет долго грузить logbook.exe ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2013, 17:36 |
|
Как убрать "подвешивание" вызывающего приложения при вызове другого через Shell?
|
|||
---|---|---|---|
#18+
AkinaДмитрий77Shocker.Proили через ShellExecute Да, уже об этом подумал. Можно попробовать Но ShellExecute это не то же самое что Shell? Небось также ждет результата. Нет? Да, уже об этом подумал.Т.е. либо одна крайность, либо другая, а вот серединку - ни-ни... ну можно и так . Уверен что можно? А то сейчас начну структуры копать а она в итоге все равно ждать будет. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2013, 17:45 |
|
Как убрать "подвешивание" вызывающего приложения при вызове другого через Shell?
|
|||
---|---|---|---|
#18+
ZVI...cделать свою легкую EXE , которая ... Вот скажи, сколько этих легких exe можно делать? Я уже "легкую" dll 3-й день делаю Что интересно давно сделал, но местному C++ народу все чего-то не нравится. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2013, 17:46 |
|
Как убрать "подвешивание" вызывающего приложения при вызове другого через Shell?
|
|||
---|---|---|---|
#18+
Дмитрий77Akinaпропущено... Т.е. либо одна крайность, либо другая, а вот серединку - ни-ни... ну можно и так . Уверен что можно? А то сейчас начну структуры копать а она в итоге все равно ждать будет. М.б. http://msdn.microsoft.com/en-us/library/windows/desktop/bb762154(v=vs.85).aspx]ShellExecute Ex function SHELLEXECUTEINFO structure SEE_MASK_ASYNCOK (0x00100000) The execution can be performed on a background thread and the call should return immediately without waiting for the background thread to finish. Note that in certain cases ShellExecuteEx ignores this flag and waits for the process to finish before returning. Похоже на правду? Вечером попробую. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2013, 18:04 |
|
Как убрать "подвешивание" вызывающего приложения при вызове другого через Shell?
|
|||
---|---|---|---|
#18+
ZVIVBS/J могут быть отключены админом, а BAT не отключают Сказать. что удивил ты меня этой фразой - всё равно что ничего не сказать... Дмитрий77М.б. http://msdn.microsoft.com/en-us/library/windows/desktop/bb762154(v=vs.85).aspx]ShellExecute Ex function SHELLEXECUTEINFO structure SEE_MASK_ASYNCOK (0x00100000) The execution can be performed on a background thread and the call should return immediately without waiting for the background thread to finish. Note that in certain cases ShellExecuteEx ignores this flag and waits for the process to finish before returning. Ооо... счас начнём ещё потоки да нити плодить, мутантов всяких - исключительно ради того, чтобы не запустить повторно дочерний процесс... Кстати, а откель этот logbook.exe, а? не тобою писаный, часом? может, именно его нагрузить заботой не стартовать повторно? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2013, 18:17 |
|
Как убрать "подвешивание" вызывающего приложения при вызове другого через Shell?
|
|||
---|---|---|---|
#18+
[quot Дмитрий77]ZVIЧто интересно давно сделал, но местному C++ народу все чего-то не нравится. Просмотрел бегло. Там же возня со связкой C - VB, поэтому "легкости" нет :-) Правильно было сделано в начале, во 2-м сообщении, с возвратом 2-байтного указателя на начало строки. Только чтобы не копировать в VB побайтно с помощью накладных вызовов CopyMemory нужно было еще со стороны С возвращать длину строки, например, в модифицируемом со стороны C параметре (int для С и Long для VB). В VB создать string-переменную, в которую заполнить через String(Длина&,0), а потом одним CopyMemory скопировать текст. Обычно еще делается txt = StrConv(txt, vbUnicode), если в С строка не в Unicode. Имя переменной str там не удачное, т.к. такое уже зарезервировано для функции в VB. А память там освобождать и не нужно было, потому что исходная С-ная строка не модифицируется, а создается копия строки в VB, и возвращаемый указатель там используется только для копирования С-шной строки в другую VB-строку. Там еще ниже было что-то про пустой возврат строки, не вникал, но такое бывает из-за нулевых байтов в начале строки, помнится, вроде бы такое лечилось Trim-ом в VB. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2013, 18:52 |
|
Как убрать "подвешивание" вызывающего приложения при вызове другого через Shell?
|
|||
---|---|---|---|
#18+
AkinaОоо... счас начнём ещё потоки да нити плодить, мутантов всяких - исключительно ради того, чтобы не запустить повторно дочерний процесс...? Akina, речь идет не о повторном запуске logbook.exe. Код который приведен в начале прекрасно и быстро справляется с НЕзапуском logbook.exe повторно. Речь идет о том случае когда logbook.exe еще НЕ запущен. Конкретно о коде Код: vbnet 1.
который возвращает ID нового процесса и из-за этого подвешивает вызывающее приложение до тех пор пока этот ID не получен. Мне этот ID нафик не нужен. Т.е. задача чтобы команда вышла сразу и не ждала. AkinaКстати, а откель этот logbook.exe, а? не тобою писаный, часом? может, именно его нагрузить заботой не стартовать повторно? Я отвечу, хотя к вопросу отношения не имеет. >не тобою писаный, часом? Часом мной. >может, именно его нагрузить заботой не стартовать повторно? Там такой код присутствует: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Но в данном конкретном случае проще проверить что logbook.exe уже запущен из вызывающего приложения в лоб, не злоупотребляя холостыми запусками. Проблемка не для случая когда запущен а для случая КОГДА ЕЩЕ НЕ ЗАПУЩЕН И НАДО ЗАПУСИТЬ . ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2013, 20:34 |
|
Как убрать "подвешивание" вызывающего приложения при вызове другого через Shell?
|
|||
---|---|---|---|
#18+
ZVIПросмотрел бегло. Там же возня со связкой C - VB, поэтому "легкости" нет :-) Правильно было сделано в начале, во 2-м сообщении, с возвратом 2-байтного указателя на начало строки. В реальный проект я ПОКА засунул именно этот вариант, когда ф-ция возвращает char * ZVIТолько чтобы не копировать в VB побайтно с помощью накладных вызовов CopyMemory нужно было еще со стороны С возвращать длину строки, например, в модифицируемом со стороны C параметре (int для С и Long для VB). Вот потому что бегло ты не увидел вот этого: 14513805 Где я именно применяю "классический" прием с возвратом длины, копированием строки в буфер и отсеканием \0 через Left$(buf, length). И по этому варианту я пока жду комментариев, т.к. его можно применять достаточно широко и хорошо бы сразу отработать технику с "запасом прочности". ZVIОбычно еще делается txt = StrConv(txt, vbUnicode), если в С строка не в Unicode. Ой-ей. Вот про эту глючную конструкцию только мне не напоминайте. Строка полученная таким образом возвращает потом неправильный len(txt) и я об этом не раз говорил. ZVIИмя переменной str там не удачное, т.к. такое уже зарезервировано для функции в VB. По жизни использую str внутри функций, раньше вообще об этом не думал. К проблемам вроде никогда не приводило. ZVIиз-за нулевых байтов ...помнится, вроде бы такое лечилось Trim-ом в VB. Ни фига Trim нулевые байты не отсекает. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2013, 21:03 |
|
Как убрать "подвешивание" вызывающего приложения при вызове другого через Shell?
|
|||
---|---|---|---|
#18+
Дмитрий77Ни фига Trim нулевые байты не отсекает. Да, вспомнил, там лишний нуль оставался в конце :) ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2013, 21:17 |
|
Как убрать "подвешивание" вызывающего приложения при вызове другого через Shell?
|
|||
---|---|---|---|
#18+
Дмитрий77в данном конкретном случае проще проверить что logbook.exe уже запущен из вызывающего приложения в лоб, не злоупотребляя холостыми запусками Переварить не удалось - с моей точки зрения это неверный подход. Для меня он аналогичен тому, что ты вместо простого вызова метода объекта или получения свойства объекта начинаешь эмулировать его внешними для этого экземпляра объекта средствами кода, в котором значение свойства или выполнение метода потребовались. Ну да ладно, просто примем на веру, что так надо. Следовательно, у тебя просто проблема старта этого приложения через Shell. Посему я бы предложил отбросить все свои предубеждения, закодить все возможные реализации запуска, после чего их сравнить - по коду, по тормозам, по иным параметрам - и выбрать с твоей точки зрения оптимальный. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2013, 22:58 |
|
Как убрать "подвешивание" вызывающего приложения при вызове другого через Shell?
|
|||
---|---|---|---|
#18+
Короче, я сделал тесты с ShellExecute и ShellExecuteEx Вот этого: Дмитрий77ShellExecuteEx SEE_MASK_ASYNCOK (0x00100000) The execution can be performed on a background thread and the call should return immediately without waiting for the background thread to finish. Note that in certain cases ShellExecuteEx ignores this flag and waits for the process to finish before returning. ни фига не надо. SEE_MASK_DEFAULT достаточно даже если я хочу заполучить этот несчастный ID запущенного процесса (а я НЕ ХОЧУ) для чего использую SEE_MASK_NOCLOSEPROCESS + .hProcess ShellExecuteEx всегда возвращает результат МГНОВЕННО И даже этого не надо. Достаточно обычной ShellExecute без всяких Ex ShellExecute тоже возвращает результат МГНОВЕННО А вот Shell (который VB6-Production) чего-то ждет и висит до тех пор пока форма не загрузится. Код: vbnet 1. 2. 3. 4. 5. 6.
Это ответ. И другого здесь быть не может. В принципе и Shocker.Pro в 3-м посте об этом сказал, и я сам об этом подумал. Но я всю жизнь использовал этот Код: vbnet 1.
но никогда не думал что ДО ТАКОВО МАРАЗМА Думаю хорошая идея проинспектировать все свои коды на предмет ЧИСТКИ от поганца ... |
|||
:
Нравится:
Не нравится:
|
|||
03.07.2013, 23:26 |
|
Как убрать "подвешивание" вызывающего приложения при вызове другого через Shell?
|
|||
---|---|---|---|
#18+
Дмитрий77Вот потому что бегло ты не увидел вот этого: 14513805 Где я именно применяю "классический" прием с возвратом длины, копированием строки в буфер и отсеканием \0 через Left$(buf, length). И по этому варианту я пока жду комментариев, т.к. его можно применять достаточно широко и хорошо бы сразу отработать технику с "запасом прочности" То ж другая ветка, мне туда незачем было ходить. Но ответил там с "более классическим" примером. В предыдущем сообщении я приврал насчет 2-х байт, 4 конечно. В общем, со строками в/из DLL не должно быть проблем, если понимать производимые при этом без нашего участия преобразования из BSTR (VB) в т.н. ABSTR (DLL) и обратно. BSTR представляет из себя массив, в 4-х первых байтах которого записана Long длина сроки в байтах, дальше следуют 2-х байтные (Unicode в терминологии MS) символы. VarPtr(txt$) указывает на StrPtr(txt$), которая в свою очередь указывает на 5-й байт этого BSTR-массива, т.е. на 1-й байт собственно текстовой части массива. Перед тем как передать txt в DLL, VB создает временную переменную (массив), в которую кладет суррогат из BSTR. Этот суррогат неформально называют ASCII BSTR или сокращенно ABSTR. У него те же 4 байта с прежним значением, а затем идут однобайтные символы, полученные из Unicode 2-байтных, и в конце еще добавляется байтик с нулем. То есть, длина текстовой части ABSTR в байтах в 2 раза короче текстовой части BSTR плюс 1 нулевой байт в конце. DLL что-то делает с этим суррогатом и хорошо, если не меняет длину ABSTR, так как первые 4 байта не корректируются. В обратном порядке txt может быть возвращена из DLL в VB, но StrPtr$(txt) при этом может быть уже другим. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2013, 00:34 |
|
Как убрать "подвешивание" вызывающего приложения при вызове другого через Shell?
|
|||
---|---|---|---|
#18+
ZVI, Спасибо. К dll еще вернусь. Но сейчас надо с Shell аккуратно довоевать. Ногами его и ф топку. На самом деле я погорячился насчет Дмитрий77 А вот Shell (который VB6-Production) чего-то ждет и висит до тех пор пока форма не загрузится. Но я всю жизнь использовал этот Код: vbnet 1.
... Думаю хорошая идея проинспектировать все свои коды на предмет ЧИСТКИ от поганца Идея может и хорошая, но менять Shell на ShellExecute в существующих кодах надо аккуратно. Где-то надо (как в случае приведенном в первом посте). Где-то не имеет смысла (например при командах типа Shell ("explorer" ...), либо когда известно что запускаемое приложение быстрое и скорость запуска не зависит от к-ва данных и т.п.) А вот в одном месте я просто с разбегу накололся: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
Фишка в чем. hwndScreen -'это окно заставки И доступно оно будет (<> 0) только когда форма заставки загрузится (в приложении screen.exe) Когда я эту фигню делал, меня занимал вопрос: А вдруг я не смогу поймать hwndScreen = FindMyWindow(3) ? Ведь я только запустил screen.exe и окно могло НЕ УСПЕТЬ запуститься. И честно готовился чего-нибудь дописывать. В итоге все оказалось OK. Я об этом забыл. А в рамках начатой было компании по борьбе с Shell которую я было развернул, сделав замену Код: vbnet 1. 2.
я получил мгновенный выход и незапуск нужного мне окна hwndScreen на момент FindMyWindow(3) как итог полный сбой алгоритма Т.е. я неявно использовал свойство Shell (VB6) не выходить до загрузки формы. Ну, все хорошо в своем месте в свое время. А понимание никогда не повредит. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2013, 01:36 |
|
|
start [/forum/topic.php?fid=60&msg=38319394&tid=2156877]: |
0ms |
get settings: |
10ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
46ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
61ms |
get tp. blocked users: |
1ms |
others: | 297ms |
total: | 450ms |
0 / 0 |