以中等 UAC 完整性级别运行 CLR 应用程序?
我一直在开发一个 C# (WinForms) 应用程序,它使用 Office 2007 PIA 与 Outlook 2007 集成。在我的开发环境中,UAC 被禁用,我的所有功能都可以工作,但我的测试环境是 Vista 32 位且启用了 UAC 。
在测试环境中,Outlook 默认以中等完整性级别运行(当用户启动时)。我的应用程序需要高完整性级别(即它在启动时显示 UAC 提示)。在这种情况下,从我的应用程序实例化 Microsoft.Office.Interop.Outlook.Application
类失败,并显示 CO_E_SERVER_EXEC_FAILURE
(COMException
, HRESULT=0x80080005 )。
我可以通过两种方式解决这个问题:
- 确保当我的应用程序实例化
Application
时 Outlook 没有运行 - 这会强制 Outlook 在高完整性模式下运行,因为启动它的进程也在高完整性模式下运行。 - 指示 Outlook 始终以管理员身份运行(“兼容性”选项卡)。
值得注意的是,Word 和 Excel PIA不会出现此问题。
有什么办法可以解决这个问题吗?我的应用程序无法以低完整性级别运行,但有可能它可以适应以中等完整性级别运行 - 但是,我不知道如何做到这一点。 .NET 可执行文件是否可以在此模式下运行?
或者,即使存在不匹配的完整性级别,是否也可以通过某种方式与 Outlook 进行通信?正如我所说,Word 和 Excel 似乎对此没有问题。
I've been developing a C# (WinForms) application that uses the Office 2007 PIAs to integrate with Outlook 2007. In my dev environment, UAC is disabled and all of my functionality works, but my test environment is Vista 32-bit with UAC enabled.
In the test environment, Outlook runs at medium integrity level by default (when started by the user). My application requires high integrity level (i.e. it presents a UAC prompt on startup). In this scenario, instantiating the Microsoft.Office.Interop.Outlook.Application
class from my application fails with a CO_E_SERVER_EXEC_FAILURE
(COMException
, HRESULT=0x80080005).
I can get around this problem in 2 ways:
- Ensure Outlook is not running when my application instantiates
Application
- this forces Outlook to run in high integrity mode, since the process that starts it is also running at high integrity. - Instruct Outlook to always run as Administrator (Compatibility tab).
It is worthwhile to note that the Word and Excel PIAs do not exhibit this problem.
Is there any way around this problem? My application cannot run at low integrity, but there is a chance that it could be adapted to run at medium integrity level - however, I can't work out how to do this. Can .NET executables even run in this mode?
Alternatively, is there some way to communicate with Outlook even while there are mismatched integrity levels? As i've said, Word and Excel seem to have no problem with this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
.NET 应用程序可以在任何 UAC 完整性级别(包括系统和低级别)下运行。
但一个进程只有一个完整性级别(将完整性列添加到 Process Explorer 查看进程在完整性级别上的分布)。
如果您尝试运行 Outlook 的第二个实例,它只会将现有实例带入视图,它会主动阻止两个实例运行。 Word 和 Excel 没有。
这些共同解释了您所看到的内容。当您实例化 Word 或 Excel 应用程序对象时,会以匹配的完整性级别运行新的 Work 或 Excel 进程。如果您对 Outlook 执行此操作并且 Outlook 已在运行,那么它将尝试附加到该现有进程。但除非 Outlook 已经以高度完整性运行,否则此操作将会失败。您应该能够通过以管理员身份运行 Outlook(即高完整性)然后运行应用程序以附加到它来验证这一点。
要求用户以管理员身份运行 Outlook 是一个糟糕的主意(由于来自未知方的电子邮件附件的风险,以高完整性运行 Outlook 只会招致恶意软件感染)。
最好的方法(这就是 Explorer 等的做法)是将您的进程分成两部分,使用 COM 名称仅提升应用程序中真正需要提升的部分。有关如何执行此操作的问题,请参阅此问题:How to UAC elevate带有 .NET 的 COM 组件
.NET applications can run at any UAC integrity level (including system and low).
But one process has only one integrity level (add the integrity column to Process Explorer to see the distribution of processes across integrity levels).
If you try and run a second instance of Outlook, it will just bring the existing instance into view, it actively prevents two instances running. Word and Excel do not.
Together these explain what you are seeing. When you instantiate a Word or Excel application object a new Work or Excel process is run with matching integrity level. If you do this with Outlook and Outlook is already running then it will try to attach to that existing process. But this will fail unless Outlook is already running at high integrity. You should be able to validate this by running Outlook as administrator (i.e. high integrity) and then running your application to attach to it.
Requiring users to run Outlook as administrator is a poor idea (due to risks of attachments to email from unknown parties, running Outlook at high integrity is just inviting malware infection).
The best approach (and this is how Explorer etc. do it) is to split your process into two parts, using COM monikers to elevate only the parts of your application that really need elevation. See this SO question on how to do this: How to UAC elevate a COM component with .NET