Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Einzelne Funktionen als Admin ausführen (https://www.delphipraxis.net/167378-einzelne-funktionen-als-admin-ausfuehren.html)

RonnyBausA 27. Mär 2012 10:25

Einzelne Funktionen als Admin ausführen
 
Hallo zusammen, ich bräuchte mal wieder einen Ratschlag.

Ich habe hier eine kleine Anwendung, welche im Systray läuft. Diese wird unter einem normalen Benutzeraccount ausgeführt. In den Programmeinstellungen zu meinem Programm kann der Benutzer wahlweise auch eine Autostart funktion aktivieren, damit das Programm beim Windows Start auch gleich mit gestartet wird. Der dafür notwendige Registry-Eintrag (Run) kann natürlich nur mit Administratorrechten geändert werden. Ich möchte das Ändern dieses Registry-Eintrages also auslagern in eine Funktion, die nach der UAC-Abfrage mit Adminrechten dann dazu in der Lage ist. Bisher muss der Nutzer dazu das Programm einmal als Administrator ausführen, was natürlich irgendwie etwas unglücklich ist.

Welches wäre dazu der einfachste Weg? Kann das eine DLL machen, der ich den Programmnamen mit Pfad als ShortString übergebe oder ein COM Server. Und wenn COM-Server diesen dann in der DLL oder in meiner Anwendung selbst? So wie ich das nach langem googlen verstanden habe, muss ich wohl eine ActiveX DLL machen mit einem COM-Server drin. Ein anderer Weg wäre meine Anwendung neu zu starten und dabei Adminrechte anfordern. Dies möchte ich aber nicht machen, da meine Anwendung sich mit einer anderen Anwendung per Windows Messages unterhällt. Dies würde nicht mehr funktionieren, wenn die eine Anwendung im normalen Benutzeraccount läuft und die andere im Admin-Account.

Kann mir jemand vielleicht mal das Vorgehen ein wenig Schritt für Schritt erläutern, da ich bisher noch nie etwas mit den COM Interfaces gemacht habe. Das wäre echt nett.

Vielen Dank schon mal.
Ronny

Bummi 27. Mär 2012 10:29

AW: Einzelne Funktionen als Admin ausführen
 
Ein anderes Programm mit entsprechendem Manifest
, oder dasselbe mit Parameter per Shellexecute(handle,'RunAs'
.... starten

Bernhard Geyer 27. Mär 2012 10:31

AW: Einzelne Funktionen als Admin ausführen
 
Zwei mögichkeiten hast du:

a, Es gibt auch einen Userspezifischen-Run-Eintrag der keine Adminrechte benötigt

b, Du erzeugst eine kleine exe die du per Manifest mit "Admin benötigt" versorgst und startest diese mit ShellExecute (Nicht Createprozess!). Dann kommt auch der UAC-Dialog für diese Exe.

RonnyBausA 27. Mär 2012 10:47

AW: Einzelne Funktionen als Admin ausführen
 
Das ging ja mal wieder sauschnell mit den Antworten. Vielen Dank erst mal dafür.
Das mit der zusätzlichen EXE für diese Funktionen hatte ich auch schon überlegt. Ist wahrscheinlich der einfachste Weg. Allerdings hatte ich bei dem Gedanken mit der DLL auch noch einen Hintergedanken. Und zwar könnte ich diese DLL oder den COM-Server dann für mehrere von meinen Programmen gemeinsam nutzen, um die jeweilige Autostartfunktion zu setzen. Eventuell möchte ich auch noch einen eigenen Dienst per Button zu Debugzwecken mal starten oder stoppen können. Dies wäre ein weitere Funktion die ich einbauen könnte.
Kann mir den jemand von Euch sagen, ob ich sowas mit einer DLL alleine machen könnte (speziell das Ausführen mit Adminrechten und UAC) oder ob es einen COM-Server benötigt? Und wenn COM-Server wäre ich echt dankbar für eine kurze Anleitung oder ähnliches.

Ronny

Luckie 27. Mär 2012 12:05

AW: Einzelne Funktionen als Admin ausführen
 
Zitat:

Zitat von RonnyBausA (Beitrag 1158829)
damit das Programm beim Windows Start auch gleich mit gestartet wird. Der dafür notwendige Registry-Eintrag (Run) kann natürlich nur mit Administratorrechten geändert werden.

Nicht der für den Benutzer. Administratorenrechte benötigt man nur, wenn man in den benutzerübergreifenden Autostartschlüssel in der Registry schreiben will.

RonnyBausA 27. Mär 2012 12:15

AW: Einzelne Funktionen als Admin ausführen
 
@Luckie
da hst Du natürlich Recht. Ich hatte es bisher immer global für alle als Autostart eingetragen. Das könnte ich natürlich ändern und nur für den Benutzer den Autostart-Eintrag setzen. Das tut meinem Programm keinen Abbruch, das werde ich machen.

Trotz alledem würde es mich interessieren, ob ich z.B. mit einer DLL oder irgendwie anders auch mal eine Funktion mit Adminrechten ausführen kann und wie das ginge. Es bleibt noch meine Wunschfunktion über, meinen eigenen Dienst auch mal vom Benutzer starten oder stoppen zu lassen, ohne ihn in die Diensteverwaltung leiten zu müssen.

Ronny

jaenicke 27. Mär 2012 13:16

AW: Einzelne Funktionen als Admin ausführen
 
Zitat:

Zitat von RonnyBausA (Beitrag 1158854)
Trotz alledem würde es mich interessieren, ob ich z.B. mit einer DLL oder irgendwie anders auch mal eine Funktion mit Adminrechten ausführen kann und wie das ginge.

Wenn der notwendige COM Server von deinem Setup vorher registriert wird, geht das, ja. Aber einfach ist das nicht.

Ich mache das daher wie schon genannt wurde einfach mit der eigenen Exe und passenden Parametern...
Wenn du die mit ShellExecute und runas als Verb startest, bist du schon fast fertig. Ein Befehl also. Und in deiner Projektdatei musst du nun nur noch schauen, ob die Exe mit diesem speziellen Parameter aufgerufen wurde und dann deinen Admincode ausführen. ;-)

Dann brauchst du gar keine zweite Datei, weder Exe noch DLL.

RonnyBausA 28. Mär 2012 12:02

AW: Einzelne Funktionen als Admin ausführen
 
@jaenicke,
ich hab das jetzt so gemacht, wie du es vorgeschlagen hast. Ich starte meine Anwendung ein zweites Mal mit ShellExecuteEx und wahlweise 2 Parametern (1x zum Starten und 1x zum Stoppen meines Dienstes).
Code:
function RunAs(const FileName, StartParam: string): Boolean;
 var sefunc: TShellExecuteInfo;
begin
  FillChar(sefunc, SizeOf(sefunc), 0);
  sefunc.cbSize:= SizeOf(sefunc);
  sefunc.Wnd:= 0;
  sefunc.lpVerb:= PChar('runas');
  sefunc.lpFile:= PChar(FileName);
  sefunc.lpParameters:= PChar(StartParam);
  sefunc.nShow:= SW_HIDE;
  Result:= ShellExecuteEx(@sefunc);
end;

procedure TMainForm.DStartBtnClick(Sender: TObject);
begin
  RunAs(Application.ExeName, ' /startts');
end;
In der Projektdatei frage ich ab, ob einer der beiden Paramter übergeben wurde. Wenn ja führe ich meine Admin-Funktionen aus und beende das Programm. Andernfalls fahre ich ganz normal mit dem Erzeugen der Formulare fort und lasse das Programm normal laufen.
Code:
  StartProg := True;
  if ParamCount > 0 then                                                       // Startparameter wurde übergeben
  begin
    if (LowerCase(ParamStr(1)) = '/startts') then                              // Dienst starten
    begin
      ServiceStart('','MyService');
      StartProg := False;                                                      // Das normale Programm nicht ausführen
    end
    else if (LowerCase(ParamStr(1)) = '/stopts') then                          // Dienst stoppen
    begin
      ServiceStop('','MyService');
      StartProg := False;                                                      // Das normale Programm nicht ausführen
    end;
  end;
  if StartProg then
  begin
    Application.CreateForm(TMainForm, MainForm);
    .
    .
    Application.Run;
  end;
Das funktioniert soweit gut. Damit ist meine Frage beantwortet.
Vielen Dank an euch alle.
Ronny

Assarbad 16. Apr 2012 20:03

AW: Einzelne Funktionen als Admin ausführen
 
Zitat:

Zitat von RonnyBausA (Beitrag 1158854)
Trotz alledem würde es mich interessieren, ob ich z.B. mit einer DLL oder irgendwie anders auch mal eine Funktion mit Adminrechten ausführen kann und wie das ginge.

Das geht mal prinzipiell garnicht, es sei denn du hast diverse Privilegien (bzw. der ausführende Prozeß). Im Endeffekt läuft es auf TCB-Privilegien hinaus ...

Ich rede hier von Impersonation, also dem Annehmen einer anderen Benutzeridentität (pro Thread). Alles andere läuft an Prozeßgrenzen ab und kann daher nicht pro Funktion privilegiert gemacht werden.

Zitat:

Zitat von RonnyBausA (Beitrag 1158854)
Es bleibt noch meine Wunschfunktion über, meinen eigenen Dienst auch mal vom Benutzer starten oder stoppen zu lassen, ohne ihn in die Diensteverwaltung leiten zu müssen.

Kannste doch. Dienste sind genau dazu da Löcher in das Rechtesystem zu bohren um gezielt Funktionalität an unprivilegierte Benutzer zu delegieren.

Sprich: schreibe zwei Dienste, oder registriere deinen Dienst zweimal. Einmal bietet er den Dienst an den du halt jetzt schon anbietest (Dienst A). Einmal bietet er (bspw. auf Basis von Gruppenmitgliedschaften oder anderen Eigenschaften) an Dienst A zu starten und zu stoppen. Schon ist die Sache gegessen und Benutzer können das bequem selber erledigen. Das geht dann ggf. sogar ohne UAC-Dialog, wenn man das so will ...

RonnyBausA 17. Apr 2012 07:35

AW: Einzelne Funktionen als Admin ausführen
 
Zitat:

Zitat von Assarbad (Beitrag 1162162)
Einmal bietet er den Dienst an den du halt jetzt schon anbietest (Dienst A). Einmal bietet er (bspw. auf Basis von Gruppenmitgliedschaften oder anderen Eigenschaften) an Dienst A zu starten und zu stoppen. Schon ist die Sache gegessen und Benutzer können das bequem selber erledigen. Das geht dann ggf. sogar ohne UAC-Dialog, wenn man das so will ...

Dienst B muss dann aber auch mit dem lokalem Systemkonto laufen, damit er Dienst A starten oder stoppen kann, sehe ich dass richtig?
Und kommt die UAC-Abfrage nicht standardmäßig, wenn ein Dienst gestartet oder gestoppt werden soll?
Das wäre jetzt nur mal für mich zum Verständnis. Da ich für diesen Fall das Starten oder Stoppen des Dienstes sowieso nur in Ausnahmefällen und dann mit Benutzerinteraktion mache funktioniert das prima mit dem Starten der zweiten Instanz meines Programms. Aber vielleicht braucht man so eine Funktion ohne UAC ja mal in einem anderen Programm.

Viele Grüße
Ronny


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:01 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz