Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   CreateProcess - wie denn nun? (chkdsk.exe) (https://www.delphipraxis.net/160725-createprocess-wie-denn-nun-chkdsk-exe.html)

Schwedenbitter 27. Mai 2011 22:26

CreateProcess - wie denn nun? (chkdsk.exe)
 
Hallo,

ich bin gerade dabei, mich daran zu versuchen die Ausgabe von chkdsk in mein Programm umzuleiten (wie z.B. hier beschrieben).

Ich habe aber Probleme mit CreateProcess(). Ich habe neben meiner Testversion auch die Unit RedirectConsole.pas analysiert - in fast jedem Falls wird CreateProcess() unterschiedlich aufgerufen. Laut Deklaration in der Windows.pas (TurboDelphi) müsste es so richtig sein:
Delphi-Quellcode:
// - WORKAROUND begin ----------------------------------------------------------
{$I-}ChDir(CBDrv.Text + '\');{$I+}
// - WORKAROUND end ------------------------------------------------------------         GetSystemDirectory(lBuffer, BufferSize);
If (Not CreateProcess(
   PChar(StrPas(lBuffer) + '\chkdsk.exe'),   // <- lpApplicationName
   PChar(CBDrv.Text),                        // <- lpCommandLine
   nil, nil, True,
   CREATE_NO_WINDOW Or NORMAL_PRIORITY_CLASS, nil,
   nil,                                    // <- lpCurrentDirectory
   lStartI, lProcInfo)) Then
   MessageBox(Handle, PChar(SysErrorMessage(GetLastError)), 'Error: CreateProcess', mb_OK)

...
Rufe ich es aber so auf, erhalte ich als Fehlermeldung: "Windows kann kein Laufwerk überprüfen, das über das Netzwerk angeschlossen ist." Das liegt wohl daran, dass ich den Quelltext auf einem Netzlaufwerk bearbeite/compilieren lasse. Es klappt nur, wenn ich den o.g. Workaround mit laufen lasse.

Nach meinem Verständnis müsste es eigentlich egal sein, weil in
Delphi-Quellcode:
CBDrv.Text
z.B. 'C:' steht. Auch das Ersetzen von
Delphi-Quellcode:
  nil, // <- lpCurrentDirectory
durch
Delphi-Quellcode:
PChar(CBDrv.Text + '\') // <- lpCurrentDirectory
bringt bloß manchmal etwas. Zudem gebe ich doch oben dem Programm über lpCommandLine 'C:' mit, welches Laufwerk er scannen soll.
Wenn ich wiederum
Delphi-Quellcode:
If (Not CreateProcess(
   PChar(StrPas(lBuffer) + '\chkdsk.exe ' + CBDrv.Text),   // <- lpApplicationName
   nil,                                 // <- lpCommandLine
...
angebe, meckert mir Windows die "falsche" Syntax an.

[EDIT]
Am Ende geht es mir darum, wie ich den Parameter '/F' erfolgreich an chkdsk übergeben bekomme.
[/EDIT]

Wie ist es denn nun richtig?

Gruß, Alex

P.S. Bei Bedarf stelle ich auch den Quellcode rein.

jaenicke 28. Mai 2011 05:40

AW: CreateProcess - wie denn nun? (chkdsk.exe)
 
Liste der Anhänge anzeigen (Anzahl: 1)
Wie du in der Dokumentation nachlesen kannst, fehlt bei CommandLine bei dir der Name der Exe.

Davon abgesehen klappt das aber sowieso nicht, es sei denn dein Programm fordert vorher generell für sich Adminrechte an. Denn die brauchst du. Ansonsten würde ich zu ShellExecute + runas als Verb raten. ;-)

Alternativ kannst du auch die eigene Exe mit Adminrechten und einem entsprechenden Parameter starten und den Parameter im Projektquelltext auswerten.

Im Anhang eine kleine Demo für beide Wege. ;-)

Schwedenbitter 28. Mai 2011 08:45

AW: CreateProcess - wie denn nun? (chkdsk.exe)
 
Liste der Anhänge anzeigen (Anzahl: 1)
Danke erstmal für die Antwort.

Zitat:

Zitat von jaenicke (Beitrag 1103408)
Wie du in der Dokumentation nachlesen kannst, fehlt bei CommandLine bei dir der Name der Exe.

Entschuldigung! Das kommt davon, wenn man nur Codestücke schickt. Eine Zeile über CreateProcess() steht ein
Delphi-Quellcode:
GetSystemDirectory(lBuffer, BufferSize);
. Der Pfad ist nicht das Problem, denn sonst käme nicht die Fehlermeldung, dass chkdsk.exe nicht mit Netzwerklaufwerken umgehen könne.

Dass chkdsk.exe Admin-Rechte braucht, ist neu für mich und schade zugleich. Ich wollte eigentlich per Button dem Benutzer meines Programmes einen Check anbieten. Wenn der sich dann jedesmal als Admin anmelden muss, wird es unkomfortabel. Da sieht man mal wieder, wie Ottonormal-User unter XP ummer schön mit Adminrechten unterwegs ist...

Der Code von Dir hat ungelogen den Charme des kurzen. Aber ich brauche ein Handle, weil ich ja die Ausgaben in mein Programm umleiten will; Siehe erster Satz.

Ich habe es jetzt so hinbekommen:
Delphi-Quellcode:
If (Not CreateProcess(PChar(lS),         // <- lpApplicationName
   PChar(lS + ' ' + CBDrv.Text + '/F'),      // <- lpCommandLine
   nil, nil, True,
   CREATE_NO_WINDOW Or NORMAL_PRIORITY_CLASS,
   nil, nil, lStartI, lProcInfo)) Then
Aber da wiederhole ich in lpCommandLine den gesamten String aus lpApplicationName zzgl. der Parameter. Soll das wirklich so gewollt sein und wozu ist das denn gut, außer Hobby-Programmierer wie mich zur Verzweiflung zu treiben? Draufgekommen bin ich nach mehrmaligem Lesen im MSDN und der Methode trial and error... Ich habe mal den Code angehängt.

Gruß, Alex

jaenicke 28. Mai 2011 09:25

AW: CreateProcess - wie denn nun? (chkdsk.exe)
 
Zitat:

Zitat von Schwedenbitter (Beitrag 1103416)
Der Code von Dir hat ungelogen den Charme des kurzen. Aber ich brauche ein Handle, weil ich ja die Ausgaben in mein Programm umleiten will; Siehe erster Satz.

Das ist der Grund weshalb ich die Methode wie es mit CreateProcess und Adminrechten geht auch mit angegeben habe. ;-)

Zitat:

Zitat von Schwedenbitter (Beitrag 1103416)
Aber da wiederhole ich in lpCommandLine den gesamten String aus lpApplicationName zzgl. der Parameter. Soll das wirklich so gewollt sein und wozu ist das denn gut, außer Hobby-Programmierer wie mich zur Verzweiflung zu treiben? Draufgekommen bin ich nach mehrmaligem Lesen im MSDN und der Methode trial and error...

Du hast mich falsch verstanden, genau das meinte ich, als ich geschrieben habe, dass der Name der Exe fehlt.

Der Grund ist ganz einfach, dass in der Commandline die meisten Programme als ersten Parameter den Namen der eigenen Exe erwarten. Das muss aber nicht so sein. Wenn du ein Programm selbst schreibst, das das nicht braucht, musst du das nicht angeben, wenn du es aufrufst. ;-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:25 Uhr.

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