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

发布于 2024-07-05 05:49:55 字数 1221 浏览 14 评论 0原文

我找到了一篇文章,介绍如何通过调用来提升用 C++ 编写的 COM 对象 CoCreateInstanceAsAdmin。 但我还没有找到或做的是一种将 .NET (c#) 应用程序的组件实现为 COM 对象,然后调用该对象来执行需要 UAC 提升的任务的方法。 MSDN 将其记录为管理 COM 对象模型

我知道以管理员身份启动应用程序(或其他应用程序),在单独的进程中执行任务是可能且非常容易的(例如,请参阅 来自 Daniel Moth 的帖子,但我正在寻找的是一种在同一个内部完成所有操作的方法,未提升的 .NET 可执行文件当然会在新进程中生成 COM 对象,但由于透明编组,.NET COM 对象的调用者不应该(太多)意识到它

。关于如何通过 CoCreateInstanceAsAdmin API 从 C# 项目实例化用 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 。 但也许我只是在做梦。

I've found an article on how to elevate a COM object written in C++ by calling
CoCreateInstanceAsAdmin. 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. MSDN documents this as the admin COM object model.

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.

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. 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.

Never mind if the elevated COM object does not run in the same process. 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. 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. But maybe I am just dreaming.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

树深时见影 2024-07-12 05:49:55

查看 Windows Vista UAC 演示示例代码

(您还需要 UnsafeNativeMethods 的 Vista Bridge 示例.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);
}

Look at Windows Vista UAC Demo Sample Code

(You also need the Vista Bridge sample for UnsafeNativeMethods.CoGetObject method)

Which gives you C# code that shows a few different ways to elevate, including a COM object

(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 2024-07-12 05:49:55

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

为了我自己在 Gallio 中的目的,我决定在旁边创建一个小型托管进程,并带有一个需要管理员权限的清单。 然后,当我需要执行提升的操作时,我会启动托管进程的一个实例,并通过 .Net 远程处理指示它执行在 Gallio 的控制反转容器中注册的特定命令。

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

I think the only way CoCreateInstanceAsAdmin works is if you have registered the COM component ahead of time. That may be a problem if you intend your application to work in an XCopy deployment setting.

For my own purposes in Gallio I decided to create a little hosting process on the side with a manifest to require admin privileges. 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.

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. Moreover, this mechanism ensures that Gallio can perform privilege elevation without requiring prior installation of any other COM components in the registry.

梦境 2024-07-12 05:49:55

提升的要素是过程。 所以,如果我正确理解你的问题,并且你想要一种在你的进程中提升 COM 对象的方法,那么答案是你不能。 CoCreateInstanceAsAdmin 的全部要点是不要在您的进程中运行它。

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. The entire point of CoCreateInstanceAsAdmin is to NOT run it in your process.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文