Einzelnen Beitrag anzeigen

Sergej_Molotov

Registriert seit: 18. Jul 2006
61 Beiträge
 
Delphi 11 Alexandria
 
#1

Programm vom Dienst starten mit mehr Rechten???

  Alt 28. Sep 2010, 16:09
Hallo Zusammen,

ich habe eine Anwendung, die als Dienst unter dem System-Account unter Windows läuft. Je nach Anforderung (wird von einem Webservice getriggert) soll der Dienst ein Programm deinstallieren. Da leider nicht jede Software direkt über msi-installiert wird, muss auch ggf. bei einer Deinstallation eine Benutzerinteraktion erfolgen. Hier besteht das Problem, dass der angemeldete User nicht unbedingt administrative Rechte besitzt. So habe ich mir gedacht, dass es möglich sein musste, das ich (als Dienst) eine Prozess für den angemeldeten Benutzer starte, und dass dieser Prozess administrative Rechte hat.

Auf meine Suche nach einer Lösung bin ich auf folgendes gestoßen.
http://www.delphipraxis.net/109191-p...ich-mal-3.html

Dieses ist aber nicht möglich, da bei uns die jwscl nicht verwendet werden soll. Aus diesem Grund suche ich nach einer Lösung mit Delphi-Boardmitteln. Die Verwendung der jwa ist aber möglich.

Delphi-Quellcode:
unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm2 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    function CreateProcess4LoggedOnUser(const cmd: String): Cardinal;
    procedure WriteLog(const aMessage: String);
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

uses
  TlHelp32,
  jwaWinBase,
  jwaUserEnv;


procedure TForm2.Button1Click(Sender: TObject);
begin
  CreateProcess4LoggedOnUser('C:\Programme\CCleaner\uninst.exe');
end;

function TForm2.CreateProcess4LoggedOnUser(const cmd: String): Cardinal;
var
  hToken : THandle;
  newToken : THandle;
  blub : Cardinal;
  aSessionId : Cardinal;
  aStartup : Windows.TStartupInfo;
  aPI : Windows.TProcessInformation;
  MyEnv : Pointer;
  bla : DWORD;
begin
  Memo1.Lines.Clear;
  result := 0;

  if Windows.OpenProcessToken(GetCurrentProcess, TOKEN_ALL_ACCESS, hToken) then
  begin
    WriteLog('OpenProcessToken Ok');
    if Windows.ImpersonateLoggedOnUser(hToken) then
    begin
      WriteLog('ImpersonateLoggedOnUser Ok');
      if Windows.DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, nil, SecurityImpersonation, TOKENPRIMARY, newToken) then
      begin
        WriteLog('DuplicateTokenEx Ok');
        aSessionId := jwaWinBase.WTSGetActiveConsoleSessionId;
        bla := DWORD(aSessionId);
        if Windows.SetTokenInformation(newToken, Windows.TokenSessionId, @bla, SizeOf(DWORD)) then //Hier wird ein Fehler ausgelöst: (Error-Code 1314): Dem Client fehlt ein erforderliches Recht
        begin
          WriteLog('SetTokenInformation Ok');

          FillChar(aStartup,SizeOf(TStartupInfo),#0);
          FillChar(aPI,SizeOf(TProcessInformation),#0);
          aStartup.cb := SizeOf(TStartupInfo);
          aStartup.lpDesktop := 'WinSta0\Default';

          MyEnv := nil;
          // Umgebungsvariablen werden vom Benutzer ermittelt.
          if jwaUserEnv.CreateEnvironmentBlock(@MyEnv, newToken, false) then
          begin
            WriteLog('CreateEnvironmentBlock Ok');
            if Windows.CreateProcessAsUser(newToken, pChar(cmd), nil, nil, nil, true, NORMAL_PRIORITY_CLASS or CREATE_NEW_CONSOLE or CREATE_UNICODE_ENVIRONMENT, MyEnv, nil, aStartup ,aPI) then
            begin
              WriteLog('CreateProcessAsUser Ok');
              CloseHandle(aPI.hProcess);
              CloseHandle(aPI.hThread);
            end
            else
            begin
              result := GetLastError;
              WriteLog('7: '+Sysutils.SysErrorMessage(result));
            end;

            jwaUserEnv.DestroyEnvironmentBlock(MyEnv);
          end
          else
          begin
            blub := Windows.GetLastError;
            WriteLog('CreateEnvironmentBlock('+IntToStr(blub)+'): ' + Sysutils.SysErrorMessage(blub));
          end;
        end
        else
        begin
          blub := Windows.GetLastError;
          WriteLog('SetTokenInformation('+IntToStr(blub)+'): ' + Sysutils.SysErrorMessage(blub));
        end;
      end
      else
        WriteLog('DuplicateTokenEx: ' + Sysutils.SysErrorMessage(Windows.GetLastError));
    end
    else
      WriteLog('ImpersonateLoggedOnUser: ' + Sysutils.SysErrorMessage(Windows.GetLastError));
  end
  else
    WriteLog('OpenProcessToken: ' + Sysutils.SysErrorMessage(Windows.GetLastError));
end;


procedure TForm2.WriteLog(const aMessage: String);
begin
  Memo1.Lines.Add(aMessage);
end;

end.
Nun meine simple Frage:
Was mach ich falsch
Thomas
  Mit Zitat antworten Zitat