#c #winapi #shellexecute
Вопрос:
Это то, что беспокоит меня уже некоторое время, и для этого просто должно быть решение. Каждый раз, когда я вызываю ShellExecute для открытия внешнего файла (будь то документ, исполняемый файл или URL-адрес), это вызывает очень длительную блокировку в моей программе, прежде чем ShellExecute создаст новый процесс и вернется. Кто-нибудь знает, как это решить или обойти?
ПРАВКА: И, как могут указывать теги, это на Win32 с использованием C .
Ответ №1:
Я не знаю, в чем причина этого, но у Марка Русиновича (известного как sysinternal) есть действительно отличный блог, в котором он объясняет, как отлаживать подобные вещи. Хорошим примером для вас был бы Случай с задержкой диалоговых окон открытия файлов Windows Vista, где он отладил аналогичную проблему, используя только проводник процессов (оказалось, что проблема с доступом к домену). Конечно, вы можете делать подобные вещи с помощью обычного отладчика Windows.
Ваша проблема, вероятно, не такая же, как у него, но использование этих методов может помочь вам приблизиться к источнику проблемы. Я предлагаю вызвать CreateProcess
вызов, а затем захватить несколько трассировок стека и посмотреть, где он, по-видимому, завис.
Случай задержки запуска процесса может быть еще более актуальным для вас.
Ответ №2:
Вы многопоточны?
Я видел проблемы с открытием файлов с помощью ShellExecute. Не исполняемые файлы, а файлы, связанные с приложением — обычно MS Office. Приложения, которые использовали DDE для открытия своих файлов, передавали некоторые сообщения всем потокам во всех (ну, я не знаю, было ли это все…) программах. Поскольку я не перекачивал сообщения в рабочие потоки в своем приложении, я бы повесил оболочку (и открытие файла) на некоторое время. В конце концов время ожидания истекло, ожидая, пока я обработаю сообщение, и приложение запустится и откроет файл.
Я помню, как использовал PeekMessage в цикле, чтобы просто удалять сообщения в очереди для этого рабочего потока. Я всегда предполагал, что есть способ избежать этого другим способом, может быть, создать поток по-другому, чтобы никогда не быть целью сообщений?
Обновите, это должен был быть не просто какой-либо поток, который делал это, а тот, который обслуживал окно. Раймонд (ссылка 1) знает все (ссылка 2). Держу пари, что либо CoInitialize (однопоточная квартира), либо что-то в MFC создало скрытое окно для потока.
Комментарии:
1. Таким образом, это означает, что потенциально любое приложение, запущенное на клиентской машине, на которой потоки не передают сообщения, может вызвать такую задержку? Поговорим о бесполезном API. 🙁
2. Обновлено с дополнительной информацией. Я столкнулся с этим где-то между 1996-1997 годами, так что мне потребовалось некоторое время, чтобы по-настоящему вспомнить всю проблему. С помощью Раймонда Чена.
3. Если в потоке есть окно, он должен перекачивать сообщения — это часть контракта на программирование в Windows