当作为远程桌面应用程序运行时,Delphi TOpenDialog在Windows 2008中挂起

时间:2010-07-08 16:46:52

标签: windows delphi rda

我有一个Delphi 2010 exe,它启动了第二个exe。在第二个exe中,有一个调用openDialog.execute的对话框。当它在远程桌面下的Windows 2008 Enterprise R2下运行时,它会按预期运行,但作为远程应用程序运行时,一旦弹出文件对话框,应用程序就会挂起,转动所有应用程序窗口白色摆脱它的唯一方法是终止应用程序。我尝试用TFileOpenDialog替换TOpenDialog,结果是一样的。我已经考虑修改启动主应用程序的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文件夹中这些dll的所有权和权限级别从TrustedInstaller更改为管理员组具有相同的结果(将它们复制到应用程序目录正在改变我认为的所有权和权限)< / p>

为了确认这一点,我确认如果我将所有权和权限级别更改回远离管理员组的TrustedInstaller,则会再次出现错误。

所以看来这是某种访问问题。也许这有助于发现问题的原因。

2010.07.18更新

可能有用的一些其他信息(由Embarcadero提供):

这篇关于GetWindowsDirectory http://msdn.microsoft.com/en-us/library/ms724454%28VS.85%29.aspx的MSDN文章记录了在终端服务下运行的应用程序的一些有趣行为。虽然没有直接调用GetWindowsDirectory,但每个用户的Windows系统目录的沙盒可能会导致某种问题。也许GetOpenFileNameA的调用链中的一个DLL试图引用真实系统目录中的真实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中定义。出于测试目的,您可以将Windows添加到应用程序的PE标题中,方法是将Windows添加到应用程序的USES部分,并在USES部分下面添加:

{$ SetPEOptFlags IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE}

这将导致您的应用程序绕过兼容层。我目前正在调查产生的进程(例如你的第二个exe)是否保留了在RDS下定义的应用程序的所有权限和设置。

6 个答案:

答案 0 :(得分:2)

Windows在thumbcache.dll模块中报告AV(c0000005)。

我认为thumbcache.dll与构建/缓存文件缩略图有关。构建缩略图可能意味着使用资源管理器的第三方扩展,这可能与RDP表现不佳。

在干净的系统上尝试一下。使用VMWare或类似的虚拟机来设置测试配置。

P.S。另见本文:How to debug application’s hang?但我认为挂起只是您案件中另一个问题的结果。

答案 1 :(得分:2)

FWIW,我们有类似的情况,但它是由安全需求驱动的,而不是崩溃。当我们的应用程序通过Citrix运行时,我们被禁止将常规窗口显示为“打开”或“另存为”对话框。所以我们推出了自己的。它有一个驱动器号(仅限本地驱动器),文件夹选择器(仅限于已批准的驱动器),文件名选择器和文件名编辑框的组合。

对我们来说,这可以解决任何活动目录问题,并保持安全性。它使用户不会试图将文件放入我们的文件系统或查看他们不应该看到的东西。

如果它们没有在沙盒中运行,我们会显示常规的Windows文件对话框。包装函数允许我们从任何地方调用它,并在一个位置留下“沙盒vs windows”决定。

答案 2 :(得分:0)

我建议您使用Process Explorer工具查看流程的属性。检查在两种情况下都加载了哪些DLL(您可以通过选择进程并在模块视图中打开下方窗格来执行此操作)。

您还可以使用Process Monitor工具监控进程启动(再次:在两种情况下)并查看对相关DLL的任何引用。

答案 3 :(得分:0)

您似乎已将问题范围缩小到某种访问问题,因此以下说明可能对您没有帮助。但RemoteApp上的弹出窗口似乎存在问题,我可以想象它可能导致(至少在理论上)类似的问题,这就是为什么我要提到它: http://social.technet.microsoft.com/Forums/en-US/winserverTS/thread/0a88919f-2d72-4340-abd7-fbe0e9545f25/

使用RemoteApp时,显然Windows的Z顺序并不总是正确的。在你的情况下,TOpenDialog应该是一个模态弹出窗口。由于这个bug,我可以想象TOpenDialog可能会出现在后台。您的主窗口将保留在前台,但由于TOpenDialog是模态的,因此将被禁用。 Windows可能不知道如何重绘已禁用的窗口,只需绘制一个白框。

答案 4 :(得分:0)

我们在OpenDialog.Execute上遇到了问题,但只在一台计算机上出现问题 - 它似乎是随机的 我发现添加Windows DEP的exe可能会解决问题 自改变以来我们没有任何问题

这是关于如何更改Windows DEP设置的链接 http://www.itechtalk.com/thread3591.html

这是一种解决方法 - 如果有人知道如何让DEP保持高兴请在下面添加评论

答案 5 :(得分:0)

Z-order不正确(我经常在Citrix中看到,没有对它进行适当的修复)你仍然可以用ctrl-F4或alt-f4关闭表单。此外,该应用程序不会“没有响应”。有时,在任务之间切换时,订单会自行纠正