如何使用.NET提升UAC COM组件
我找到了一篇有关如何通过调用来提升用C ++编写的COM对象的文章
CoCreateInstanceAsAdmin。但是我无法找到或者做的是一种将.NET(c#)应用程序的组件实现为COM对象,然后调用该对象执行需要UAC提升的任务的方法。 MSDN将其记录为管理COM对象模型。
我知道以管理员身份启动该应用程序(或者另一个应用程序)是可能且非常容易的,可以在一个单独的过程中执行任务(例如,参见Daniel Moth的帖子,但我正在寻找一种方法可以在同一未提升的.NET可执行文件中执行所有操作。当然,这样做会在一个新进程中生成COM对象,但是由于透明的编组,.NET COM对象的调用者不应该(很多)意识到这一点。
关于如何通过CoCreateInstanceAsAdmin
API从Cproject实例化用C#编写的COM对象的任何想法都将非常有帮助。因此,我对学习如何用C#编写COM对象非常感兴趣,然后可以通过C海拔高度的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
。但是也许我只是在做梦。
解决方案
高程的要素是过程。因此,如果我正确理解了问题,并且我们想要一种在处理过程中提升COM对象的方法,那么答案是我们不能做到。 CoCreateInstanceAsAdmin的重点是不要在过程中运行它。
查看Windows Vista UAC演示示例代码
(对于UnsafeNativeMethods.CoGetObject方法,我们还需要Vista Bridge示例)
这使Ccode可以显示几种不同的提升方式,包括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); }
我认为CoCreateInstanceAsAdmin的唯一工作方式是如果我们提前注册了COM组件。如果我们希望应用程序在XCopy部署设置中工作,则可能会出现问题。
出于我自己在Gallio中的目的,我决定在清单上创建一个小的托管过程,以要求管理员特权。然后,当我需要执行提升操作时,我启动了托管过程的实例,并通过.Net远程处理指示它执行在Gallio的Inversion of Control容器中注册的特定命令。
这是一项相当不错的工作,但是Gallio已经拥有了一个进程外托管设备,因此在组合中增加高度并不是一件难事。此外,此机制确保Gallio可以执行特权提升,而无需在注册表中事先安装任何其他COM组件。