AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) User-Spezifische Folder ermitteln wenn mit "Run als Administrator" gestartet wurde
Thema durchsuchen
Ansicht
Themen-Optionen

User-Spezifische Folder ermitteln wenn mit "Run als Administrator" gestartet wurde

Ein Thema von Christoph Schneider · begonnen am 30. Aug 2011 · letzter Beitrag vom 4. Sep 2011
Antwort Antwort
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#1

AW: User-Spezifische Folder ermitteln wenn mit "Run als Administrator" gestartet wurd

  Alt 31. Aug 2011, 11:17
Um beispielsweise ein Menu-Eintrag ins Startmenu zu schreiben ist der Zeitpunkt der Installation sicher der einzig richtige.
Und was ist mit den anderen Benutzern? Wenn du keine halben Sachen machen willst, müsstest du alle Benutzer durchgehen und für jeden Benutzer den Startmenüeintrag anlegen.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.343 Beiträge
 
Delphi 12 Athens
 
#2

AW: User-Spezifische Folder ermitteln wenn mit "Run als Administrator" gestartet wurd

  Alt 31. Aug 2011, 11:25
Wenn du keine halben Sachen machen willst, müsstest du alle Benutzer durchgehen und für jeden Benutzer den Startmenüeintrag anlegen.
Für sowas gibt es aber den Default-User.

Ich fände es schön, wenn setups fragen würden (was einige Wenige sogar schon machen) wo es installiert werden soll.
- für aktuellen benutzer
- für alle Benutzer
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#3

AW: User-Spezifische Folder ermitteln wenn mit "Run als Administrator" gestartet wurd

  Alt 31. Aug 2011, 11:43
Dann muss er aber nicht umständlich mit Tokens und Sessions rumhantieren. Den Default-User gibt es nicht, das ist nur ein Ordner unter den Benutzerprofilen, der für alle gilt. Da kann er dann einfach seinen Startmenüeintrag machen. Was ich aber auch nicht leiden kann, weil eine Verknüpfung die da liegt, kann der einzelne Benutzer nicht löschen oder verschieben, wenn er sie nicht haben will oder an einer anderen Stelle.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Christoph Schneider
Christoph Schneider

Registriert seit: 7. Okt 2008
Ort: CH-Baar
56 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: User-Spezifische Folder ermitteln wenn mit "Run als Administrator" gestartet wurd

  Alt 31. Aug 2011, 13:02
Genau, mein Installationsprogram frägt den Anwender, ob für alle oder nur für den laufenden User installiert werden soll. Im ersten Falle wird dann als CSIDL bspw. für den Startordner CSIDL_COMMON_PROGRAMS verwendet während für den aktuellen User CSIDL_PROGRAMS abgefragt wird. Dieser Ansatz funktionierte auch bis und mit XP problemlos. Seit aber immer mehr User ohne Admin-Rechte laufen und gezielt für die Installation ein User-Wechsel vorgenommen wird, läuft dies wie erwähnt nicht mehr.
Die Verwendung des Default-Users ist mea. auch nicht geeignet, den dieser wird als Template-User verwendet, wenn in Zukunkt ein neuer User eingerichtet wird.
Christoph Schneider
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.343 Beiträge
 
Delphi 12 Athens
 
#5

AW: User-Spezifische Folder ermitteln wenn mit "Run als Administrator" gestartet wurd

  Alt 31. Aug 2011, 13:54
Stimmt, DefaultUser war eh falsch ... gab es nicht früher mal einen User AllUsers?

In Win2008 isses C:\ProgramData\Microsoft\Windows\Start Menu\Programs .


Tja, dann wirst du es wohl doch z.B. mal über den Besitzer der Session probieren müssen.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von Christoph Schneider
Christoph Schneider

Registriert seit: 7. Okt 2008
Ort: CH-Baar
56 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: User-Spezifische Folder ermitteln wenn mit "Run als Administrator" gestartet wurd

  Alt 2. Sep 2011, 09:28
Unterdessen habe ich meinen Fehler entdeckt. Es lag an einem Seiteneffekt und gar nicht am gezeigten Code - der funktionierte bereits richtig.
Ich habe für Test-Zwecke das Token noch gebraucht um Domain und UserName darzustellen. Dafür hätte ich aber das
Token vorher noch duplizieren müssen. Hier zeige ich gerne die jetzt implementierte Lösung:
Code:
function CreateTokenOfProcess(ProcessId: DWORD): THandle;
const
  PROCESS_QUERY_LIMITED_INFORMATION = $1000;
