Вы тоже можете использовать свои телепатические способности, чтобы найти решение этой проблемы:
У нас есть проблема с открытием документов в нашем приложении по двойному щелчку в Проводнике. При этом мы видим странную вещь: если мы подключим отладчик к Проводнику и установим точку останова на kernel32!CreateProcessW, то, подождав чуток после завершения CreateProcess, и нажимая возобновление процесса - тогда документ открывается нормально. Но если мы не будем ждать, то документ не открывается. Вместо этого появляется сообщение об ошибке "Windows не может найти файл 'abc.lit'. Убедитесь, что вы набрали его имя правильно и попробуйте ещё раз". Вот команда, которую мы использовали, когда встретились с этой проблемой:Если вы внимательно читали объяснение как работает открытие документов через DDE, то вы уже знаете, в чём проблема.
"F:\Program Files\LitSoft\LitWare\LitWare.exe" /ddeЧто не так?
Вспомните, что запуск документов через DDE выполняется сначала поиском DDE сервера, а затем, если таковой не найден, его запуском и повтором попытки. Командная строка выше очевидно регистрируется как команда, связанная с ddeexec. Почему? Для этого есть две подсказки. Во-первых: обратите внимание, что имя файла не участвует в командной строке (как программа узнает, какой файл ей надо открыть?). Вторая подсказка: наличие ключа /dde в командной строке.
Очевидно, что-то пошло не так, когда Проводник попытался выполнить повторную инициализацию DDE при открытии документа. Тот факт, что вставка ожидания в Проводник исправляет проблему, делает причину очевидной: DDE сервер слишком медленно инициализирует себя и не готов к коммуникации. Проводник запускает сервер и пытается с ним взаимодействовать, но сервер ещё не готов и не отвечает на инициализацию DDE.
Но как это исправить?
Оболочка предполагает, что DDE сервер готов к общению, когда он переходит к простою (input idle). Как только функция WaitForInputIdle возвращает управление, Проводник делает вторую попытку подключения. Исправление для приложения заключается в том, чтобы поднять работоспособный DDE сервер до начала цикла прокачки сообщений. Моё предположение было в том, что приложение переместило инициализацию DDE в фоновый поток, чтобы улучшить производительность запуска, поскольку DDE сервер не используется при обычной работе программы. Жаль, что программа забыла, что сервер должен работать к моменту обработки сообщений, когда ей передают флаг /dde.
Мораль истории: если вы хотите работать как DDE сервер, то убедитесь, что именно это вы и сделали, прежде чем ваш первичный поток начнёт обработку сообщений. В противном случае у вас будет условие гонки между запуском вашего приложения и оболочкой, которая пытается с вами общаться.
В Википедии термин "Race condition" переводят как "Состояние гонки", я тоже склоняюсь к тому, что так лучше.
ОтветитьУдалитьПереводят и так и сяк. Лично мне больше нравится вариант с "условие", но спасибо за замечание.
ОтветитьУдалитьКосяк с DDE-сервером
ОтветитьУдалить