如何使用.NET升级COM组件

时间:2008-09-24 13:13:18

标签: c# com uac elevation moniker

我发现了article如何通过调用来提升用C ++编写的COM对象 CoCreateInstanceAsAdmin。但是我无法找到或做的是将.NET(c#)应用程序的一个组件实现为COM对象,然后调用该对象来执行需要UAC提升的任务。 MSDN将其记录为admin COM object model

我知道以管理员身份启动应用程序(或其他应用程序)是可行且非常容易的,以便在单独的进程中执行任务(例如参见post from Daniel Moth,但我在寻找什么for是一种在相同的,未提升的.NET可执行文件中执行所有操作的方法。当然,这样做会在新进程中生成COM对象,但是由于透明的编组,.NET COM对象的调用者应该不要(太多)意识到它。

关于如何使用C#项目,通过CoCreateInstanceAsAdmin API实现用C#编写的COM对象的任何想法都会非常有用。所以我真的很想学习如何在C#中编写COM对象,然后我可以通过COM高程API从C#调用它。

不要紧,提升的COM对象是否在同一进程中运行。我只是不想让整个应用程序升级;我想要提升将执行代码的COM对象。如果我能写出一些东西:

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

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

然后让我的主应用程序通过ElevatedClass调用实现CoCreateInstanceAsAdmin。但也许我只是在做梦。

3 个答案:

答案 0 :(得分:8)

查看Windows Vista UAC Demo Sample Code

(还需要UnsafeNativeMethods.CoGetObject方法的Vista Bridge示例)

它为您提供了C#代码,它们显示了几种不同的提升方式,包括COM对象

(不完整的代码示例 - 抓取上面的文件)

[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);
}

答案 1 :(得分:3)

我认为CoCreateInstanceAsAdmin工作的唯一方法是提前注册COM组件。如果您希望应用程序在XCopy部署设置中工作,则可能会出现问题。

出于我自己在Gallio的目的,我决定在旁边创建一个小的托管进程,其中包含需要管理员权限的清单。然后,当我需要执行提升操作时,我启动托管进程的一个实例,并通过.Net remoting指示它执行在Gallio的Inversion of Control容器中注册的特定命令。

这是一项相当多的工作,但Gallio已经拥有一个进程外托管设施,因此在混合中增加高度并不是太难。此外,此机制确保Gallio可以执行权限提升,而无需事先在注册表中安装任何其他COM组件。

答案 2 :(得分:2)

提升的要素是过程。因此,如果我正确理解您的问题,并且您想要一种方法来提升流程中的COM对象,那么答案就是您不能。 CoCreateInstanceAsAdmin的全部内容是不在您的过程中运行它。