Delphi TOpenDialog зависает в Windows 2008 при запуске в качестве приложения удаленного рабочего стола

У меня есть Delphi 2010 exe, который запускает второй exe. Во втором exe есть диалог, который вызывает openDialog.execute. Когда это выполняется в Windows 2008 Enterprise R2 на удаленном рабочем столе, оно работает как положено, но при запуске в качестве удаленного приложения, как только появляется диалоговое окно файла, приложение зависает, и все окна приложения становятся белыми. Единственный способ выйти из него - закрыть приложение. Я попытался заменить TOpenDialog на TFileOpenDialog, результаты совпадают. Я посмотрел на изменение файла RDP, который запускает основное приложение, но не видит там никаких параметров, которые могли бы изменить ситуацию. Кто-нибудь когда-либо видел такое поведение раньше?


2010.07.13 Обновлено

Это можно воспроизвести на простом примере. В примере есть два исполняемых файла. Первый - это средство запуска файлов, называемое m_module.exe, которое содержит одну кнопку редактирования, одну кнопку и приведенный ниже код. Я изменяю имя исполняемого файла в редакторе, чтобы он соответствовал второму исполняемому файлу, прежде чем я нажимаю кнопку запуска:

procedure TForm1.Button1Click(Sender: TObject);
begin
     ShellExecute(Handle, 'open', stringToOLEstr(edit1.text) , nil, nil, SW_SHOWNORMAL) ; 
end;

procedure TForm1.FormShow(Sender: TObject);
begin
     edit1.text:=application.exename;
end;

Второй исполняемый файл содержит кнопку и код ниже:

procedure TForm1.Button1Click(Sender: TObject);
begin
     OpenDialog1.execute;
end;

Первый модуль запускается из файла RDP.

2010.07.14 Обновлено

Я обнаружил, что если я копирую следующие DLL:

thumbcache.dll 
dtsh.dll 
wkscli.dll 

из папки \Windows\System32 в папку приложения проблема устранена.

Кроме того, я обнаружил, что изменение уровней владения и разрешений этих библиотек в папке \Windows\System32 с TrustedInstaller на группу администраторов приводит к тому же результату (копирование их в каталог приложения меняет владельца и разрешения, я думаю)

Чтобы убедиться в этом, я убедился, что ошибки появились снова, если я изменил уровни владения и разрешений обратно на TrustedInstaller вне группы администраторов.

Таким образом, похоже, что это проблема доступа какого-то рода. Возможно, это поможет выяснить причину проблемы.

2010.07.18 Обновлено

Некоторая дополнительная информация, которая может быть полезна (предоставлена ​​Embarcadero):

Эта статья MSDN для GetWindowsDirectory http://msdn.microsoft.com/en-us/library/ms724454%28VS.85%29.aspx описывает интересное поведение приложений, работающих в службах терминалов. Хотя GetWindowsDirectory не вызывается напрямую, песочница системного каталога Windows для пользователя может вызывать какие-то проблемы. Возможно, одна из библиотек DLL в вызывающей цепочке GetOpenFileNameA пытается сослаться на настоящую DLL в реальном системном каталоге, а не в изолированную, вызывая нарушение прав. Это просто предположение, но это стоит исследовать. Если вы смогли заставить SysInternals Process Monitor или Process Explorer работать на сервере, вы должны увидеть commdlg32 и другие DLL в загружаемой трассировке стека.

Все устаревшие приложения (т.е. все приложения, не созданные для служб терминалов или служб удаленных рабочих столов) работают на уровне совместимости приложений. См. Эту статью MSDN http://msdn.microsoft.com/en-us/library/cc834995%28VS.85%29.aspx. Флаг IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE определен в Windows.PAS. В целях тестирования вы можете добавить его в PE-заголовок вашего приложения, добавив Windows в раздел USES вашего приложения и прямо в разделе USES:

{$ SetPEOptFlags IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE}

Это заставит ваше приложение обходить уровень совместимости. В настоящее время я изучаю, сохраняют ли порожденные процессы (например, ваш второй exe) все права и настройки приложения, определенные в RDS.

6 ответов

FWIW, у нас похожая ситуация, но она вызвана необходимостью безопасности, а не крахом. Когда наше приложение запускается через Citrix, нам запрещено показывать обычные окна "открыть" или "сохранить как". Таким образом, мы катились самостоятельно. Он содержит комбинацию букв дисков (только для локальных дисков), селектора папок (только для утвержденных дисков), селектора имени файла и поля редактирования имени файла.

Для нас это позволяет обойти любые проблемы с активными каталогами и обеспечить безопасность. И это удерживает пользователей от попыток выбросить файлы в нашу файловую систему или увидеть вещи, которые они не должны.

Если они не работают в песочнице, мы показываем обычные диалоги файлов Windows. Функция-обертка позволяет нам вызывать ее из любого места и оставить решение "песочница против окон" в одном месте.

Windows сообщает AV (c0000005) в модуле thumbcache.dll.

Я думаю, что thumbcache.dll как-то связан с созданием / кэшированием миниатюр для файлов. Создание миниатюр может означать использование сторонних расширений для Explorer, которые могут плохо работать с RDP.

Попробуйте это на чистой системе. Используйте VMWare или аналогичную виртуальную машину для настройки конфигурации теста.

PS Смотрите также эту статью: Как отлаживать зависание приложения? Но я думаю, что зависание - просто следствие другой проблемы в вашем случае.

Если Z-порядок неверен (что я часто вижу в Citrix, без правильного исправления), вы все равно сможете закрыть форму с помощью ctrl-F4 или alt-f4. Кроме того, заявка не будет "не отвечать". Иногда порядок будет исправляться при переключении между задачами

Я рекомендую вам использовать инструмент Process Explorer для просмотра свойств вашего процесса. Проверьте, какие именно библиотеки DLL загружены в обоих случаях (вы можете сделать это, выбрав свой процесс и открыв нижнюю панель в представлении модулей).

Вы также можете использовать инструмент Process Monitor для мониторинга запуска процесса (опять же: в обоих случаях) и просмотра любых ссылок на рассматриваемые библиотеки DLL.

Похоже, вы сузили свою проблему до какой-то проблемы с доступом, поэтому следующее объяснение может вам не помочь. Но, похоже, существует проблема с всплывающими окнами в RemoteApp, и я мог предположить, что это может привести (по крайней мере теоретически) к аналогичной проблеме, поэтому я хотел бы упомянуть об этом: http://social.technet.microsoft.com/Forums/en-US/winserverTS/thread/0a88919f-2d72-4340-abd7-fbe0e9545f25/

Очевидно, Z-порядок окон не всегда корректен при использовании RemoteApp. В вашем случае TOpenDialog должен быть модальным всплывающим окном. Из-за ошибки я мог представить, что TOpenDialog может появиться в фоновом режиме. Ваше главное окно останется на переднем плане, но будет отключено, так как TOpenDialog является модальным. Тогда Windows может не знать, как перерисовать отключенное окно, и просто нарисовать белое поле.

У нас были проблемы с OpenDialog.Execute, но только на одном компьютере - и казалось, что это случайно, я обнаружил, что добавление исполняемого файла Windows DEP может решить проблему, с которой у нас не было проблем с момента ее изменения

вот ссылка на то, как изменить настройки Windows DEP http://www.itechtalk.com/thread3591.html

это обходной путь - если кто-нибудь знает, как сохранить DEP счастливым, пожалуйста, добавьте комментарий ниже

Другие вопросы по тегам