![]() |
fehlende Rechte nach EXE start auf WIN7
Hallo zusammen,
ich bin nicht sicher, ob dies hier die richtige Rubrik ist .. Ich habe: (1) Eine Startroutine zur aktualisierung einer lokalen Installation meines Programmes, Diese ist mit einem Manifest ausgestattet, so daß diese mit Admin-Privilegien gestartet wird. --> Das klappt, die Startroutine kopiert evt. Updates problemlos ohne Fehler. (2) Ein Programm, welche von der Startroutine (nach dem Updaten) mittels CreateProcess gestartet wird --> das klappt auch. Nach dem Start des Programmes wird die Startroutine (1) beendet. Beim CreateProcess sind die process security attributes und thread security attributes jeweils nil, also müsste ich die Sicherheitsrichtlinien der Startroutine für das neue gestartete Programm übernehmen. Nun das Problem: Wenn auf einem Win7 Rechner jedoch das Programm (2) auf eine Datei mit den Attributen versteckt und schreibgeschützt zugreifen möchte, so klappt das nicht ("Datei nicht gefunden"). Wird das Programm (2) direkt durch einen Doppelklick gestartet, geht alles wunderbar. Ebenfalls problemlos ist der Programmstart auf XP Rechner. Ob eine Datei da ist oder nicht prüfe ich mittels GetFileAttributes wie z.B. in ![]() beschrieben. Mir scheint es so zu sein, daß beim Programmstart über die Startroutine der Benutzerkontext und damit die Berechtigungen verschwinden - allerdings nur bei Win7. Liegt es daran, daß die Startroutine beendet wird und dadurch dieser Kontext verschwindet? Wenn ja - wie starte ich das Programm dann ohne dieses Problem aus der Startroutine heraus? Hat jemand einen Vorschlag, wie ich der Sache auf den Grund gehen kann? Danke. Ach ja: Ich arbeite hier mit D7 |
AW: fehlende Rechte nach EXE start auf WIN7
Wie sieht denn dein CreateProcess aus?
Ich vermute ein Pfadproblem. Worauf genau da versucht wird zuzugreifen usw. siehst du am einfachsten im Process Monitor von Sysinternals / Microsoft. |
AW: fehlende Rechte nach EXE start auf WIN7
Guten Morgen Jaenicke,
den Aufruf von CreateProcess habe ich hier abgeguckt: ![]() Bei mir sieht das so aus:
Delphi-Quellcode:
Die Funktion liegt in einer Singelton Unit und wird auch für andere Zwecke verwendet.
procedure TRMGlobFuncUniversal.ExecuteFile(
const AFilename: String; AParameter, ACurrentDir: String; AWait: Boolean; AOnWaitProc: TExecuteWaitEvent); var si: TStartupInfo; pi: TProcessInformation; bTerminate: Boolean; lokParameter, lokFilename : string; begin bTerminate := False; if Length(ACurrentDir) = 0 then ACurrentDir := ExtractFilePath(AFilename); if AnsiLastChar(ACurrentDir) = '\' then Delete(ACurrentDir, Length(ACurrentDir), 1); FillChar(si, SizeOf(si), 0); with si do begin cb := SizeOf(si); dwFlags := STARTF_USESHOWWINDOW; wShowWindow := SW_NORMAL; end; FillChar(pi, SizeOf(pi), 0); lokParameter := Trim(AParameter); lokFilename := Trim(AFilename); // Format('"%s"', [AFilename]); AParameter := Format('"%s" %s', [AFilename, TrimRight(AParameter)]); if CreateProcess( // Nil, PChar(AParameter), PChar(lokFilename), // pointer to name of executable module PChar(''), // pointer to command line string Nil, // pointer to process security attributes Nil, // pointer to thread security attributes False, // handle inheritance flag CREATE_DEFAULT_ERROR_MODE or CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, // creation flags Nil, // pointer to new environment block PChar(ACurrentDir), // pointer to current directory name si, // pointer to STARTUPINFO pi // pointer to PROCESS_INFORMATION ) then try if AWait then while WaitForSingleObject(pi.hProcess, 50) <> Wait_Object_0 do begin if Assigned(AOnWaitProc) then begin AOnWaitProc(pi, bTerminate); if bTerminate then TerminateProcess(pi.hProcess, Cardinal(-1)); end; Application.ProcessMessages; end; finally CloseHandle(pi.hProcess); CloseHandle(pi.hThread); end; end; Der Aufruf sieht so aus:
Delphi-Quellcode:
wobei PfadPASExeLok als Property in der aufrufenden Unit definiert ist:
RMFuncUniversal.ExecuteFile(PfadPASExeLok, '', ExtractFilePath(PfadPASExeLok), False, nil);
Delphi-Quellcode:
Der Pfad zur EXE ist korrekt, das Programm wird auch gestartet. Es gibt eben dann
property PfadPASExeLok : string read FPfadPASExeLok write FPfadPASExeLok;
nach dem Aufruf de Programmes aus der Startroutine heraus im Programm bei Dateizugriff den Fehler "Datei nicht gefunden". Die Dateien, auf die zugegriffen wird, liegen auf einem Netzwerklaufwerk und sind Teil eines Archivsystems. Der Pfad wird aus einer Datenbank (FB2.5) ausgelesen und ist dort "hart" incl. LW-Buchstaben belegt. Die entsprechende Netzwerkverbindung ist angemeldet und funktioniert, das ist schon daran zu erkennen, daß bei einem Direktaufruf (Doppelklick auf die EXE) das ganze fehlerfrei läuft. |
AW: fehlende Rechte nach EXE start auf WIN7
Zitat:
Die Exe liegt unter c:\program files bzw. c:\programme? Und der Pfad, den du nutzt, lautet c:\programme\...? Da c:\programme auf c:\program files umgeleitet wird, funktioniert der Start durchaus. Eigene Dateizugriffe aber nicht. Kann das so etwas sein? Wenn das Delphi 7 bereits unterstützt, kannst du in den Debugger-Optionen die Option "Debug in Spawned-Prozessen" aktivieren um nach dem Start der Exe weiter zu debuggen. Alternativ kannst du auch die Exe mit externen Debugsymbolen kompilieren und dich dann mit "Start --> Mit Prozess verbinden..." mit dem Debugger einklinken. Dafür ist es am einfachsten direkt nach das begin in der .dpr Projektdatei diese Zeilen einzufügen und danach einen Haltepunkt zu setzen:
Delphi-Quellcode:
Wenn das alles nicht funktioniert, bleiben noch Process Explorer um das Arbeitsverzeichnis usw. zu prüfen und der Process Monitor um die Dateizugriffe zu sehen und zu prüfen.
while not IsDebuggerPresent do // Unit Windows wird benötigt
Sleep(100); |
AW: fehlende Rechte nach EXE start auf WIN7
gelöscht
|
AW: fehlende Rechte nach EXE start auf WIN7
Ich bin nicht sicher, ob wir hier wirklich ein Pfadproblem haben.
Hier nochmals das "Kondensat" der Umgebung (a) OS <= WinXP Die Startroutine liegt auf einem Netzpfad und kopiert die notwendigen Programmdateien lokal. Dabei wird zwar auch u.U. einiges in das Windowsverzeichnis kopiert (z.B. DLL), aber das eigentliche Programm kommt in das Programmverzeichnis - meist also in C:\Programme\RMPAS Von dort wird es auch im CreateProcess gestartet (property PfadPASExeLok). (b) Win7 64bit Wie bei (a) liegt die Startroutine im Netz. Damit das Kopieren funktioniert wird diese mit Admin Rechten aufgerufen (Manifest). Das Kopieren klappt auch problemlos. Das eigentliche Programm liegt dann (typischer Weise) in C:\Program Files (x86)\RMPAS und wird von dort auch gestartet. Beim Belegen des Properties PfadPASExeLok wird mittels SHGetSpecialFolderLocation und CSIDL_PROGRAM_FILES der Programmpfad vom System abgefragt und dann um das Installationsverzeichnis der Anwendung erweitert (\RMPAS). Das Debuggen muß ich noch ausprobieren. Aus oben genanntem Zusammenhang heraus ich bin jedoch skeptisch, ob ich hier fündig werden. Irgendwie kennt Win7 beim Aufruf der Exe aus der Startroutine heraus die Benutzerrechte bzw. die Netwerkpfade nicht mehr ... |
AW: fehlende Rechte nach EXE start auf WIN7
Ja, den Zusammenhang, dass du eingangs von Adminrechten gesprochen hast und beim letzten Post von Netzwerkpfaden hatte ich übersehen. :oops:
Es ist so, dass ein Programm ebenfalls Adminrechte hat, wenn es von einem anderen Programm mit Adminrechten gestartet wird. Netzlaufwerke sind aber im Adminkontext nicht vorhanden, wenn sie nicht auch für das Admintoken des Users angelegt sind. Deshalb machen eigentlich alle Update oder Installationsprogramme das so, dass die Anwendung danach mit normalen Rechten gestartet wird. Ich selbst habe das in meinem (leider nicht mehr weiterentwickelten) ![]() Normale Installer machen das natürlich anders, diese ermitteln den Benutzerkontext und starten die Anwendung mit diesen Privilegien. In Inno Setup solltest du sehen können wie das geht, das ist ja Open Source. |
AW: fehlende Rechte nach EXE start auf WIN7
Noch allgemeiner formuliert: Netzlaufwerke sind seit Windows XP nutzerspezifisch (bei Win2k zwar ebenfalls, aber noch nicht so strikt getrennt wie bei XP+). D.h. jeder Nutzer hat seine eigenen Netzlaufwerke, so dass man bei Geschichten wie RunAs darauf achten muss. Das wäre dir übrigens auch aufgefallen, wenn du den Nutzerwechsel unter XP ebenfalls gemacht hättest - was nebenbei gesagt eine gute Idee wäre, denn momentan liest sich das so, als gingest du davon aus, dass der Nutzer Adminrechte hat...
MfG Dalai |
AW: fehlende Rechte nach EXE start auf WIN7
Zitat:
Aber das ist glaube ich nicht das Problem hier. Gruß, Chris [EDIT] Is doch immer mal wieder gut, sein vermeintliches Wissen zu überprüfen. Die Aussage bzgl. Windows 8 / 8.1 stimmt nur wenn man die Netzlaufwerke per ![]() ![]() [/EDIT] |
AW: fehlende Rechte nach EXE start auf WIN7
Danke für die Tipps an alle.
@Dalai ich hatte bereits Nutzerwechsel im XP und im Win7 und unter W2K (ja - das tuckert auch noch manchmal :wink:) gemacht. Ergebnis: es gibt nur beim Win7 das geschilderte Problem. Mittels procexp.exe habe ich nun mir die Properties der EXE nach dem Aufruf aus der Startroutine heraus angeschaut und mit denen nach Aufruf per Doppelklick verglichen. Ergebnis: a) in beiden Fällen ist der richtige User angegeben. @Dalai: dies gilt auch nach Userwechsel für unterschiedliche User. b) beim Aufruf per Doppelklick ist als Parent "explorer.exe" angegeben, beim Aufruf aus der Startroutine ist als Parent die Exe der Startroutine angegeben. Wenn man den Startvorgang im procexp.exe beobachtet "hängt" die Programm-Exe als Prozess zuerst unter dem Prozess der Startroutine. Dann beendet sich die Startroutine und die Programm-Exe ist auf die oberste Ebene der Prozesshirachie verschoben. Ich würde daher gerne die Programm-Exe aus der Startroutine mit dem parent "explorer.exe" starten. Kann mir jemand sagen, wie das gehen könnte? Danke. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:38 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