Запуск приложений и выключение компьютера.
В данном примере я продемонстрирую, как использовать методы, предоставляемые провайдерами.
… var Form1: TForm1; Service: ISWbemServices; InParam, OutParam, SObject, Process: ISWbemObject; Method: ISWbemMethod; SProp1, SProp2, MyProperty: ISWbemProperty; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var PropValue: OleVariant; begin Service:= SWbemLocator1.ConnectServer('.', 'root\cimv2', '', '', '', '', 0, nil); // Service.Security_.Set_ImpersonationLevel(wbemImpersonationLevelImpersonate); Process:= Service.Get('Win32_Process', 0, nil); // Method:= Process.Methods_.Item('Create', 0); // InParam:= Method.InParameters.SpawnInstance_(0); // MyProperty:= InParam.Properties_.Add('CommandLine', wbemCimtypeString, False, 0); { С помощью метода Set_Value объекта ISWbemProperty присваеваем свойству CommandLine значение Notepad.exe } PropValue:= 'Notepad.exe'; MyProperty.Set_Value(PropValue); // После того, как все входные свойства определены, запускаем приложение. // OutParam - объект, возвращаемый методом ExecMethod_ OutParam:= Process.ExecMethod_('Create', InParam, 0, nil); // Получения выходных параметров из возвращённого объекта OutParam типа SWbemObject SProp1:= outParam.Properties_.Item('ReturnValue', 0); // Проверяю, удалось ли запустить приложение. Если свойство ReturnValue не равно 0, // то произошла ошибка. if SProp1.Get_Value = 0 then begin SProp2:= outParam.Properties_.Item('ProcessID', 0); Button2.Enabled:= True; Button1.Enabled:= False; sleep(300); SetForegroundWindow(Form1.Handle); end else MessageBox(0, PChar('Не удалось запустить приложение.'), PChar(Form1.Caption), MB_OK); end; procedure TForm1.Button2Click(Sender: TObject); var PropValue: OleVariant; begin SObject:= Service.Get('Win32_Process.Handle="' + WideString(SProp2.Get_Value) + '"', 0, nil); Method:= SOBject.Methods_.Item('Terminate', 0); InParam:= Method.InParameters.SpawnInstance_(0); MyProperty:= InParam.Properties_.Add('Reason', wbemCimtypeUint32, False, 0); PropValue:= 0; MyProperty.Set_Value(PropValue); OutParam:= SObject.ExecMethod_('Terminate', InParam, 0, nil); SProp1:= outParam.Properties_.Item('ReturnValue', 0); if SProp1.Get_Value = 0 then begin Button1.Enabled:= True; Button2.Enabled:= False; end else MessageBox(0, PChar('Не удалось закрыть приложение.'), PChar(Form1.Caption), MB_OK); end; procedure TForm1.Button3Click(Sender: TObject); var ObjectSet: ISWbemObjectSet; Enum: IEnumVariant; TempObj: OleVariant; Value: Cardinal; begin // Выключение компьютера - использование Shutdown без свойств. if MessageBox(0, PChar('Если вы выберете ''Да'', ваш компьютер выключится!'), PChar(Form1.Caption), MB_YESNO or MB_ICONEXCLAMATION or MB_DEFBUTTON2) = mrYes then begin Service:= SWbemLocator1.ConnectServer('.', 'root\cimv2', '', '', '', '', 0, nil); Service.Security_.Privileges.Add(wbemPrivilegeShutdown, True); // // SObject:= Service.Get('Win32_OperatingSystem', wbemFlagUseAmendedQualifiers, nil); // ObjectSet:= SObject.Instances_(0, nil); ObjectSet:= Service.ExecQuery('SELECT * FROM Win32_OperatingSystem WHERE Primary=True', 'WQL', wbemFlagReturnImmediately, nil); Enum:= (ObjectSet._NewEnum) as IEnumVariant; while (Enum.Next(1, TempObj, Value) = S_OK) do begin SObject:= IUnknown(tempObj) as SWBemObject; SObject.ExecMethod_('Shutdown', nil, 0, nil); end; end; { if MessageBox } end; end. |
Пояснения к коду: Примечание 1 Security_ - данное свойство используется в том случае, когда вы собираетесь считать или установить настройки безопасности для объекта SWbemServices. Объект SWbemSecurity имеет следующие свойства: AuthenticationLevel, ImpersonationLevel, Privileges. Нас в данном случае будет интересовать только второе свойство. ImpersonationLevel - Числовое значение. Данное свойство определяет, может ли процесс, владельцем которого является WMI, пользоваться правами вашей учётной записи, что может быть необходимо при обращении к другим процессам. Я буду пользоваться значением '3' (wbemImpersonationLevelImpersonate), что означает, что я наделяю данный объект правами того, кто его вызвал. Об остальных уровнях наследования прав читайте в SDK.
Примечание 2 Свойство Methods_ объекта SWbemObject представляет собой объект типа SWbemMethodSet, который является не чем иным, как коллекцией методов данного класса (или экземпляра класса).
Данное свойство предназначено только для чтения (read-only).
Единственный метод Item объекта SWbemMethodSet возвращает объект типа SWbemMethod.
Метод Item принимает следующие параметры: objMethod = Item( strName, [ iFlags = 0 ] ) strName - необходимый параметр. Имя метода, указатель на который должен быть возвращён данным методом.
Примечание 3 Свойство InParameters объекта SWbemMethod определяет входные параметры для данного метода. Метод SpawnInstance_ объекта SWbemObject создаёт новый экземпляр класса.
Данный метод имеет следующие входные параметры: objNewInstance = SpawnInstance_( [ iFlags = 0 ] ) Единственный параметр iFlags зарезервирован и не обязателен к указанию.
Если указывается, то должен быть равен 0.
Примечание 4 Свойство Properties_ объекта SWbemObject представляет собой объект типа SWbemPropertySet, который является коллекцией свойств для данного класса или экземпляра.
Метод Add объекта SWbemPrivilegeSet добавляет объект типа SWbemProperty к объекту SWbemPrivilegeSet.
Данный метод имеет следующие входные параметры: objProperty = Add( strName, iCIMType, [ bIsArray = FALSE ], [ iFlags = 0 ] )
- strName - обязательный к указанию параметр. Имя нового свойства.
- iCIMType - обязательный к указанию параметр. Определяет тип (CIMType) свойства.
- bIsArray - необязательный к указанию параметр. Определяющий является ли данное свойство массивом. По умолчанию False.
- iFlags - необязательный к указанию параметр. Зарезервирован. Если указывается, то должен быть равен 0.
Примечание 5 Для получения коллекции экземпляров Win32_OperatingSystem я намеренно воспользовался методом ExecQuery объекта ISWbemServices, что бы продемонстрировать работу данной ф-ии.
Использование данного метода равносильно используемой мною ранее конструкции.
Кстати, синтаксис WQL вам ничего не напоминает? ;) Правильно - WQL прямой потомок ANSI SQL, и соответствует синтаксису SQL. В WQL введены незначительные семантические изменения необходимые для работы с WMI. Так что вам даже не придётся учить новый язык запросов, для того что бы использовать WMI - Microsoft оказалась гуманной и мудрой в этом отношении и в очередной раз не усложнила нашу жизнь :)
Для интересующихся правилами составления запросов: откруваем SDK, раздел "Querying with WQL", всё понятно и доступно.
Исходный код и exe-файл данного примера вы сможете найти в прилагаемом к статье архиве в каталогах \source\ UseMethods и \Exe-files соответственно.