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

发布于 2024-09-08 20:27:47 字数 2382 浏览 6 评论 0原文

我有一个 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 更改为管理员组具有相同的结果(我认为将它们复制到应用程序目录正在更改所有权和权限)

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

因此,这似乎是某种访问问题。也许这将有助于发现问题的原因。

2010.07.18 更新

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

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

{$SetPEOptFlags IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE}

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

I have a Delphi 2010 exe that launches a second exe. In the second exe, there is a dialog that calls openDialog.execute. When this runs under Windows 2008 Enterprise R2 under a remote desktop, it runs as expected, but when run as a remote application, as soon as the file dialog pops up, the application hangs, turning all of the application windows white. The only way to get out of it is to terminate the application. I tried replacing TOpenDialog with TFileOpenDialog, the results are the same. I've looked into modifying the RDP file that launches the main application, but cannot see any parameters there that would make a difference. Has anyone ever seen this kind of behavior before?


2010.07.13 Updated

This is reproducable using a simple example. There are two executable files in the example. The first is a file launcher, called m_module.exe, which contains one edit, one button, and the code below. I change the name of the executable file in the edit to match the second executable before I click the launch button:

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;

The second executable contains a button and the code below:

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

The first module is launched from an RDP file.

2010.07.14 Updated

I have discovered that if I copy the following dlls:

thumbcache.dll 
dtsh.dll 
wkscli.dll 

from the \Windows\System32 folder into the application folder, the problem is eliminated.

I've further discovered that changing ownership and permission levels of these dlls in the \Windows\System32 folder from TrustedInstaller to the Administrator's group has the same result (Copying them to the application directory is changing ownership and permission I think)

To confirm this, I verified that the errors reappeared if I changed the ownership and permission levels back to TrustedInstaller away from the Administrator's group.

So it appears that this is an access issue of some kind. Perhaps this will help in discovering the cause of the issue.

2010.07.18 Updated

Some additional information that might be helpful (provided by Embarcadero):

This MSDN article for GetWindowsDirectory http://msdn.microsoft.com/en-us/library/ms724454%28VS.85%29.aspx documents some interesting behavior of applications running under Terminal Services. While GetWindowsDirectory is not being called directly the sandboxing of the Windows System directory per user could be causing some sort of problem. Perhaps one of the DLLs in the calling chain to GetOpenFileNameA is trying to reference the real DLL in the real System directory instead of the sandboxed one thus causing a rights violation. It is just speculation but it is worth investigating. If you were able to get the SysInternals Process Monitor or Process Explorer working on the server you should be able to see commdlg32 and the other DLLs in the stack trace being loaded.

All legacy applications (i.e. all applications not created for Terminal Services or Remote Desktop Services) run under an Application Compatibility Layer. See this MSDN article http://msdn.microsoft.com/en-us/library/cc834995%28VS.85%29.aspx . The IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE flag is defined in Windows.PAS. For testing purposes you can add it to your application's PE header by adding Windows to your application's USES section and right under the USES section put:

{$SetPEOptFlags IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE}

This will cause your application to bypass the compatibility layer. I am currently investigating if spawned processes (e.g. your second exe) retain all of the rights and settings of the application defined under RDS.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

孤独难免 2024-09-15 20:27:47

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

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

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

PS 另请参阅这篇文章:如何调试应用程序的挂起? 但是我认为挂起只是您案例中另一个问题的结果。

Windows reports AV (c0000005) in thumbcache.dll module.

I think that thumbcache.dll have something to do with building/caching thumbnails for files. Building thumbnails may mean using 3rd party extensions to Explorer, which may not behave nicely with RDP.

Try that on clean system. Use VMWare or similar virtual machine to setup test configuration.

P.S. See also this article: How to debug application’s hang? But I think that hang is just consequence of another problem in your case.

琉璃梦幻 2024-09-15 20:27:47

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

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

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

FWIW, we have a similar situation, but it's driven by a security need, and not a crash. When our app runs via Citrix, we are forbidden to ever show the regular windows "open" or "save as" dialogs. So we rolled our own. It's got a combo of drive letters (local drives only), folder selector (restricted to the approved drives), filename selector, and filename edit box.

For us, this gets around any active directory issues, and keeps security happy. And it keeps the users from trying to drop files into our filesystem or see things they shouldn't.

If they're not running in the sandbox, we show the regular windows file dialogs. A wrapper function allows us to call it from anywhere and leave the "sandboxed vs windows" decision in one spot.

蓝眸 2024-09-15 20:27:47

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

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

I recommend you to use Process Explorer tool to view properties of your process. Check, which exactly DLLs are loaded in both cases (you can do it by selecting your process and opening lower pane in modules view).

You can also use Process Monitor tool to monitor process startup (again: in both cases) and see any references to DLLs in question.

难忘№最初的完美 2024-09-15 20:27:47

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

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

You seems to have narrowed your problem to an access issue of some kind, so the following explanation might not help you. But there seems to exist a problem with popup windows on RemoteApp and I could imagine that it could lead (at least theoretically) to a similar problem, that's why I would like to mention it:
http://social.technet.microsoft.com/Forums/en-US/winserverTS/thread/0a88919f-2d72-4340-abd7-fbe0e9545f25/

Apparently the Z-order of the windows isn't always correct when using RemoteApp. In your case TOpenDialog should be a modal popup window. Due to the bug, I could imagine that TOpenDialog could appear in the background. Your main window would remain in the foreground but would be disabled as TOpenDialog is modal. Windows might then not know how to redraw a disabled window and simply draw a white box.

风情万种。 2024-09-15 20:27:47

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

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

这是一个解决方法 - 如果有人知道如何让 DEP 满意请在下面添加评论

We were having problems on the OpenDialog.Execute but only on one computer - and it seemed to be random
I found that adding the exe the Windows DEP may resolve the problem
we haven't had any issues since changing it

here is the link on how to change the windows DEP settings
http://www.itechtalk.com/thread3591.html

this is a workaround - if anyone knows how to keep the DEP happy please add a comment below

三生殊途 2024-09-15 20:27:47

如果 Z 顺序不正确(我经常在 Citrix 中看到这种情况,但没有对其进行适当的修复),您仍然可以使用 ctrl-F4 或 alt-f4 关闭表单。此外,应用程序不会“不响应”。有时在任务之间切换时顺序会自行纠正

It the Z-order is incorrect (which I often see in Citrix, without having a proper fix to it) you would still be able to close the form with ctrl-F4 or alt-f4. Furthermore the application would not be "not responding". Sometimes the order will correct itself when switching between tasks

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文