![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
||||
|
||||
|
Доброго времени суток, уважаемы форумчане!
Что-то не могу найти на форумах похожих тем (наверное плохо ищу), поэтому буду рад любой помощи. Суть вот в чем. При запуске из командной строки (с правами администратора) какой-нибудь системной утилиты (например sfc /scannow или powercfg /energy) все работает отлично и замечательно. Но стоит запустить эти же утилиты из приложения - начинаются проблемы. Пробовал решить их и так, и сяк - ничего не получается. Под "и так, и сяк" я понимаю ShellExecute(), WinExec(); CreateProcess(). Всегда одно и то же. Привожу пример выполнения команды powercfg /energy: С помощью CreateProcess: Код:
if (Radiobutton1.Checked = True) then
FillChar(si,SizeOf(si),0);
si.cb := SizeOf(si);
si.dwFlags := STARTF_USESHOWWINDOW;
si.wShowWindow := SW_SHOWNORMAL;
if CreateProcess(nil, 'cmd.exe /K "powercfg /energy"', nil, nil, false, 0, nil, nil, si, pi) then begin
CloseHandle(pi.hProcess);
end else begin
MessageBox(0, PChar(IntToStr(GetLastError())), nil, 0);
end;С помощью ShellExecute: Код:
if (Radiobutton1.Checked = True) then
begin
Nrg_btn:='/K powercfg /energy';
ShellExecute(Handle, nil, 'cmd.exe', PChar(Nrg_btn), nil, SW_SHOW);
end;P.S. Ошибка при выполнении: Цитата:
|
|
#2
|
||||
|
||||
|
Очевидно же,в вопросе и сам ответ:
Цитата:
Код:
const
SE_CREATE_TOKEN_NAME = 'SeCreateTokenPrivilege';
SE_ASSIGNPRIMARYTOKEN_NAME = 'SeAssignPrimaryTokenPrivilege';
SE_LOCK_MEMORY_NAME = 'SeLockMemoryPrivilege';
SE_INCREASE_QUOTA_NAME = 'SeIncreaseQuotaPrivilege';
SE_UNSOLICITED_INPUT_NAME = 'SeUnsolicitedInputPrivilege';
SE_MACHINE_ACCOUNT_NAME = 'SeMachineAccountPrivilege';
SE_TCB_NAME = 'SeTcbPrivilege';
SE_SECURITY_NAME = 'SeSecurityPrivilege';
SE_TAKE_OWNERSHIP_NAME = 'SeTakeOwnershipPrivilege';
SE_LOAD_DRIVER_NAME = 'SeLoadDriverPrivilege';
SE_SYSTEM_PROFILE_NAME = 'SeSystemProfilePrivilege';
SE_SYSTEMTIME_NAME = 'SeSystemtimePrivilege';
SE_PROF_SINGLE_PROCESS_NAME = 'SeProfileSingleProcessPrivilege';
SE_INC_BASE_PRIORITY_NAME = 'SeIncreaseBasePriorityPrivilege';
SE_CREATE_PAGEFILE_NAME = 'SeCreatePagefilePrivilege';
SE_CREATE_PERMANENT_NAME = 'SeCreatePermanentPrivilege';
SE_BACKUP_NAME = 'SeBackupPrivilege';
SE_RESTORE_NAME = 'SeRestorePrivilege';
SE_SHUTDOWN_NAME = 'SeShutdownPrivilege';
SE_DEBUG_NAME = 'SeDebugPrivilege';
SE_AUDIT_NAME = 'SeAuditPrivilege';
SE_SYSTEM_ENVIRONMENT_NAME = 'SeSystemEnvironmentPrivilege';
SE_CHANGE_NOTIFY_NAME = 'SeChangeNotifyPrivilege';
SE_REMOTE_SHUTDOWN_NAME = 'SeRemoteShutdownPrivilege';
SE_UNDOCK_NAME = 'SeUndockPrivilege';
SE_SYNC_AGENT_NAME = 'SeSyncAgentPrivilege';
SE_ENABLE_DELEGATION_NAME = 'SeEnableDelegationPrivilege';
SE_MANAGE_VOLUME_NAME = 'SeManageVolumePrivilege';
// Enables or disables privileges debending on the bEnabled
function NTSetPrivilege(sPrivilege: string; bEnabled: Boolean): Boolean;
var
hToken: THandle;
TokenPriv: TOKEN_PRIVILEGES;
PrevTokenPriv: TOKEN_PRIVILEGES;
ReturnLength: Cardinal;
begin
Result := True;
// Only for Windows NT/2000/XP and later.
if not (Win32Platform = VER_PLATFORM_WIN32_NT) then Exit;
Result := False;
// obtain the processes token
if OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then
begin
try
// Get the locally unique identifier (LUID) .
if LookupPrivilegeValue(nil, PChar(sPrivilege),
TokenPriv.Privileges[0].Luid) then
begin
TokenPriv.PrivilegeCount := 1; // one privilege to set
case bEnabled of
True: TokenPriv.Privileges[0].Attributes:= SE_PRIVILEGE_ENABLED;
False:TokenPriv.Privileges[0].Attributes:= 0;
end;
ReturnLength := 0; // replaces a var parameter
PrevTokenPriv := TokenPriv;
// enable or disable the privilege
AdjustTokenPrivileges(hToken, False, TokenPriv, SizeOf(PrevTokenPriv),
PrevTokenPriv, ReturnLength);
end;
finally
CloseHandle(hToken);
end;
end;
// test the return value of AdjustTokenPrivileges.
Result := GetLastError = ERROR_SUCCESS;
if not Result then raise Exception.Create(SysErrorMessage(GetLastError));
end; |
| Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
ffpereverzev (18.02.2017)
| ||
|
#3
|
||||
|
||||
|
Решение, конечно, элегантное и не лишено смысла, но не помогло. Результат точно такой же.
Да, я написал, что от имени администратора все хорошо, но забыл упомянуть, что все хорошо, когда я ОТДЕЛЬНО запускаю командную строку от имени администратора. Если я запускаю свою программу от имени администратора, то, вроде как, командная строка запускается тоже от имени администратора (факт), но результат, почему-то другой. Цитата:
|
|
#4
|
||||
|
||||
|
Цитата:
Код:
type
PTOKEN_GROUPS = TOKEN_GROUPS^;
function RunningAsAdministrator(): Boolean;
var
SystemSidAuthority: SID_IDENTIFIER_AUTHORITY = SECURITY_NT_AUTHORITY;
psidAdmin: PSID;
ptg: PTOKEN_GROUPS = nil;
htkThread: Integer; { HANDLE }
cbTokenGroups: Longint; { DWORD }
iGroup: Longint; { DWORD }
bAdmin: Boolean;
begin
Result := false;
if not OpenThreadToken(GetCurrentThread(), // get security token
TOKEN_QUERY, FALSE, htkThread) then
if GetLastError() = ERROR_NO_TOKEN then
begin
if not OpenProcessToken(GetCurrentProcess(),
TOKEN_QUERY, htkThread) then
Exit;
end else Exit;
if GetTokenInformation(htkThread, // get #of groups
TokenGroups, nil, 0, cbTokenGroups) then Exit;
if GetLastError() <> ERROR_INSUFFICIENT_BUFFER then Exit;
ptg := PTOKEN_GROUPS(getmem(cbTokenGroups));
if not Assigned(ptg) then Exit;
if not GetTokenInformation(htkThread, // get groups
TokenGroups, ptg, cbTokenGroups, cbTokenGroups) then Exit;
if not AllocateAndInitializeSid(SystemSidAuthority,
2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0, psidAdmin) then Exit;
iGroup := 0;
while iGroup < ptg^.GroupCount do // check administrator group
begin
if EqualSid(ptg^.Groups[iGroup].Sid, psidAdmin) then
begin
Result := TRUE;
break;
end;
Inc(iGroup);
end;
FreeSid(psidAdmin);
end; |
|
#5
|
||||
|
||||
|
Чего-то я не очень понимаю, куда мне деть этот код. У меня не консольное приложение. А при объявлении новой категории
Код:
type PTOKEN_GROUPS = TOKEN_GROUPS^; Цитата:
|
|
#6
|
||||
|
||||
|
Кстати, по-поводу запуска приложения от имени администратора. Если я запускаю приложение обычным способом и затем выполняю операцию вызывающую командную строку, то вижу такую картину:
![]() А если запуск был от имени администратора, то тогда такую: ![]() Может это и не важно (или не говорит ни о чем). Я поэтому и обратился к знающим людям. ![]() |
|
#7
|
||||
|
||||
|
У меня этот код работает на W7Х32, под W10Х64 не пошел, всегда проблемы в 64х разрядных системах такого рода возникают,требуется более тонкая настройка среды, конкретно - это индивидуально для каждого случая - больше подсказать нечего, извнт
|
| Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
ffpereverzev (18.02.2017)
| ||
|
#8
|
||||
|
||||
|
У меня как раз W10. Ну что ж....будем думать, размышлять и обмозговывать...
![]() |
|
#9
|
||||
|
||||
|
Во, через вызов ShellExecuteEx удалось в десятке запустить нужную вам ситемную утилиту с правами одмина
Код:
procedure TForm1.Button1Click(Sender: TObject); var shInfo: PSHELLEXECUTEINFOA; s: string; begin s:= 'cmd.exe'; New(shInfo); shInfo^.cbSize:= sizeof(SHELLEXECUTEINFO); shInfo^.fMask:= 0; shInfo^.Wnd:= 0; shInfo^.lpVerb:= 'runas'; shInfo^.lpFile:= PAnsiChar(ExtractFileName(s)); shInfo^.lpParameters:= '/K powercfg /energy'; shInfo^.lpDirectory:= PAnsiChar(ExtractFilePath(s)); shInfo^.nShow:= SW_SHOWNORMAL; shInfo^.hInstApp:= 0; ShellExecuteEx(shInfo); Dispose(shInfo); shInfo:= nil; end; |
| Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
ffpereverzev (28.02.2017)
| ||
|
#10
|
||||
|
||||
|
Цитата:
|
| Этот пользователь сказал Спасибо Karsh за это полезное сообщение: | ||
ffpereverzev (28.02.2017)
| ||
|
#11
|
||||
|
||||
|
Цитата:
|
|
#12
|
||||
|
||||
|
Цитата:
Последний раз редактировалось Karsh, 19.02.2017 в 23:44. |
| Этот пользователь сказал Спасибо Karsh за это полезное сообщение: | ||
Alegun (20.02.2017)
| ||
|
#13
|
||||
|
||||
|
Оффтоп:
Да, действительно, здесь вы совершенно правы - оказалось я в торопях по ошибке не ту версию виндовстэн под проверку загружал, всё зло от мультизагрузки, так вот выпендриться побыстрее хотелось, сейчас перепроверил - всё точно как в описании автора, значит "делфийцам-семеристам" этот путь в Х64 заказан, жаль Спасибо, УК Karsh!Последний раз редактировалось Alegun, 20.02.2017 в 00:37. |
|
#14
|
||||
|
||||
|
Спасибо ВСЕМ огромное за столь быстрые, качественные и информативные ответы!
|