У меня есть exe Delphi 2010, который запускает второй 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 Обновлено
Я обнаружил, что если я скопирую следующие dlls:
thumbcache.dll
dtsh.dll
wkscli.dll
из папки \Windows\System32 в папку приложения, проблема устранена.
Я также обнаружил, что изменение прав собственности и уровней разрешений для этих DLL в папке \Windows\System32 из TrustedInstaller в группу "Администратор" имеет тот же результат (копирование их в каталог приложения меняет право собственности и разрешение, я думаю)
Чтобы подтвердить это, я подтвердил, что ошибки появились снова, если я изменил права собственности и уровни разрешения на TrustedInstaller вдали от группы "Администратор".
Итак, похоже, что это проблема доступа. Возможно, это поможет обнаружить причину проблемы.
2010.07.18 Обновлено
Дополнительная информация, которая может быть полезной (предоставляется Embarcadero):
Эта статья MSDN для GetWindowsDirectory http://msdn.microsoft.com/en-us/library/ms724454%28VS.85%29.aspx документирует интересное поведение приложений, запущенных в Terminal Services. Хотя GetWindowsDirectory не вызывается непосредственно, песочница системного каталога Windows для каждого пользователя может вызвать какую-то проблему. Возможно, одна из DLL в вызывающей цепочке GetOpenFileNameA пытается ссылаться на настоящую DLL в реальном каталоге System вместо изолированной, что приводит к нарушению прав. Это просто спекуляция, но стоит исследовать. Если вы смогли запустить 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.