如何使用.NET提升UAC COM组件

16
我在一篇文章中发现了如何通过调用CoCreateInstanceAsAdmin来提升使用C++编写的COM对象。但是我没有找到或做到的是,以一种方式实现我的.NET(c#)应用程序组件作为一个COM对象,然后调用该对象以执行需要UAC提升的任务。MSDN将此文档化为管理员COM对象模型
我知道可以并且很容易以管理员身份启动应用程序(或另一个应用程序),以在单独的进程中执行任务(例如,参见Daniel Moth的文章),但我正在寻找的是一种方法从同一个未提升的.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 */ }
}

然后,我的主应用程序只需通过CoCreateInstanceAsAdmin调用来实例化ElevatedClass。但也许这只是我的梦想。

3个回答

8

查看Windows Vista UAC演示样例代码

(您还需要Vista Bridge示例来使用UnsafeNativeMethods.CoGetObject方法)

这提供了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);
}

3
我认为CoCreateInstanceAsAdmin的唯一途径是预先注册COM组件。如果您打算在XCopy部署环境中使用应用程序,这可能会成为问题。
为了满足Gallio的需求,我决定创建一个具有管理员权限要求的小型托管进程,并在旁边添加清单。然后,在需要执行提升操作时,我启动托管进程的实例,并通过.Net remoting指示其执行Gallio的Inversion of Control容器中注册的特定命令。
这是相当大量的工作,但Gallio已经拥有一个外部托管设施,因此将提权添加到混合中并不太难。此外,该机制确保Gallio可以执行特权提升,而无需先安装注册表中的任何其他COM组件。

感谢您的反馈;运行单独的托管进程并不是我的意图。我真的很希望能够像与本地对象交互一样与提升的COM组件进行交互(即,提升的COM组件应该能够回调其他本地.NET对象)。 - Pierre Arnaud

2

提升的元素是过程。如果我正确理解了您的问题,并且您想要一种在进程中提升COM对象的方法,那么答案是您不能够这样做。CoCreateInstanceAsAdmin的整个目的是不在您的进程中运行它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接