delphi - COM API 调用后,仅在 Windows 7 上切换用户或锁定工作站时出现 EOSError 异常(访问被拒绝)

标签 delphi com access-denied switch-user

我的 Delphi 6 应用程序收到 EOSError 异常,代码 5,访问被拒绝,但仅当我切换到另一个 Windows 7 用户帐户或锁定工作站时。我正在打印堆栈跟踪,但错误似乎直接来自 Application.Run() 语句,而 Application.ProcessMessages() 紧接在堆栈上的下面。堆栈的其余部分是我的异常处理代码。

在操作期间,代码确实会调用 ShellExecuteEx() 并访问 COM/ActiveX 对象,但仅当用户显式单击按钮时才有效。这只发生在 Windows 7 上,不会发生在 Windows XP 上。我更改了我的应用程序,以便它完全安装到用户应用程序数据目录,因此不需要访问任何管理权限目录。我知道这并不重要,但我指出这一点以防万一。

当这种情况发生时,异常就会来得又快又猛。我捕获它们并将它们转储到错误日志中,以避免大量的对话框困扰用户。谁能告诉我,仅仅通过切换或锁定当前登录的用户,什么会引发大量这些错误?当当前用户帐户未激活时,为什么我的应用程序会遇到问题?

一个想法。如果用户当前未登录,某些位图操作是否会导致问题?我确实有一个旋转标签云,它不断执行 Windows API 位图操作以更新标签云图像。会不会跟这个有关系?

如果是这样,我可以尝试在当前用户被切换或锁定时停用标签云,但我相信我需要 Delphi 代码来对 Stack Overflow 帖子中提到的事件使用react:

How do I detect a Lock This Computer command from a WPF application?

更新:我做了一些额外的测试。直到我访问我正在与之交互的软件 Evernote 的 COM/ActiveX 接口(interface)后,这些错误才会发生。当我通过 COM API 第一次调用 Evernote 时,当我锁定工作站时,错误立即发生。

最佳答案

我发现了问题。这是因为我在计时器上调用 Controls.TMouse.GetCursorPos() 来更新我在原始帖子中提到的标签云 View 。如果当前桌面不可用,例如当您切换到另一个用户帐户或锁定工作站时,该功能将引发异常。这篇 Stack Overflow 帖子涵盖了 GetCursorPos() 函数的一般 WinAPI 上下文中的问题。

Call to TMouse.GetCursorPos sometimes fails with "A call to an OS function failed"

与上述帖子的作者相反,这种情况只发生在 Windows 7 上,而在 Windows XP 上不会。我需要更改代码以检测事件桌面何时不再可用,并使用下面链接的帖子中介绍的 session 锁定/解锁/登录/注销检测技术来抑制该调用,如下所示TLama。请参阅 DavidHeffernan 的回答:

What does an application have to do in order "support" Remote Desktop Services?

关于delphi - COM API 调用后,仅在 Windows 7 上切换用户或锁定工作站时出现 EOSError 异常(访问被拒绝),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12773935/

相关文章:

c# - 在托管代码和非托管代码之间传递非托管结构的安全数组

成功验证后,Spring Security 通过拒绝访问异常重定向到登录页面

java - 在 Windows Vista 上请求 Java 应用程序的管理员权限

delphi - 没有主图标的服务应用程序

api - 为什么某些函数在导入表中出现多次?

delphi - 您对 uniGUI 这个同时创建 Web 应用程序和 win32 应用程序的框架有何看法?

com - 为什么在 C++ 中的 Windows COM 编程中有这么多方法显式解析为全局命名空间?

Delphi 中的 Json 和 System.JSON

c# - 在 C# 中捕获 COM 异常的最佳实践是什么?

c++ - 可以使用错误代码为 ERROR_ACCESS_DENIED 的 OpenProcess 来了解进程是否存在吗?