V
Vadik(R)
Тема в принципе заезженная, поэтому решил написать в ветке FAQ (да и вообще, моей любимой
).
В общем, проблема такая. Когда делаешь какую-либо программу на Delphi 7, и в ней, допустим, пытаешься создать какой-либо файл в корне диска, то в Windows XP все работает нормально, а в Windows 7 - файл вместо корня диска создается в папке C:\Users\Vadim\AppData\Local\VirtualStore.
Ну, как и следует, видимо из соображений безопасности. Для того, чтобы создать файл именно в корне диска C - приходиться запускать программу с правами администратора, щелкать по кнопке OK в UAC-окне. Проблема в следующем, что мне надоело каждый раз принудительно щелкать правой кнопкой мыши и запускать программу с администраторскими правами. Решение есть - поставить в свойствах галочку - запустить программу с правами администратора. Но оно меня не очень устраивает, поскольку, если сменить расположение программы, то галочку приходится ставить заново, да и вообще, выходит мне так придеться ставить галочки почти для каждой написанной мною программы? - Не выход. Отключать UAC я тоже не хочу, все же раз придумали эту штуку как средство защиты, пускай есть, пригодится. Потому пришёл к выводу, что надо сделать так, чтобы программа сама запускала себя сразу с правами администратора. Погуглив, я нашёл способ сделать такое с помощью manifest-файла, правда везде этот способ описывался для Visual Studio C++. А мне надо для Delphi 7, все же, хоть и мертвый язык, для меня он привычней
Вот, стал гуглить, как запустить программу с правами администратора для Delphi, а параллельно наткнулся на код, который определяет, запущена ли программа уже с правами администратора или нет:
Но, проблема в том, что этот код не рабочий. Он всегда выдает сообщение, что программа запущена с правами администратора.
Поэтому, я нашёл другой выход из этой ситуации, правда кривой на мой взгляд. А именно, программе без администраторских прав запрещено создавать exe-файлы в корне диска, даже если в файл будет создаваться в VirtualStore. Потому я пытаюсь создать какую-либо exe-шку в корне диска, и, если это сделать не получается, то программа запущена без администраторских прав, иначе все хорошо
Способ, понятное дело, очень не хороший, так как программа с таким именем может уже существовать в корне диска, да и в целом, левый способ. Хотя, если бы можно было внедрять manifest-файл в Delphi, так же, как и в Visual Stidio C++, то проблема определения, запущена ли программа с администраторскими правами, отпадет сама 
Но это только половина дела, определить, как запущена программа, ведь если она запущена не под админом, то ей стоит перезапустить саму себя уже с администраторскими правами. Вот, опять погуглил эту проблему, нашёл код с функцией CreateProcessWithLogonW:
Но эта функция всегда выводит мне сообщение "Краххх.." 
Не знаю, почему так. Кто-то говорит, что это из-за того, что пароль стоит пустой, и таким образом это такая защита...
В общем, проблема такая, что надо программно запустить самого себя с правами администратора. Сделать это надо средствами Delphi 7, было бы обидно, что если такая возможность была только в C++.

В общем, проблема такая. Когда делаешь какую-либо программу на Delphi 7, и в ней, допустим, пытаешься создать какой-либо файл в корне диска, то в Windows XP все работает нормально, а в Windows 7 - файл вместо корня диска создается в папке C:\Users\Vadim\AppData\Local\VirtualStore.
Ну, как и следует, видимо из соображений безопасности. Для того, чтобы создать файл именно в корне диска C - приходиться запускать программу с правами администратора, щелкать по кнопке OK в UAC-окне. Проблема в следующем, что мне надоело каждый раз принудительно щелкать правой кнопкой мыши и запускать программу с администраторскими правами. Решение есть - поставить в свойствах галочку - запустить программу с правами администратора. Но оно меня не очень устраивает, поскольку, если сменить расположение программы, то галочку приходится ставить заново, да и вообще, выходит мне так придеться ставить галочки почти для каждой написанной мною программы? - Не выход. Отключать UAC я тоже не хочу, все же раз придумали эту штуку как средство защиты, пускай есть, пригодится. Потому пришёл к выводу, что надо сделать так, чтобы программа сама запускала себя сразу с правами администратора. Погуглив, я нашёл способ сделать такое с помощью manifest-файла, правда везде этот способ описывался для Visual Studio C++. А мне надо для Delphi 7, все же, хоть и мертвый язык, для меня он привычней

