Tryb administratora Vista i 7

0

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?

0

tak - było ostatnio, trzeba odpowiednio spreparować manifest

0

Możesz mi wskazać ten temat, bo szukałem, ale nic konkretnego nie mogę znaleźć.

0

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?

0
{
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);
0

Dobra jutro wszystko przetestuje, ale co z Windows 7? Ten sam manifest co z Visty ma działać?

0

Od Visty w górę (jeśli chodzi o uprawnienia).
Od XP w górę (jeśli chodzi o style).

0

Napisałem wszystko tak jak tam jest, ale niestety nie działa.

0

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.

0

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!

0

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

0

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.

0

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.

0

musiałeś coś źle zrobić. Jak będę w domu to zarzucę plikiem ;)

0

Byłbym wdzięczny, będę czekał. ;)

0

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 )

0

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?

0

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)

0

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?

1 użytkowników online, w tym zalogowanych: 0, gości: 1