UAC – это Контроль Учетных Записей (Wikipedia), используется для повышения привилегий в том случае если вашему приложению это необходимо. Появился в Windows Vista и присутствует Windows 7, 8, 10. Необходимо убедится в том, что UAC включен. В Windows 7 это можно проверить, открыв «Панель управления» - «Учетные записи пользователей» - «Изменение параметров контроля учетных записей» - убедится, что установлен уровень «По умолчанию» (Смотрите рисунок 1).
Основным, важным моментом в файле манифеста является строчка кода:
Параметр level со значением requireAdministrator указывает на то, что нашему приложению для работы требуются права администратора. Следующими строчками кода мы указываем с какими операционными системами наше приложение будет совместимо:
Далее нам необходимо в каталоге проекта создать файл ресурсов компиляции с именем Win7UAC.rc. Содержимое файла компиляции будет следующее:
1 24 "Win7UAC.manifest"
То есть мы в качестве ресурсов нашего приложения указываем наш файл манифеста.
Файл ресурсов компиляции Win7UAC.rc необходимо скомпилировать при помощи компилятора ресурсов brcc32.exe, этот компилятор ресурсов расположен в каталоге, где расположены бинарные файлы Delphi, у меня это каталог D:\Programs\Delphi7\Files\Delphi7\Bin. Убедитесь, что данный каталог добавлен в переменную окружения Path. Запустите командную строку Windows, перейдите в каталог проекта и выполните команду компиляции ресурсов (Смотрите рисунок 2).
В качестве результата в каталоге проекта вы получите файл ресурсов Win7UAC.RES, который необходимо в файле проекта p12.dpr подключить. Смотрите код ниже:
Вынесите на форму с именем Form1 одну кнопку Button1 и один список ComboBox1 (Смотрите рисунок 3).
Добавьте в свойства Items списка ComboBox1 две строки DOMAIN\User1 и DOMAIN\User2 (Смотрите рисунок 4). Эти строки у нас будут выбираться в ComboBox1. Также поменяйте свойства Style для списка ComboBox1 на csOwnerDraw.
В данном обработчике мы присваиваем списку ComboBox1 значение по умолчанию значение DOMAIN\User1.
Рассмотрим обработчик нажатия кнопки Button1, это следующий код:
В данном обработчике мы указываем путь в реестре Windows куда будем писать значения, это переменная типа String c именем SubKey. Смотрите код:
SubKey : String = 'SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI';
Далее берем выбранное значение ComboBox1 и присваиваем его переменной strSetRegValue. Смотрите код:
strSetRegValue := ComboBox1.Text;
Если переменная strSetRegValue не пуста, то начинаем писать в реестр Windows. Работать будем в корневом разделе HKEY_LOCAL_MACHINE. Смотрите код:
if (strSetRegValue <> '') then
begin
R := TRegistry.Create(KEY_READ);
R.RootKey := HKEY_LOCAL_MACHINE;
Далее проверяем существует ли путь в реестре SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI. Также открываем подраздел реестра на запись для Windows 7 32 bit и 64 bit, следующая строчка:
Access := KEY_WRITE OR $0100;
Смотрите следующий код:
if (R.KeyExists(SubKey)) then
begin
With R do
begin
Access := KEY_WRITE OR $0100;
openResult := OpenKey(SubKey, False);
if (not openResult = True) Then
begin
MessageDlg('Unable to create key! Exiting.', mtError, mbOKCancel, 0);
end;
Далее пишем в реестр параметры LastLoggedOnSAMUser, LastLoggedOnUser и закрываем ветку реестра и освобождаем память. Следующие строчки:
WriteString('LastLoggedOnSAMUser', strSetRegValue);
WriteString('LastLoggedOnUser', strSetRegValue);
CloseKey();
Free;
Ниже показан снимок рабочей программы (Смотрите рисунок 5) и код полностью. При запуске приложения, оно спросит повышения привилегий, если вы имеете права админа (Смотрите рисунок 6) или повышения привилегий путем ввода логина и пароля администратора (Смотрите рисунок 7).
Рисунок 1. Включение UAC в Windows 7
Создадим тестовое приложение, которое будет писать в реестр Windows выбираемые из списка значения, правда путь куда мы будем записывать значения требуют повышения привилегий. Откроем Delphi 7 и создадим новый проект. Присвоим ему имя p12.dpr. Сохраним основной модуль под именем p12_unit.pas. Чтобы научить наше приложение работать с UAC, необходимо создать в папке проекта файл манифеста, назовём его Win7UAC.manifest. Содержимое файла следующее:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assemblyIdentity type="win32" name="App" version="3.1.0.0" processorArchitecture="*"/> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" publicKeyToken="6595b64144ccf1df" language="*" processorArchitecture="*"/> </dependentAssembly> </dependency> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> <security> <requestedPrivileges> <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/> </requestedPrivileges> </security> </trustInfo> <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> <application> <!--The ID below indicates application support for Windows Vista --> <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> <!--The ID below indicates application support for Windows 7 --> <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> <!--The ID below indicates application support for Windows 8 --> <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> <!--The ID below indicates application support for Windows 8.1 --> <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> <!--The ID below indicates application support for Windows 10 --> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> </application> </compatibility></assembly>
Основным, важным моментом в файле манифеста является строчка кода:
<requestedPrivileges> <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/> </requestedPrivileges>
Параметр level со значением requireAdministrator указывает на то, что нашему приложению для работы требуются права администратора. Следующими строчками кода мы указываем с какими операционными системами наше приложение будет совместимо:
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> <application> <!--The ID below indicates application support for Windows Vista --> <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> <!--The ID below indicates application support for Windows 7 --> <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> <!--The ID below indicates application support for Windows 8 --> <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> <!--The ID below indicates application support for Windows 8.1 --> <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> <!--The ID below indicates application support for Windows 10 --> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> </application> </compatibility>
Далее нам необходимо в каталоге проекта создать файл ресурсов компиляции с именем Win7UAC.rc. Содержимое файла компиляции будет следующее:
1 24 "Win7UAC.manifest"
То есть мы в качестве ресурсов нашего приложения указываем наш файл манифеста.
Файл ресурсов компиляции Win7UAC.rc необходимо скомпилировать при помощи компилятора ресурсов brcc32.exe, этот компилятор ресурсов расположен в каталоге, где расположены бинарные файлы Delphi, у меня это каталог D:\Programs\Delphi7\Files\Delphi7\Bin. Убедитесь, что данный каталог добавлен в переменную окружения Path. Запустите командную строку Windows, перейдите в каталог проекта и выполните команду компиляции ресурсов (Смотрите рисунок 2).
Рисунок 2. Запуск компилятора ресурсов
brcc32.exe Win7UAC.rc
В качестве результата в каталоге проекта вы получите файл ресурсов Win7UAC.RES, который необходимо в файле проекта p12.dpr подключить. Смотрите код ниже:
program p12; uses Forms, p12_unit1 in 'p12_unit1.pas' {Form1}; {$R 'Win7UAC.RES'} begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end.
Вынесите на форму с именем Form1 одну кнопку Button1 и один список ComboBox1 (Смотрите рисунок 3).
Рисунок 3. Создания формы приложения
Добавьте в свойства Items списка ComboBox1 две строки DOMAIN\User1 и DOMAIN\User2 (Смотрите рисунок 4). Эти строки у нас будут выбираться в ComboBox1. Также поменяйте свойства Style для списка ComboBox1 на csOwnerDraw.
Рисунок 4. Формирование списка ComboBox
Переходим к написанию кода. Рассмотрим обработчик показа формы Form1, это следующий код:
procedure TForm1.FormShow(Sender: TObject); begin Combobox1.ItemIndex := Combobox1.Items.IndexOf('DOMAIN\User1'); end;
В данном обработчике мы присваиваем списку ComboBox1 значение по умолчанию значение DOMAIN\User1.
Рассмотрим обработчик нажатия кнопки Button1, это следующий код:
procedure TForm1.Button1Click(Sender: TObject); var R: TRegistry; openResult: Boolean; const SubKey : String = 'SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI'; begin strSetRegValue := ComboBox1.Text; if (strSetRegValue <> '') then begin R := TRegistry.Create(KEY_READ); R.RootKey := HKEY_LOCAL_MACHINE; if (R.KeyExists(SubKey)) then begin With R do begin Access := KEY_WRITE OR $0100; openResult := OpenKey(SubKey, False); if (not openResult = True) Then begin MessageDlg('Unable to create key! Exiting.', mtError, mbOKCancel, 0); end; WriteString('LastLoggedOnSAMUser', strSetRegValue); WriteString('LastLoggedOnUser', strSetRegValue); CloseKey(); Free; end; end; ShowMessage('Done! Recorded in the registry.'); strSetRegValue := ''; end; end;
В данном обработчике мы указываем путь в реестре Windows куда будем писать значения, это переменная типа String c именем SubKey. Смотрите код:
SubKey : String = 'SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI';
Далее берем выбранное значение ComboBox1 и присваиваем его переменной strSetRegValue. Смотрите код:
strSetRegValue := ComboBox1.Text;
Если переменная strSetRegValue не пуста, то начинаем писать в реестр Windows. Работать будем в корневом разделе HKEY_LOCAL_MACHINE. Смотрите код:
if (strSetRegValue <> '') then
begin
R := TRegistry.Create(KEY_READ);
R.RootKey := HKEY_LOCAL_MACHINE;
Далее проверяем существует ли путь в реестре SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI. Также открываем подраздел реестра на запись для Windows 7 32 bit и 64 bit, следующая строчка:
Access := KEY_WRITE OR $0100;
Смотрите следующий код:
if (R.KeyExists(SubKey)) then
begin
With R do
begin
Access := KEY_WRITE OR $0100;
openResult := OpenKey(SubKey, False);
if (not openResult = True) Then
begin
MessageDlg('Unable to create key! Exiting.', mtError, mbOKCancel, 0);
end;
Далее пишем в реестр параметры LastLoggedOnSAMUser, LastLoggedOnUser и закрываем ветку реестра и освобождаем память. Следующие строчки:
WriteString('LastLoggedOnSAMUser', strSetRegValue);
WriteString('LastLoggedOnUser', strSetRegValue);
CloseKey();
Free;
Ниже показан снимок рабочей программы (Смотрите рисунок 5) и код полностью. При запуске приложения, оно спросит повышения привилегий, если вы имеете права админа (Смотрите рисунок 6) или повышения привилегий путем ввода логина и пароля администратора (Смотрите рисунок 7).
Рисунок 5. Запущенная программа
Рисунок 6. Окно разрешения запуска вашей программы, если вы имеете права администратора
Рисунок 7. Запрос прав администратора, если они у вас отсутствуют
unit p12_unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Registry; type TForm1 = class(TForm) Button1: TButton; ComboBox1: TComboBox; procedure Button1Click(Sender: TObject); procedure FormShow(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} var strSetRegValue: String; procedure TForm1.Button1Click(Sender: TObject); var R: TRegistry; openResult: Boolean; const SubKey : String = 'SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI'; begin strSetRegValue := ComboBox1.Text; if (strSetRegValue <> '') then begin R := TRegistry.Create(KEY_READ); R.RootKey := HKEY_LOCAL_MACHINE; if (R.KeyExists(SubKey)) then begin With R do begin Access := KEY_WRITE OR $0100; openResult := OpenKey(SubKey, False); if (not openResult = True) Then begin MessageDlg('Unable to create key! Exiting.', mtError, mbOKCancel, 0); end; WriteString('LastLoggedOnSAMUser', strSetRegValue); WriteString('LastLoggedOnUser', strSetRegValue); CloseKey(); Free; end; end; ShowMessage('Done! Recorded in the registry.'); strSetRegValue := ''; end; end; procedure TForm1.FormShow(Sender: TObject); begin Combobox1.ItemIndex := Combobox1.Items.IndexOf('DOMAIN\User1'); end; end.
Комментариев нет:
Отправить комментарий