C# 如何使用 .NET UAC 提升 COM 组件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/127042/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to UAC elevate a COM component with .NET
提问by Pierre Arnaud
I've found an articleon 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.
我找到了一篇关于如何通过调用
CoCreateInstanceAsAdmin
. 但是我无法找到或做的是一种将我的 .NET (c#) 应用程序的组件实现为 COM 对象的方法,然后调用该对象以执行需要 UAC 提升的任务。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. 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# 项目通过CoCreateInstanceAsAdmin
API实例化用 C# 编写的 COM 对象的任何想法都会非常有帮助。所以我对学习如何用 C# 编写 COM 对象非常感兴趣,然后我可以通过 COM 提升 API 从 C# 调用它。
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:
如果提升的 COM 对象不在同一个进程中运行,没关系。我只是不想启动整个应用程序;我只想提升将执行代码的 COM 对象。如果我可以写一些类似的东西:
// 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.
然后让我的主应用程序ElevatedClass
通过CoCreateInstanceAsAdmin
调用实例化。但也许我只是在做梦。
回答by MSalters
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.
提升的要素是过程。因此,如果我正确理解您的问题,并且您想要一种在您的过程中提升 COM 对象的方法,那么答案是您不能。CoCreateInstanceAsAdmin 的全部意义在于不要在您的进程中运行它。
回答by Ryan
Look at Windows Vista UAC Demo Sample Code
看Windows Vista UAC Demo Sample Code
(You also need the Vista Bridgesample 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);
}
回答by Jeff Brown
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.
我认为 CoCreateInstanceAsAdmin 工作的唯一方法是您是否提前注册了 COM 组件。如果您希望应用程序在 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. 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.
出于我自己在 Gallio 的目的,我决定创建一个带有清单的小托管进程,以要求管理员权限。然后,当我需要执行提升的操作时,我会启动托管进程的一个实例,并通过 .Net 远程处理指示它执行在 Gallio 的控制反转容器中注册的特定命令。
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.
这是一项相当大的工作,但 Gallio 已经有一个进程外托管设施,因此在混合中添加海拔并不太难。此外,这种机制确保 Gallio 可以执行特权提升,而无需事先在注册表中安装任何其他 COM 组件。