简体   繁体   English

如何使用.NET升级COM组件

[英]How to UAC elevate a COM component with .NET

I've found an article on how to elevate a COM object written in C++ by calling CoCreateInstanceAsAdmin . 我发现了一篇关于如何通过调用CoCreateInstanceAsAdmin来提升用C ++编写的COM对象的文章 But what I have not been able to find or do, is a way to implement a component of my .NET (c#) application as a COM object and then call into that object to execute the tasks which need UAC elevation. 但是我无法找到或做的是将.NET(c#)应用程序的一个组件实现为COM对象,然后调用该对象来执行需要UAC提升的任务。 MSDN documents this as the admin COM object model . MSDN将此文档记录为管理COM对象模型

I am aware that it is possible and quite easy to launch the application (or another app) as an administrator, to execute the tasks in a separate process (see for instance the post from Daniel Moth , but what I am looking for is a way to do everything from within the same, un-elevated .NET executable. Doing so will, of course, spawn the COM object in a new process, but thanks to transparent marshalling, the caller of the .NET COM object should not be (too much) aware of it. 我知道以管理员身份启动应用程序(或其他应用程序)是可能的,并且很容易在单独的进程中执行任务(例如参见Daniel Moth帖子 ,但我正在寻找的是一种方式从同一个未提升的.NET可执行文件中做所有事情。当然,这样做会在新进程中生成COM对象,但是由于透明的编组,.NET COM对象的调用者不应该(也是很多)意识到这一点。

Any ideas as to how I could instanciate a COM object written in C#, from a C# project, through the CoCreateInstanceAsAdmin API would be very helpful. 有关如何使用C#项目,通过CoCreateInstanceAsAdmin API实现C#编写的COM对象的任何想法都非常有用。 So I am really interested in learning how to write a COM object in C#, which I can then invoke from C# through the COM elevation APIs. 所以我真的很想学习如何在C#中编写COM对象,然后我可以通过COM高程API从C#调用它。

Never mind if the elevated COM object does not run in the same process. 不要紧,升高的COM对象是否在同一进程中运行。 I just don't want to have to launch the whole application elevated; 我只是不想让整个应用程序升级; I would just like to have the COM object which will execute the code be elevated. 我想要提升将执行代码的COM对象。 If I could write something along the lines: 如果我能写出一些东西:

// in a dedicated assembly, marked with the following attributes:
[assembly: ComVisible (true)]
[assembly: Guid ("....")]

public class ElevatedClass
{
    public void X() { /* do something */ }
}

and then have my main application just instanciate ElevatedClass through the CoCreateInstanceAsAdmin call. 然后让我的主应用程序通过CoCreateInstanceAsAdmin调用实例化ElevatedClass But maybe I am just dreaming. 但也许我只是在做梦。

Look at Windows Vista UAC Demo Sample Code 查看Windows Vista UAC演示示例代码

(You also need the Vista Bridge sample for UnsafeNativeMethods.CoGetObject method) (您还需要针对UnsafeNativeMethods.CoGetObject方法的Vista Bridge示例)

Which gives you C# code that shows a few different ways to elevate, including a COM object 这为您提供了C#代码,显示了几种不同的提升方式,包括COM对象

(Incomplete code sample - grab the files above) (不完整的代码示例 - 抓取上面的文件)

[return: MarshalAs(UnmanagedType.Interface)]
static internal object LaunchElevatedCOMObject(Guid Clsid, Guid InterfaceID)
   {
   string CLSID = Clsid.ToString("B"); // B formatting directive: returns {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} 
   string monikerName = "Elevation:Administrator!new:" + CLSID;

   NativeMethods.BIND_OPTS3 bo = new NativeMethods.BIND_OPTS3();
   bo.cbStruct = (uint)Marshal.SizeOf(bo);
   bo.hwnd = IntPtr.Zero;
   bo.dwClassContext = (int)NativeMethods.CLSCTX.CLSCTX_ALL;

   object retVal = UnsafeNativeMethods.CoGetObject(monikerName, ref bo, InterfaceID);

   return (retVal);
}

I think the only way CoCreateInstanceAsAdmin works is if you have registered the COM component ahead of time. 我认为CoCreateInstanceAsAdmin工作的唯一方法是提前注册COM组件。 That may be a problem if you intend your application to work in an XCopy deployment setting. 如果您希望应用程序在XCopy部署设置中工作,那么这可能是一个问题。

For my own purposes in Gallio I decided to create a little hosting process on the side with a manifest to require admin privileges. 出于我自己在Gallio的目的,我决定在旁边创建一个托管进程,其中包含需要管理员权限的清单。 Then when I need to perform an elevated action, I spin up an instance of the hosting process and instruct it via .Net remoting to execute a particular command registered in Gallio's Inversion of Control container. 然后当我需要执行提升动作时,我启动一个托管进程的实例并通过.Net remoting指示它执行在Gallio的Inversion of Control容器中注册的特定命令。

This is a fair bit of work but Gallio already had an out of process hosting facility so adding elevation into the mix was not too hard. 这是一项相当多的工作,但Gallio已经有一个进程外托管设施,因此在混合中增加高度并不太难。 Moreover, this mechanism ensures that Gallio can perform privilege elevation without requiring prior installation of any other COM components in the registry. 此外,此机制确保Gallio可以执行权限提升,而无需事先在注册表中安装任何其他COM组件。

The elements of elevation are processes. 提升的要素是过程。 So, if I understand your question correctly, and you want a way to elevate a COM object in your process, than the answer is you can't. 因此,如果我正确理解您的问题,并且您想要一种方法来提升流程中的COM对象,那么答案就是您不能。 The entire point of CoCreateInstanceAsAdmin is to NOT run it in your process. CoCreateInstanceAsAdmin的全部内容是不在您的进程中运行它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM