Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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/



Страницы: 1 вся ветка

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

Наверх





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


2-1294899349
12
2011-01-13 09:15
2011.04.10
Control.Enable := False Но, чтоб визуально не изменился.


6-1236185481
It's not me
2009-03-04 19:51
2011.04.10
Зависание над чтением сокета


2-1294822487
Sam86
2011-01-12 11:54
2011.04.10
Получение информации о функции по ее адресу


1-1251978398
gosha52
2009-09-03 15:46
2011.04.10
Delphi 2009-2010, утекает память в записях





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский