Как UAC повысить компонент COM с помощью.NET
Я нашел статью о том, как поднять COM-объект, написанный на C++, вызвав CoCreateInstanceAsAdmin
, Но то, что я не смог найти или сделать, - это способ реализовать компонент моего приложения.NET (C#) в виде COM-объекта, а затем вызвать этот объект для выполнения задач, требующих повышения UAC. MSDN документирует это как объектную модель COM администратора.
Я знаю, что можно и довольно легко запустить приложение (или другое приложение) в качестве администратора, выполнить задачи в отдельном процессе (см., Например, сообщение от Daniel Moth, но я ищу способ делать все из одного и того же невыпущенного исполняемого файла.NET. Это, конечно, порождает COM-объект в новом процессе, но благодаря прозрачному маршаллингу вызывающий.NET COM-объект не должен (слишком сильно) осознаю это.
Любые идеи относительно того, как я мог бы создать COM-объект, написанный на C#, из проекта C#, через CoCreateInstanceAsAdmin
API был бы очень полезен. Так что мне действительно интересно узнать, как написать COM-объект в C#, который я затем могу вызывать из C# через API повышения COM.
Не берите в голову, если повышенный 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 ответа
Посмотрите пример кода демонстрации UAC в Windows Vista
(Вам также необходим пример 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);
}
Я думаю, что единственный способ CoCreateInstanceAsAdmin работает, если вы зарегистрировали COM-компонент заранее. Это может быть проблемой, если вы хотите, чтобы ваше приложение работало в настройках развертывания XCopy.
Для своих собственных целей в Галлио я решил создать небольшой процесс хостинга на стороне с манифестом, требующим прав администратора. Затем, когда мне нужно выполнить повышенное действие, я запускаю экземпляр процесса хостинга и инструктирую его через.Net remoting для выполнения определенной команды, зарегистрированной в контейнере Gallio Inversion of Control.
Это довольно трудоемкая работа, но у Галлио уже был хостинг вне процесса, поэтому добавить повышение в смесь было не слишком сложно. Более того, этот механизм гарантирует, что Gallio может выполнять повышение привилегий, не требуя предварительной установки каких-либо других компонентов COM в реестре.
Элементы возвышения являются процессами. Итак, если я правильно понимаю ваш вопрос и вам нужен способ поднять COM-объект в вашем процессе, то ответ - вы не можете. Весь смысл CoCreateInstanceAsAdmin - НЕ запускать его в вашем процессе.