var
  ProcessHandle, TokenHandle: THandle;
begin
  result := 0;
  ProcessHandle := 0;
  try
    ProcessHandle:= OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, True, ProcessId);
    if ProcessHandle <> 0 then
    begin
      if OpenProcessToken(ProcessHandle, TOKEN_QUERY or TOKEN_IMPERSONATE, TokenHandle) then
        result := TokenHandle;
      // Call CloseHandle(TokenHandle) by caller
    end;
  finally
    CloseHandle(ProcessHandle);
  end;
end;

function GetParentProcessID: DWORD;
// This function should be part of the API!
var
  Snap: THandle;
  Proc: TProcessEntry32;
  CurrentProc: cardinal;
begin
  result := 0;
  Snap := CreateToolHelp32SnapShot(TH32CS_SNAPALL, 0);
  try
    CurrentProc := GetCurrentProcessId;
    Proc.dwSize := SizeOf(TProcessEntry32);
    Process32First(Snap, Proc);
    repeat
      if Proc.th32ProcessID = CurrentProc then
      begin
        result := Proc.th32ParentProcessID;
        Break;
      end;
    until (not Process32Next(Snap, Proc));
  finally
    CloseHandle(Snap);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  hres: HResult;
  Folder: array[0..Max_Path] of Char;
  Token: THandle;
begin
  Token := CreateTokenOfProcess(GetParentProcessID);
  try
    hRes := SHGetFolderPath(Handle, CSIDL_PROGRAMS, Token, SHGFP_TYPE_DEFAULT, Folder);
    if not Succeeded(hRes) then
      raise Exception.Create(SysErrorMessage(hRes)));
    ShowMessage('SHGetFolderPath Succeeded:' + string(Folder));
  finally
    CloseHandle(Token);
  end;
end;

Den Ansatz über die Session ID bringe ich leider nicht zum Laufen. Hier kurz der Abriss:
Code:
function WTSQueryUserToken(SessionId: DWORD; phToken: pHandle):bool; stdcall; external 'wtsapi32.dll';
function ProcessIdToSessionId(dwProcessId: DWORD; pSessionId: DWORD): bool; stdcall; external 'Kernel32.dll';

function CreateTokenFromSession: THandle;
var
  SessionID: cardinal;
begin
  if not ProcessIdToSessionId(GetCurrentProcessId, DWORD(@SessionID)) then
    raise Exception.Create(SysErrorMessage(GetLastError)));
  { Korrekte Session ID erhalten }
  if not WTSQueryUserToken(SessionId, @result) then
    raise Exception.Create(SysErrorMessage(GetLastError)));
    { Hier bekomme ich immer "A required privilege is not held by the client" }
end;
Ich versuchte noch das Privileg SE_TCB_NAME zu setzen, scheiterte aber auch damit.

Die Lösung mit dem Parent-Prozess sollten im normalen Umfeld eigentlich gut funktieren. Probleme entstehen,
wenn der Installer aus einem Batch oder einer anderen Applikation gestartet wird, die bereits den User-Switch
vorgenommen haben. Da mein Installer über kein Command-Line Interface verfügt, mache ich mir hierzu aber
keine weiteren Sorgen.
Im Gegensatz zu Unix fehlt unter Windows ein richtiger Root-Process, der die User-Session gestartet hat. Der
Explorer-Prozess übernimmt zwar mehrheitlich diese Aufgabe, kann aber jederzeit beendet und neugestartet werden.
Ergo ist es schwierig über den Prozessbaum den gültigen Root-Prozess zu finden. Aus diesem Grunde versuche ich
mal mit diesem Workaround zu leben.
Christoph Schneider
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#7

AW: User-Spezifische Folder ermitteln wenn mit "Run als Administrator" gestartet wurd

  Alt 2. Sep 2011, 09:50
OK, das ist jetzt für Alice die den Installationsprozess angestoßen hat. Und was ist mit Benutzer Bob, der sich am nächsten Tag anmeldet und die Software nutzen will?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:31 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz