Форум: "Прочее";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2011.04.10;
Скачать: [xml.tar.bz2];




Вниз

Консольное приложение и UAC 


DVM ©   (2010-12-23 22:30) [0]

Понадобилось тут мне сделать консольное приложение, которое бы выдавало диалог с запросом на повышение прав при запуске. Добавил я манифест - результат ноль. Тот же самый манифест в оконном приложении дает нужный эффект, но с консольными это не проходит. Кто нибудь сталкивался с подобным?



Eraser ©   (2010-12-23 22:31) [1]

> [0] DVM ©   (23.12.10 22:30)

манифест точно один привязан?



DVM ©   (2010-12-23 22:33) [2]


> Eraser ©

один



Eraser ©   (2010-12-23 22:40) [3]

видимо вот http://msdn.microsoft.com/en-us/library/bb756922.aspx
Requirements for Console Applications

A console application presents its output on the console window and not with a separate user interface. If an application needs a full administrator access token to run, then that application needs to be launched from an elevated console window.

You must do the following for console applications:

Mark that your application "asInvoker": You can do this by authoring the manifest of your application in which you set RequestedExecutionLevel == asInvoker. This setup allows callers from non-elevated contexts to create your process, which allows them to proceed to step 2.

Provide an error message if application is run without a full administrator access token: If the application is launched in a non-elevated console, your application should give a brief message and exit. The recommended message is:

"Access Denied. Administrator permissions are needed to use the selected options. Use an administrator command prompt to complete these tasks."

The application should also return the error code ERROR_ELEVATION_REQUIRED upon failure to launch to facilitate scripting.



DVM ©   (2010-12-23 22:58) [4]

Да, похоже просто так диалог на повышение не вызвать. Непонятно за каким лешим нужен asInvoker когда что с ним что без него все одинаково работает.



DVM ©   (2010-12-23 23:04) [5]

Вот кстати пример нашелся http://cc.embarcadero.com/item/24512
Диалога конечно он не выдает.



Anatoly Podgoretsky ©   (2010-12-23 23:08) [6]

> DVM  (23.12.2010 22:58:04)  [4]

С консольными приложениями так и нужно поступать, запускать интерпритатор
командной строки от администратора и уже в нем запускать приложение. Это не
доработано, но это известстно и надо следовать этому. По сути тут происходит
два процесса, первое запуск консоли, повышение прав не требуется, а потом
запуск из нее приложение и повышать уже поздно.



Inovet ©   (2010-12-24 07:27) [7]

> [6] Anatoly Podgoretsky ©   (23.12.10 23:08)
> запускать интерпритатор
> командной строки от администратора и уже в нем запускать
> приложение.

FAR как-то без этого повышает, когда надо, потом понижает, UAC естественно тоже вопрос задаёт при первом повышении.



Inovet ©   (2010-12-24 07:40) [8]

> [7] Inovet ©   (24.12.10 07:27)
> FAR

У меня FAR свежий юникодная версия х86
Far Manager v2.0 build 1666 x86
Фича недавно появилась, х64 и не юникод не пробовал, но должна и в них быть.
http://www.farmanager.com/download.php?p=32&l=ru



Владислав ©   (2010-12-24 09:19) [9]


> С консольными приложениями так и нужно поступать, запускать
> интерпритатор
> командной строки от администратора и уже в нем запускать
> приложение.


А diskpart консольное приложение? Вроде да. :)

Он запрашивает повышение.



DVM ©   (2010-12-24 10:28) [10]


> А diskpart консольное приложение? Вроде да. :)
>
> Он запрашивает повышение.

Манифест в нем такой:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Copyright (c) Microsoft Corporation -->
<assembly xmlns="urn:schemas-microsoft-com:asm.v1"  xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" manifestVersion="1.0">
<assemblyIdentity
       version="5.1.0.0"
       processorArchitecture="x86"
       name="Microsoft.Windows.DiskPart"
       type="win32"
/>
<description>Command-line tool for disk and volume management</description>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
   <security>
       <requestedPrivileges>
           <requestedExecutionLevel
               level="requireAdministrator"
               uiAccess="false"
           />
       </requestedPrivileges>
   </security>
</trustInfo>


Вроде ничего необычного



DVM ©   (2010-12-25 12:15) [11]

Придумал вот такой вариант:

program Project2;

{$APPTYPE CONSOLE}

uses
 Windows,
 SysUtils,
 ShellApi;

function IsAdministrator: Boolean;
var
 psidAdmin: Pointer;
 Token: THandle;
 Count: DWORD;
 TokenInfo: PTokenGroups;
 HaveToken: Boolean;
 I: Integer;
const
 SECURITY_NT_AUTHORITY: TSidIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5));
 SE_GROUP_USE_FOR_DENY_ONLY = $00000010;
 SECURITY_BUILTIN_DOMAIN_RID  = $00000020;
 DOMAIN_ALIAS_RID_ADMINS = $00000220;
begin
 psidAdmin := nil;
 TokenInfo := nil;
 HaveToken := False;
 try
   Token := 0;
   HaveToken := OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True, Token);
   if (not HaveToken) and (GetLastError = ERROR_NO_TOKEN) then
     HaveToken := OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, Token);
   if HaveToken then
   begin
     Win32Check(AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2,
       SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
       psidAdmin));
     if GetTokenInformation(Token, TokenGroups, nil, 0, Count) or
      (GetLastError <> ERROR_INSUFFICIENT_BUFFER) then
        RaiseLastOSError;
     TokenInfo := PTokenGroups(AllocMem(Count));
     Win32Check(GetTokenInformation(Token, TokenGroups, TokenInfo, Count, Count));
     for I := 0 to TokenInfo^.GroupCount - 1 do
     begin
       {$RANGECHECKS OFF} // Groups is an array [0..0] of TSIDAndAttributes, ignore ERangeError
       Result := EqualSid(psidAdmin, TokenInfo^.Groups[I].Sid);
       if Result then
       begin
         //consider denied ACE with Administrator SID
         Result := TokenInfo^.Groups[I].Attributes and SE_GROUP_USE_FOR_DENY_ONLY
             <> SE_GROUP_USE_FOR_DENY_ONLY;
         Break;
       end;
       {$IFDEF RANGECHECKS_ON}
       {$RANGECHECKS ON}
       {$ENDIF RANGECHECKS_ON}
     end;
   end;
 finally
   if TokenInfo <> nil then
     FreeMem(TokenInfo);
   if HaveToken then
     CloseHandle(Token);
   if psidAdmin <> nil then
     FreeSid(psidAdmin);
 end;
end;

procedure Restart;
var
SEI: TShellExecuteInfo;
begin
ZeroMemory(@SEI, SizeOf(SEI));
SEI.cbSize := SizeOf(TShellExecuteInfo);
SEI.Wnd := 0;
SEI.fMask := SEE_MASK_FLAG_DDEWAIT or SEE_MASK_FLAG_NO_UI;
SEI.lpVerb := PChar("runas");
SEI.lpFile := PChar(ParamStr(0));
SEI.nShow := SW_SHOWNORMAL;
ShellExecuteEx(@SEI);
end;

begin
 if not IsAdministrator then
   begin
     Restart;
     Exit;
   end;
 Readln;
end.



Eraser ©   (2010-12-25 15:17) [12]

> [11] DVM ©   (25.12.10 12:15)

функция IsAdministrator с такой реализацией будет иногда криво работать, вот правильный вариант:

///  <summary>
///  Новая функция определения, является ли пользователь админом,
///  основанная на CheckTokenMembership.
///  </summary>
function IsAdminNew: Boolean;
const
 SE_GROUP_ENABLED = $00000004;
 SE_GROUP_USE_FOR_DENY_ONLY  = $00000010;
var
 psidAdministrators: PSID;
 bIsMember: LongBool;
begin
 if Win32Platform <> VER_PLATFORM_WIN32_NT then
 begin
   Result := True;
   Exit;
 end;

 Result := False;
 psidAdministrators := nil;
 try
   if AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2,
     SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
     0, 0, 0, 0, 0, 0, psidAdministrators) then
   begin
     if CheckTokenMembership(0, psidAdministrators, bIsMember) then
       Result := bIsMember;
   end;
 finally
   if psidAdministrators <> nil then
     FreeSid(psidAdministrators);
 end;
end;



DVM ©   (2010-12-25 15:42) [13]


> Eraser ©   (25.12.10 15:17) [12]

Спасибо, учту.



Alex Konshin ©   (2010-12-26 05:06) [14]

Пошукай вокруг http://www.softblog.com/2008-07/vista-elevator2/




Форум: "Прочее";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2011.04.10;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.76 MB
Время: 0.021 c
15-1293223383     Stenfit               2010-12-24 23:43  2011.04.10  
перевод


2-1294948457      Oleg_teacher          2011-01-13 22:54  2011.04.10  
Excel + Delphi совмесный доступ


2-1294996934      12                    2011-01-14 12:22  2011.04.10  
Error creating variant or safe array. Из-за чего?


2-1294923778      student22             2011-01-13 16:02  2011.04.10  
HTML


2-1294913584      Finder                2011-01-13 13:13  2011.04.10  
замена OleVariant