Вот, стал гуглить, как запустить программу с правами администратора для Delphi, а параллельно наткнулся на код, который определяет, запущена ли программа уже с правами администратора или нет:
Код:
const
SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5));
SECURITY_BUILTIN_DOMAIN_RID = $00000020;
DOMAIN_ALIAS_RID_ADMINS = $00000220;
function IsAdmin: Boolean;
var
hAccessToken: THandle;
ptgGroups: PTokenGroups;
dwInfoBufferSize: DWORD;
psidAdministrators: PSID;
x: Integer;
bSuccess: BOOL;
begin
Result := False;
bSuccess := OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True, hAccessToken);
if not bSuccess then
begin
if GetLastError = ERROR_NO_TOKEN then bSuccess := OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, hAccessToken);
end;
if bSuccess then
begin
GetMem(ptgGroups, 1024);
bSuccess := GetTokenInformation(hAccessToken, TokenGroups, ptgGroups, 1024, dwInfoBufferSize);
CloseHandle(hAccessToken);
if bSuccess then
begin
AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, psidAdministrators);
{$R-}
for x := 0 to ptgGroups.GroupCount - 1 do
if EqualSid(psidAdministrators, ptgGroups.Groups[x].Sid) then
begin
Result := True;
Break;
end;
{$R+}
FreeSid(psidAdministrators);
end;
FreeMem(ptgGroups);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if isAdmin then ShowMessage('Logged in as Administrator');
end;
Поэтому, я нашёл другой выход из этой ситуации, правда кривой на мой взгляд. А именно, программе без администраторских прав запрещено создавать exe-файлы в корне диска, даже если в файл будет создаваться в VirtualStore. Потому я пытаюсь создать какую-либо exe-шку в корне диска, и, если это сделать не получается, то программа запущена без администраторских прав, иначе все хорошо


Но это только половина дела, определить, как запущена программа, ведь если она запущена не под админом, то ей стоит перезапустить саму себя уже с администраторскими правами. Вот, опять погуглил эту проблему, нашёл код с функцией CreateProcessWithLogonW:
Код:
function CreateProcessWithLogonW(lpUsername: PWideChar; lpDomain: PWideChar; lpPassword: PWideChar; dwLogonFlags: DWORD; lpApplicationName: PWideChar; lpCommandLine: PWideChar; dwCreationFlags: DWORD; lpEnvironment: Pointer; lpCurrentDirectory: PWideChar; const lpStartupInfo: STARTUPINFO; var lpProcessInfo: PROCESS_INFORMATION): BOOL; stdcall; external 'advapi32.dll' name 'CreateProcessWithLogonW';
...
var
si: STARTUPINFO;
pi: PROCESS_INFORMATION;
begin
...
ZeroMemory(@si, SizeOf(si));
si.cb := SizeOf(si);
if CreateProcessWithLogonW('administrator', nil, '', 1, nil, PWideChar(Application.ExeName), 0, nil, nil, si, pi) then ShowMessage('Yahoo') else ShowMessage('Krahhh...');
end;

Не знаю, почему так. Кто-то говорит, что это из-за того, что пароль стоит пустой, и таким образом это такая защита...
В общем, проблема такая, что надо программно запустить самого себя с правами администратора. Сделать это надо средствами Delphi 7, было бы обидно, что если такая возможность была только в C++.