Как UAC повысить компонент COM с помощью .NET - PullRequest
15 голосов
/ 24 сентября 2008

Я нашел статью о том, как поднять COM-объект, написанный на C ++, с помощью вызова CoCreateInstanceAsAdmin. Но то, что я не смог найти или сделать, - это способ реализовать компонент моего приложения .NET (c #) в виде COM-объекта, а затем вызвать этот объект для выполнения задач, требующих повышения UAC. MSDN документирует это как объектную модель admin COM .

Мне известно, что можно и довольно легко запустить приложение (или другое приложение) от имени администратора, выполнить задачи в отдельном процессе (см., Например, сообщение от Daniel Moth , но я ищу способ сделать все из одного и того же невыполненного исполняемого файла .NET, что, конечно, вызовет COM-объект в новом процессе, но благодаря прозрачному маршаллингу, вызывающему COM-объект .NET не должен (слишком много) осознавать это.

Любые идеи относительно того, как я мог бы создать 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 ]

8 голосов
/ 23 ноября 2008

Посмотрите на Пример кода демонстрации 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);
}
3 голосов
/ 27 мая 2009

Я думаю, что единственный способ работы CoCreateInstanceAsAdmin - это если вы заранее зарегистрировали компонент COM. Это может быть проблемой, если вы хотите, чтобы ваше приложение работало в настройках развертывания XCopy.

Для своих собственных целей в Галлио я решил создать небольшой процесс хостинга на стороне с манифестом, требующим прав администратора. Затем, когда мне нужно выполнить повышенное действие, я запускаю экземпляр процесса хостинга и инструктирую его через .Net remoting для выполнения определенной команды, зарегистрированной в контейнере Gallio Inversion of Control.

Это довольно трудоемкая работа, но у Галлио уже был хостинг вне процесса, поэтому добавить повышение в микс было не слишком сложно. Более того, этот механизм гарантирует, что Gallio может выполнять повышение привилегий, не требуя предварительной установки каких-либо других компонентов COM в реестре.

2 голосов
/ 24 сентября 2008

Элементы возвышения являются процессами. Итак, если я правильно понимаю ваш вопрос и вам нужен способ поднять COM-объект в вашем процессе, тогда ответ - вы не можете. Весь смысл CoCreateInstanceAsAdmin - НЕ запускать его в вашем процессе.

...