-
как сделать выполнение команды под админом если прога запущена юзером ? т.е. все надеюсь видели кнопки со щитом, вот я про это и соответствено повышение прав дается только под выполнение команды или навсегда для всей проги ?
-
> или навсегда для всей проги ?
конкретно для какого-то действия нельзя. админские права запрашиваются для всей программы.
-
> Eraser © (25.01.10 17:09) [1]
А на время поднять свои права можно?
-
> [2] Дмитрий С © (26.01.10 15:54)
нельзя вроде как.
-
Поднять нельзя. А запрашивать права при старте очень даже просто. Пипшешь вот такой RC файл: #define RT_MANIFEST 24 #define CREATEPROCESS_MANIFEST_RESOURCE_ID 1 CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST ".\manifest.txt"Подключаешь этот RC к своей программе (стандартный манифест только отключи) В файл manifest.txt вбиваеш след текст: <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
type="win32"
name="DelphiApplication"
version="1.0.0.0"
processorArchitecture="*"/>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
publicKeyToken="6595b64144ccf1df"
language="*"
processorArchitecture="*"/>
</dependentAssembly>
</dependency>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="requireAdministrator"
uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly> Получаешь программу со "щитом", которая при старте будет требовать права админа. Из минусов - если дельфя запущена без админских прав, дебащить проект с таким манифестом с включенным UAC не получится.
-
Вот тебе кстати до кучи код, который показывает имеем ли мы админские права или нет с учетом UAC type
TPrivilegeCheckState = (csError, csLimitedUser, csAdmin);
function IsAdmin: TPrivilegeCheckState;
const
SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority =
(Value: (0, 0, 0, 0, 0, 5));
SECURITY_BUILTIN_DOMAIN_RID = $00000020;
DOMAIN_ALIAS_RID_ADMINS = $00000220;
SECURITY_MANDATORY_HIGH_RID = $00003000;
TokenIntegrityLevel = 25;
var
hAccessToken: THandle;
ptgGroups: PTokenGroups;
dwInfoBufferSize: DWORD;
psidAdministrators: PSID;
I: Integer;
SubAuthority: DWORD;
begin
Result := csError;
if Win32Platform <> VER_PLATFORM_WIN32_NT then Exit;
if not OpenThreadToken(GetCurrentThread,
TOKEN_QUERY, True, hAccessToken) then
if not OpenProcessToken(GetCurrentProcess,
TOKEN_QUERY, hAccessToken) then Exit;
try
GetMem(ptgGroups, 1024);
try
if Win32MajorVersion < 6 then
begin
if not GetTokenInformation(hAccessToken, TokenGroups,
ptgGroups, 1024, dwInfoBufferSize) then Exit;
AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2,
SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0, psidAdministrators);
try
Result := csLimitedUser;
for I := 0 to ptgGroups.GroupCount - 1 do
if EqualSid(psidAdministrators, ptgGroups.Groups[I].Sid) then
begin
Result := csAdmin;
Break;
end;
finally
FreeSid(psidAdministrators);
end;
end
else
begin
if GetTokenInformation(hAccessToken, TTokenInformationClass(TokenIntegrityLevel),
ptgGroups, 1024, dwInfoBufferSize) and
IsValidSid(PSIDAndAttributes(ptgGroups)^.Sid) then
begin
Result := csLimitedUser;
SubAuthority :=
GetSidSubAuthorityCount(PSIDAndAttributes(ptgGroups)^.Sid)^ - 1;
if GetSidSubAuthority(PSIDAndAttributes(ptgGroups)^.Sid,
SubAuthority)^ >= SECURITY_MANDATORY_HIGH_RID then
Result := csAdmin;
end;
end;
finally
FreeMem(ptgGroups);
end;
finally
CloseHandle(hAccessToken);
end;
end;
-
в дополнение к [4] Rouse_ © (26.01.10 18:04) скажу что, нужно удалить из проекта и других юнитов все упоминания о модуле XPMan (компонент TXPManifest), а то он подсовывает свой манифест, который мешает новому.
-
> [5] Rouse_ © (26.01.10 18:09)
у этого способа (точнее не конретно этого, а такого подхода с перечислением вручную) есть недостаток. у некоторых клиентов при сложной организации прав в домене он отрабатывал не правильно, причем даже на XP. Ховард рекомендует такие проверки делать с пом. CheckTokenMembership. Кстати не совсем понял зачем нужен особый способ определения админских прав для UAC? Работает и стандартный вроде. до кучи пример с 5 способами проверки админских прав (4 самый корректный) http://slil.ru/28550987 function IsAdmin3: Boolean;
const
SE_GROUP_ENABLED = $00000004;
SE_GROUP_USE_FOR_DENY_ONLY = $00000010;
var
psidAdministrators: PSID;
bIsMember: LongBool;
begin
Result := False;
if Win32Platform <> VER_PLATFORM_WIN32_NT then
begin
Result := True;
Exit;
end;
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;
-
> до кучи
Shell32.IsUserAnAdmin
-
> Кстати не совсем понял зачем нужен особый способ определения > админских прав для UAC? Работает и стандартный вроде.
У меня не отрабатывал, пришлось допиливать. Точнее как, под Windows 7 возвращал что я с админскими правами, хотя на самом деле приложение было запущено как обычный пользователь. Опять-же делалось все в состоянии "сдать проект нужно еще вчера", поэтому...
> Игорь Шевченко © (26.01.10 18:47) [8] > > до кучи > Shell32.IsUserAnAdmin
Танк секретный, наука может и не знать? :) Shell32 моя 2007-ая студия не опознает :)
-
Rouse_ © (26.01.10 20:39) [9]
Я не знаю, как оно отрабатывает при обычном пользователе, но с поднятыми правами. Наверняка что-то на эту тему есть в Shell32 или в ShlwApi изданием для Vista или Windows 7
-
Ну это ты наверно про 2009-ую студию говоришь, ибо в 2007-ой нет модуля Shell32, а в модуле ShlwApi нет IsUserAnAdmin
-
Rouse_ © (26.01.10 20:56) [11]
Я говорю про функции в Shell32.dll или в Shlwapi.dll, без разницы, каким средством разработки пользоваться.
-
> Игорь Шевченко © (26.01.10 21:02) [12] > Rouse_ © (26.01.10 20:56) [11] > > Я говорю про функции в Shell32.dll или в Shlwapi.dll
Мдя... совсем мозги зашорились... :) Ясно :)
-
в примере по ссылке есть function IsAdmin4: Boolean;
var
hShell32: HMODULE;
_IsUserAnAdmin: function(): BOOL; stdcall;
begin
Result := False;
hShell32 := LoadLibrary('shell32.dll');
_IsUserAnAdmin := GetProcAddress(hShell32, 'IsUserAnAdmin'); if Assigned(_IsUserAnAdmin) then
Result := _IsUserAnAdmin()
else
ShowMessage('Does not supported!');
end;
только она тоже не правильно в домене работает иногда.
-
Ну мой вариант гарантированно работает всегда, проверял и под вистой и под 2008 сервером и под семеркой (как 32 так и 64 бита)
-
-
я не про запуск самой проги от админа и манифесты а про команды выполняемые под админом,т.е. запись в реестр удал. файлов, когда системой задается вопрос разрешить или нет,а не возвращается типа нет доступа или проглатывается виртуализацией при этом изначально прога не под админом,и встречается это частенько
-
под UAC все сразу виртуализируется без дополнительных вопросов.
|