Решил поделиться идеей, и обсудить некоторые нюансы.
Смысл ее в том, чтобы запускать программы от имени "Администратора", так как я постоянно тусуюсь в интернете, то нахожусь всегда под учетной записью пользователя (дабы вирусы всякие не доставали), наступают моменты, когда нужно запускать проги от Админа, "AdminLancher" и пригождается.
Вы скажете, а чем плох "RunAs"? да тем, что эту пароль нужно вписывать всегда каждый раз - это такой облом, если учесть, что пароль бессмыслица и по сто раз на дню приходится запускать. Не судите строго, но лень двигатель прогресса.
Сама идея:
1. Есть сам AdminLancher.exe - это консольное приложение но запускается через контекстное меню windows при открытии файла
а)получает путь к программе
б)читает свои параметры из реестра и сохраненный зашифрованный профиль Администратора (имя, пароль)
в)запускает программу от имени Администратора.
2. Есть конфигуратор, который
a)шифрует и сохраняет имя Администратора и пароль в раздел пользователя HKEY_CURRENT_USER\Software\...
(т.е. другой пользователь вошедший в систему уже не сможет запускать...)
б)Настраивает контекстное меню windows, чтобы программы можно было запускать через пункт "Run as Admin" подобный "запустить от имени", но при это пароль писаться не будет.
Есть проблема:
3. Касательно самого конфигуратора, если у учетной записи нет прав Админа, то конфигуратор не сможет занести настройки в реестр в ключ exefile/shell/RunAsAdmin/command т.е. необходима поднятие своих прав до уровня Администратора - а это я еще не научился, если подскажете то научусь,
а так как бы все работает...
Вот ссылка на действующую программу, для тестирования:
- запускающий : AdminLancher.exe
- конфигуратор: LanchConfig.exe
Если будут возникать ошибки или не будет работать, то сообщения из программы сбрасываются в специальную утилиту,
ее можно скачать здесь:
http://www.elsetrue.narod.ru/Softfolder/msgloger.7z Код программы AdminLancher.exe:
program AdminLancher;
uses
Windows, SysUtils, Registry, Users, Scrb, MsgLog;
Type
PUser = ^TUser;
TUser = Record
UserName : String[20];
Domain : String[MAX_COMPUTERNAME_LENGTH];
UserPass : String[14];
UserStatus : String[255];
end;
Var
Reg : TRegistry;
Buff : String;
BuffSize : Integer;
User : PUser;
StartupInfo : TStartupInfo;
ProcessInfo : TProcessInformation;
AppName : String;
Const
ConfigPath = '\Software\elsetrue\AdminLancher';
Profile = 'Profile';
begin
if ParamCount = 0 then begin
SendDebugMsg('Exit: ParamCount = '+IntToStr(ParamCount));
exit;
end;
for BuffSize:=1 to ParamCount do
AppName:=AppName+ParamStr(BuffSize)+' ';
SendDebugMsg('ParamCount = '+IntToStr(ParamCount));
AppName := Trim(AppName);
SendDebugMsg('AppName = '+AppName);
try
Reg:=TRegistry.Create;
Reg.RootKey:=HKEY_CURRENT_USER;
if Not Reg.OpenKeyReadOnly(ConfigPath) Then begin
SendDebugMsg('error: no open key = '+ConfigPath);
Exit;
end;
if Not REg.ValueExists(Profile) Then begin
SendDebugMsg('error: no value exists = '+Profile);
Exit;
end;
BuffSize:=Reg.GetDataSize(Profile);
if BuffSize = 0 then begin
SendDebugMsg('error: GetDataSize = 0');
Exit;
end;
SetLength(Buff,BuffSize);
FillChar(Buff[1], BuffSize, #0);
if Reg.ReadBinaryData(Profile,Buff[1],BuffSize) = 0 then begin
SendDebugMsg('Exet. error: ReadBinaryData readSize = 0');
Exit;
end;
finally
Reg.Free;
end;
Buff:=DeCode(Buff);
try
try
New(User);
BuffSize := Sizeof(TUser);
FillChar(User^, BuffSize, #0);
Move(Buff[1], User^, BuffSize);
SendDebugMsg('User Name = ' + User.UserName);
SendDebugMsg('User Domain = ' + User.Domain);
SetLength(Buff,Length(User.UserPass));
FillChar(buff[1],Length(User.UserPass), Ord('*'));
SendDebugMsg('User Password = ' + Buff);
SendDebugMsg('User Status = ' + User.UserStatus);
if Not CreateProcessWithLogonW(
PWideChar(StringToWideString(User^.UserName,CP_ACP)),
PWideChar(StringToWideString(User^.Domain,CP_ACP)),
PWideChar(StringToWideString(User^.UserPass,CP_ACP)), 0, Nil,
PWideChar(StringToWideString(AppName,CP_ACP)), 0, Nil, Nil,
StartupInfo,
ProcessInfo) then
begin
SendDebugMsg('CreateProcessWithLogonW = false, GetLastError: '+IntToStr(GetLastError));
Exit;
end;
finally
Dispose(User);
end;
Except
SendDebugMsg('Critical error: bed copy buffer');
end;
end.