-
Всем доброго времени суток! Никогда не работал с UAC, но тут понадобилось. Основная программа создает пайп и ивент и запускает дочерний процесс которому передается разрешение на наследование хэндлов и в переменных окружения передаются сами хэндлы на объекты. Основной процесс ждет установки ивента. Когда дочерний процесс готов работать он дергает ивент и приложения общаются через пайп. Сейчас это все пока под ХР-2000, проблем нет, но нужно чтобы на висте и семерке иногда выводился запрос на повышение привилегий. Т.е. одни действия выполняются из-под ограниченной по дефолту учетки, а на другие надо просить разрешения админских прав. Вопрос: можно ли переиначить такую систему с использованием CreateProcess чтобы по требованию просить привилегий? Или же нужно делать исключительно через ShellExecuteEx-RunAs и передавать имена объектов (пайпа и ивента) в параметрах? Вобщем, наставьте на путь истинный, я в этом пока дуб дубом )
-
CreateProcess при вызове любого приложения, которое требует elevation тупо обламывает с кодом вроде 740 (это на вскидку, точно не помню). Никаких запросов к юзеру не выдается, просто облом и всё. Запрос умеет выдавать ShellExecute*, а через CreateProcess - никак (поубивав бы тех в MS, кто это придумал). Это, кстати, одна из причин, почему хуча программ перестало работать в Windows 6+ при включеном UAC. Например, Java не умеет создавать процессы иначе чем через CreateProcess, да и большинство других средств разработки тоже. Пути борьбы... Почитай сначала побольше про UAC, чтобы понимать, что там происходит. Рекомендую посмотреть на занятный пример: http://www.codeproject.com/KB/vista-security/UAC__The_Definitive_Guide.aspx?display=Print
-
Большое спасибо за ссылочку, весьма занятно и интересно. Обязательно поковыряю, что там за magic реализован ) Про UAC читал, в общих чертах вроде понимаю и представляю что он и для чего и как. Но вот шаг в сторону от шаблонных примеров с манифестом или runas уперся в стену отсутствия инфы и толковых инструментов реализации.
Вторая задачка возникла - самостоятельно вызвать показ окошка "Установка программы от имени другого пользователя" под ХР (желательно и 2000) при запуске из-под ограниченной учетки как это делает система при запуске setup.exe (runas показывает диалог "Запуск программы от имени другого ползователя", он другой).
-
> SPeller
uses
shellapi;
function RunAsAdmin(hWnd: HWND; filename: string; Parameters: string): Boolean;
var
sei: TShellExecuteInfo;
begin
ZeroMemory(@sei, SizeOf(sei));
sei.cbSize := SizeOf(TShellExecuteInfo);
sei.Wnd := hwnd;
sei.fMask := SEE_MASK_FLAG_DDEWAIT or SEE_MASK_FLAG_NO_UI;
sei.lpVerb := PChar('runas');
sei.lpFile := PChar(Filename); if parameters <> '' then
sei.lpParameters := PChar(parameters); sei.nShow := SW_SHOWNORMAL; Result := ShellExecuteEx(@sei);
end;
Вариант с ожиданием заверщения приложения + таймаут работы.
function VistaExecElevated(FileName, CLParams, Dir : String; var ExitCode: DWORD; const Wait: DWORD = 0): LongWord;
var
shExecInfo : TShellExecuteInfo;
iWaitRes: DWORD;
begin
Result := 0;
if FileName <> '' then
begin
FillChar(shExecInfo, SizeOf(shExecInfo), 0);
shExecInfo.cbSize := SizeOf(shExecInfo);
shExecInfo.fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_FLAG_NO_UI;
shExecInfo.lpVerb := PChar('runas');
shExecInfo.lpFile := PChar(FileName);
if CLParams <> '' then
shExecInfo.lpParameters := PChar(CLParams);
if Dir <> '' then
shExecInfo.lpDirectory := pchar(Dir);
shExecInfo.nShow := SW_SHOW;
ShellExecuteEx(@shExecInfo);
Result := shExecInfo.hInstApp;
if Result > 32 then
begin
if (Wait > 0) then
begin
iWaitRes := WaitForSingleObject(shExecInfo.hProcess, Wait);
if (iWaitRes = WAIT_TIMEOUT) then
begin
TerminateProcess(shExecInfo.hProcess, 0);
end;
GetExitCodeProcess(shExecInfo.hProcess, ExitCode);
end;
CloseHandle(shExecInfo.hProcess);
end;
end;
end;
-
Удалено модератором Примечание: не в пивной
|