Czy da się wymusić na aplikacji pisanej w Delphi, aby bez żadnych ustawień w systemie (PPM->Uruchom jako administrator) uruchamiała się w systemie Windows Vista i 7 w trybie administratora?
tak - było ostatnio, trzeba odpowiednio spreparować manifest
Możesz mi wskazać ten temat, bo szukałem, ale nic konkretnego nie mogę znaleźć.
Znalazłem wiele rozwiązać, choć żadne mnie nie zachwyciło, gdyż żadne nie działało jak trzeba jeśli w ogóle działało...
Skorzystałem z poniższego rozwiązania, gdzie style w XP działają poprawnie i podobno w Viście uruchamia się jako administrator, lecz nie u mnie:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly
xmlns="urn:schemas-microsoft-com:asm.v1"
manifestVersion="1.0">
<assemblyIdentity
name="CiaoSoftware.Ciao.Shell.Contacts"
processorArchitecture="x86"
version="5.1.0.0"
type="win32"/>
<description>Windows Shell</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="x86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>
Wyczytałem, że w Windows 7, trzeba dorzucić do tego pliku to:
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!--The ID below indicates application support for Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!--The ID below indicates application support for Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
</application>
</compatibility>
Lecz i to nie dawało żadnych rezultatów. Może po prostu robię coś źle. Wrzucam to do pliku o jakieś dowolnej nazwie z rozszerzeniem 'manifest'. Potem do pliku o tej samej nazwie co plik manifestu, tylko że o rozszerzeniu 'RC' wrzucam to:
1 24 "Nazwa_pliku.Manifest"
Na koniec z konsoli Windows kompiluje to poleceniem:
brcc32 Nazwa_pliku.RC -foNazwa_pliku.REC
(po uprzednim skopiowaniu pliku brcc32.exe do lokalizacji z plikiem manifestu) i w unicie głównym projektu dorzucam:
{$R Nazwa_pliku.REC}
Co jest nie tak?
{
Manifesty aplikacji nie są niczym nowym w Windows Vista - dotychczas używano już ich w Windows XP.
W Windows Vista dodano jednak nowy element, dzięki któremu można określić wymagany poziom
uprawnień dla aplikacji.
Wygląda on przykładowo tak:
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
Dostępne wartości dla atrybutu level to:
* requireAdministrator - aplikacja jest uruchamiana od razu w stanie podwyższonych uprawnień
* highestAvaliable - aplikacja jest uruchamiana z maksymalnymi prawami dostępnymi dla danego użytkownika
* asInvoker - aplikacja działa z takimi uprawnieniami, z jakimi została uruchomiona
Atrybut uiAccess odpowiada za pewne zachowania dotyczące aplikacji -
wartość false powinna być stosowana najczęściej, wartość true pozwala aplikacji wysyłać
zdarzenia do okien aplikacji o wyższych uprawnieniach. Aby uruchomić aplikację z uiAccess
ustawionym na true, musi być ta aplikacja podpisana cyfrowo z użyciem mechanizmu Authenticode.
Tworzenie manifestu
UWAGA: Remove all references to XPMan unit from project!!!
UWAGA: Usuń komponent XPMan jeśli chcesz użyć zmodyfikowanego Manifestu dla XP i Visty !
Aby określić wymagany poziom uprawnień w aplikacji, należy najpierw stworzyć odpowiedni plik manifestu
- powinien on mieć taką nazwę jak plik wykonywalny, z rozszerzeniem .manifest.
Na przykład może on wyglądać tak:
Aplikacja: IsUserAdmin.exe
Manifest: IsUserAdmin.exe.manifest
//-->
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0"
processorArchitecture="X86"
name="IsUserAdmin"
type="win32"/>
<description>Opis aplikacji</description>
<!-- Wymagania odpowiedzialne za bezpieczeństwo. -->
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="requireAdministrator" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
//<--
Jednak dotyczy to tylko i wyłącznie aplikacji dla Windows Vista. Aplikacje,
które mają pracować także w Windows XP, niestety należy nieco zmodyfikować manifest.
Jest to spowodowane, że aplikacja dodająca manifesty, mt.exe z pakietu Visual Studio 2005,
posiada błąd uniemożliwiający użycie drugiej przestrzeni nazw w pliku XML. Można to obejść
stosując taką konstrukcję pliku:
UWAGA:
Jeśli plik manifestu jest źle sformatowany (zawiera błędne dane),
może pojawiać się BlueScreen w Windows.
Czytaj błąd Microsoft: KB921337.
//-->
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<ms_asmv2:trustInfo xmlns:ms_asmv2="urn:schemas-microsoft-
com:asm.v2">
<ms_asmv2:security>
<ms_asmv2:requestedPrivileges>
<ms_asmv2:requestedExecutionLevel
level="requireAdministrator">
</ms_asmv2:requestedExecutionLevel>
</ms_asmv2:requestedPrivileges>
</ms_asmv2:security>
</ms_asmv2:trustInfo>
</assembly>
//<--
Taki plik manifestu należy dołączyć do zasobów aplikacji.
W pliku .rc powinny się znaleźć przykładowo takie linie:
//-->
#define MANIFEST_RESOURCE_ID 1
MANIFEST_RESOURCE_ID RT_MANIFEST "nazwa_aplikacji.exe.manifest"
//<--
Dodanie manifestu w kodzie
}
program
{$R 'ExecetionLevelManifest.res' 'ExecutionLevelManifest.rc'}
uses
Forms,
// ...;
{$R *.res}
begin
Application.Initialize;
//
Application.Run;
end;
{
Zapisuj swoje dane, logi za pomocą funkcji SHGetFolderPath w następujących folderach
(nigdy nie używaj do tego folderów "ProgramFiles", "Windows", "System32" !).
}
CSIDL_PERSONAL { My Documents }
CSIDL_APPDATA { Application Data, new for NT4 }
CSIDL_LOCAL_APPDATA { non roaming, user\Local Settings\Application Data }
CSIDL_COMMON_APPDATA { All Users\Application Data }
CSIDL_MYPICTURES { My Pictures, new for Win2K }
CSIDL_COMMON_DOCUMENTS { All Users\Documents }
uses
SHFolder;
function GetFolder(CSIDL: Integer; ForceFolder: Boolean = False): String;
var
i: Integer;
begin
SetLength(Result, MAX_PATH);
if ForceFolder then SHGetFolderPath(0, CSIDL or CSIDL_FLAG_CREATE, 0, 0, pChar(Result))
else SHGetFolderPath(0, CSIDL, 0, 0, pChar(Result));
i := Pos(#0, Result);
if i > 0 then SetLength(Result, Pred(i));
end;
{Przykład użycia}
function GetLocalAppDataFolder(ForceFolder: Boolean = False): String;
begin
Result := GetFolder(CSIDL_LOCAL_APPDATA, ForceFolder);
end;
{Jak uruchamiać inne programy jako Administrator ?}
procedure RunAsAdmin(hWnd: HWND; aFile, aParam: String);
var
Sei: TShellExecuteInfoA;
begin
FillChar(Sei, SizeOf(Sei), 0);
Sei.cbSize := SizeOf(Sei);
Sei.Wnd := hWnd;
Sei.fMask := SEE_MASK_FLAG_DDEWAIT or SEE_MASK_FLAG_NO_UI;
Sei.lpVerb := 'runas';
Sei.lpFile := pChar(aFile);
Sei.lpParameters := pChar(aParam);
Sei.nShow := SW_SHOWNORMAL;
if not ShellExecuteEx(@Sei) then RaiseLastOSError;
end;
{lub zmodyfikowana procedura w/w}
procedure TFormODK.UruchomProgram(Plik, Param: String);
var
Sei: TShellExecuteInfoA;
begin
{Jeśli nie jest to Win9x}
if Win32Platform <> VER_PLATFORM_WIN32_WINDOWS then
begin
FillChar(Sei, SizeOf(Sei), 0);
Sei.cbSize := SizeOf(Sei);
Sei.Wnd := Application.Handle;
Sei.fMask := SEE_MASK_IDLIST or SEE_MASK_FLAG_DDEWAIT or SEE_MASK_FLAG_NO_UI;
{Jeśli jest to Vista}
if Win32MajorVersion >= 6 then Sei.lpVerb := 'runas'
else Sei.lpVerb := 'open';
Sei.lpFile := pChar(Plik);
Sei.lpParameters := pChar(Param);
Sei.nShow := SW_SHOWNORMAL;
if not ShellExecuteEx(@Sei) then RaiseLastOSError;
end
else ShellExecute(Application.Handle, 'open', pChar(Plik), pChar(Param), nil, SW_SHOWNORMAL);
end;
{Dodanie do własnej aplikacji ikonki Shield Visty, która informuje iż wymagane są podwyższone uprawnienia}
const
BCM_FIRST = $1600; //Button control messages
BCM_SETSHIELD = BCM_FIRST + $000C;
procedure SetElevationRequiredState(aControl: TWinControl; Requiered: Boolean);
var
i: Integer;
begin
i := Integer(Requiered);
SendMessage(aControl.Handle, BCM_SETSHIELD, 0, i);
end;
{Wywołanie}
SetElevationRequiredState(B_Przycisk.Control, True);
Dobra jutro wszystko przetestuje, ale co z Windows 7? Ten sam manifest co z Visty ma działać?
Od Visty w górę (jeśli chodzi o uprawnienia).
Od XP w górę (jeśli chodzi o style).
Napisałem wszystko tak jak tam jest, ale niestety nie działa.
Tzn co masz na myśli ?
Wiesz o tym, że UAC i tak (jeśli jest włączone) to poprosi Cię o podwyższenie uprawnień ?
Odpada Ci tylko ręczne wybieranie programu przez "Uruchom jako administrator".
Poza tym, pokaż kod.
UAC poprosi o podwyższenie uprawnień, ale oszczędzi to przykrych skutków działania programu na ograniczonych uprawnieniach, szczególnie jeżeli chodzi o zapis plików lub do kluczy innych niż HKCU.
ja zrobiłem to sobie tak i działa fajnie, nie muszę się martwić o to.
Znajdź plik WindowsXP.res w katalogu %PROGRAMFILES%\Borland\Delphi7\Lib
Podmień całą jego zawartość na :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1"
manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
<v3:trustInfo xmlns:v3="urn:schemas-microsoft-com:asm.v3">
<v3:security>
<v3:requestedPrivileges>
<v3:requestedExecutionLevel level="requireAdministrator" />
</v3:requestedPrivileges>
</v3:security>
</v3:trustInfo>
</assembly>
I masz sprawę załatwioną. Do każdej aplikacji dodajesz komponent XPManifest (XPman.pas). Jeżeli go nie masz, sciągnij z neta, zainstaluj w delphi i postępuj tak jak ja Ci napisalem.
Pozdro!
siema, troche odswieze, cos nie dzialaja mi te spoosby, a chcialbym uzyskac aplikacje, ktora uruchamia sie jako admin zarowno w XP jak i VISTA/7 .... albo chociaz XP na razie.
niech sie specjalisci wypowiedza, ktory sposob w 100% dziala i bede kombinoal potem czemu nie gra u mnie. pozdro
zrob moj sposób i miej spokuj. u mnie to działa. jak Ci nie dziala to weż manifest od kolegów wyżej i wpisz go tak jak Ci napisałem.
Wiem, że będzie wyskakiwał komunikat. Mam specjalnie włączony UAC, żeby ten komunikat wyskakiwał, niestety żadna metoda nie działa. Przerobienie tego pliku Windows.res też nie działa, kompilator wyrzuca później błędy o jakichś 16 bitach, które są niepoprawne. Jakbyś mógł to wrzuć gdzieś ten plik Windows.res gotowy, ten co tobie działało.
musiałeś coś źle zrobić. Jak będę w domu to zarzucę plikiem ;)
Byłbym wdzięczny, będę czekał. ;)
tak tak, jednym z bledow po zmianie zawartosci w WindowXP.res bylo to ze D& Personal nie mogla nic kompilowac bo cos o 16bit pisalo ze niepoprawne. (dobrze ze zrobilem kopie bezpieczenstwa hehe :D )
Poradziłem sobie inaczej z trybem admina zarówno w Windows Vista jak i Windows 7. Mianowicie do głównej formatki dorzucam komponent ManifestXP i po skompilowaniu programu uruchamiam sobie inny program - ResHacker. Otwieram przez niego mój skompilowany program. W lewej kolumnie otwierają się poszczególne grupy. Otwierasz tą na samym dole: "24". Wyświetli się plik "0" z treścią manifestu. Kasujesz wszystko i wrzucasz to:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="x86"
name="Appname"
type="win32"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator"/>
</requestedPrivileges>
</security>
</trustInfo>
<description>Mój program</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="x86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>
Klikasz "Compile Script" i z menu file zapisujesz nowy plik exe, który działa we wszystkich systemach :). U mnie działa w 100%.
Może jak Legalnl wrzuci ten swój plik WindowsXP.res będzie prościej.
Zastanawiam się tylko jeszcze, co zrobić, żeby w polach 'nazwa aplikacji' i 'wydawca' przy zapytaniu UAC zamiast nazwy pliku i Nieznany wydawca pisało to co chcemy? Czy musimy mieć podpis cyfrowy?
o metodzie z ResHackiem tez slyszalem chociaz nie uzywalem jeszcze - wolalbym to zrobic w pelni programowo w delphi,
a w ogole czy powyzszy sposob dziala takze na XP? (napisales ze na wszystkich systemach ale to chyba rozne manifesty)
Napisałem we wszystkich systemach: XP SP3, Vista, Vista SP1, Vista SP2 i 7. W starszych XP nie mam jak sprawdzić.
EDIT: Udało mi się przekompilować ten plik manifestu XP. Jak ktoś chce by aplikacja działała z trybem admina w Viście i 7-ce podbieracie ten plik: POBIERZ i wrzucacie go do folderu ...\Borland\Delphi7\Lib\ i zamieniacie. Na koniec dodajecie manifest XP do programu.
Zastanawiam się tylko nadal, co zrobić, żeby w polach 'nazwa aplikacji' i 'wydawca' przy zapytaniu UAC zamiast nazwy pliku i Nieznany wydawca pisało to co chcemy? Czy musimy mieć podpis cyfrowy dla pliku?