Форум: "Прочее";
Текущий архив: 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.005 c