AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi in KommandozeilenAnwendung DOS-Befehl ausführen

in KommandozeilenAnwendung DOS-Befehl ausführen

Offene Frage von "Tyler"
Ein Thema von Tyler · begonnen am 24. Jul 2007 · letzter Beitrag vom 28. Jul 2007
Antwort Antwort
Seite 1 von 2  1 2   
Benutzerbild von Tyler
Tyler

Registriert seit: 19. Jun 2003
Ort: Berlin
241 Beiträge
 
#1

in KommandozeilenAnwendung DOS-Befehl ausführen

  Alt 24. Jul 2007, 22:30
Hallo,

hab schon n paar Seiten durchwühlt, aber noch keine Antwort gefunden. Ich will den Parameter, den meine Konsolenanwendung erhält, per Dos-Befehl "SET" in den Umgebungsvariablen speichern. Weiss aber nicht ansastzweise, wie ich vorgehen soll.

Habt ihr ne Idee?

Danke,

tyler
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#2

Re: in KommandozeilenAnwendung DOS-Befehl ausführen

  Alt 24. Jul 2007, 22:50
Hallo Tyler,

hast du diesen Thread schon gelesen?

Gruß Hawkeye
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.262 Beiträge
 
Delphi 2006 Professional
 
#3

Re: in KommandozeilenAnwendung DOS-Befehl ausführen

  Alt 24. Jul 2007, 23:10
Moin Tyler,

Dir muss dabei aber klar sein, dass Set nur im Kontext des aufrufenden Prozesses wirkt, dass heisst: Wird der Prozess (also Dein Konsolenprogramm) beendet, ist die Änderung weg. Das passiert, da beim Starten eines Programmes der neue Prozess ein Kopie des Environments des Aufrufers (in diesem Falle also der Konsole) bekommt. Es funktioniert nicht einmal, die Werte direkt in die Registry zu schreiben.

Einen groben Ansatz kann ich Dir geben (noch nicht ganz ausgereift, da er von einer festen Adresse bezüglich des Environmentblocks ausgeht, ausserdem darf das Environment nicht um soviel grösser werden, dass der Block neu zugewiesen werden muss, da sich sonst dessen Startadresse ändert.)

Diese Vorgehensweise geht davon aus, dass das Environment bei jeden Prozess immer an der gleichen Adresse beginnt, was, zumindest bis incl. XP, der Fall zu sein scheint.

Ermittle die Adresse Deines Environment-Blocks (geht sehr gut GetEnvironmentStringsW. Es muss die Widestring-Version sein, mit der Ascii-Version funktioniert es nicht).
Füge den neuen Environmentstring hinzu (SetEnvironmentVariableW).
Vergleiche die ermittelte Adresse mit der aktuellen. Stimmen die nicht überein: Schade, der Block wurde zu gross, und an eine neue Adresse verschoben, dass ist hier (nocht) nicht abgedeckt. Ansonsten kann es weiter gehen:

Ermittle den Parentprozess zu Deinem (CreateToolHelp32Snapshot).
Öffne diesen mit Schreibrechten (OpenProcess)
Ermittle mit VirtualQueryEx die MEMORY_BASIC_INFORMATION für den Environmenblock des Aufrufers.
Ändere mit VirtualProtectEx die Zugriffsrechte auf PAGE_READWRITE.
Kopiere Deinen Environmentblock in den des Aufrufers (WriteProcessMemory, Länge MEMORY_BASIC_INFORMATION.RegionSize)
Setze die Zugriffsrechte wieder zurück auf den Ursprungswert (VirtualProtectEx)
Jetzt noch alle Handle schliessen und fertig.

BTW:
Das ist nicht als Witz gemeint, unter 2000 und XP konnte ich das schon so machen (unter 2000 habe ich es auch schon mit Userrechten ausprobiert )

Einen Beispielcode könnte ich aber frühestens am Wochenende fertig bekommen.


Falls Dir das zu aufwändig ist:
Microsoft schlägt für die Lösung dieses Problems vor, dass man aus seinem Konsolenprogramm heraus eine Batchdatei mit dem entsprechenden Set-Kommando erstellt, die dann nach dem Konsolenprogramm per Call aufgerufen wird.


(Das ist übrigens genau das Problem, dass mich zu einem Forum gebracht hat )
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#4

Re: in KommandozeilenAnwendung DOS-Befehl ausführen

  Alt 24. Jul 2007, 23:32
Moin Chris,

in dem von mir verlinkten Thread verweist MathiasSimmack auf einen Beitrag im DF. Ich habe den dortigen Code zwar nicht getestet, aber er verspricht eine systemweite Änderung der Umgebungsvariablen.

Gruß Hawkeye
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.262 Beiträge
 
Delphi 2006 Professional
 
#5

Re: in KommandozeilenAnwendung DOS-Befehl ausführen

  Alt 24. Jul 2007, 23:55
Moin Hawkeye,

ich habe es gerade einmal getestet.
Eine neue Anwendung, im OnCreate des Formuales dann die Variable setzen.
Wie erwartet: Anschliessend stand die Variable in der Konsole nicht zur Verfügung.
Der Broadcast hilft einem da nicht, da er von der Konsole nicht verarbeitet wird.
Macht man eine neuen Konsole auf ist der Wert dann da, was einem, im Zuge einer Batchverarbeitung aber leider nicht weiterhilft.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Hansa

Registriert seit: 9. Jun 2002
Ort: Saarland
7.554 Beiträge
 
Delphi 8 Professional
 
#6

Re: in KommandozeilenAnwendung DOS-Befehl ausführen

  Alt 25. Jul 2007, 01:02
@Fragesteller : Erkläre mal bitte, warum eine Umgebungsvariable gesetzt werden MUSS. Geht das nicht anders, z.B. INI ? In einer Multitasking-Umgebung macht das SET tatsächlich wenig Sinn. Siehe Christians Vorlesung.
Gruß
Hansa
  Mit Zitat antworten Zitat
Benutzerbild von Tyler
Tyler

Registriert seit: 19. Jun 2003
Ort: Berlin
241 Beiträge
 
#7

Re: in KommandozeilenAnwendung DOS-Befehl ausführen

  Alt 25. Jul 2007, 08:07
Zitat von Hawkeye219:
Hallo Tyler,

hast du diesen Thread schon gelesen?

Gruß Hawkeye
tatsächlich... gabs das Problem schonmal. Aber den Thread hatte ich nicht gefunden, vielleicht weil ich nie nach "umgebungs variabeln" gesucht habe. Ich hab aber nach "EnvironmentVariable" gesucht.. seltsam. Egal, danke für den Link

@Christian
Vielen Dank, war mir bisher neu, dass Env-Variablen nur für eine CMD-Sitzung zählen. Allerdings würde mir das für den Anfang vielleicht schon reichen... denn:

@hansa
ich hatte gestern abend noch die fixe Idee, folgenden eigentlich einfachen Programmwunsch zu erfüllen

aus dem efb
Zitat:
Ausserdem eine Batch-Datei-Level-Lösung um (LFN) D:\Program Files\FirefoxPortable\FirefoxPortable.exe in path=D:\Program Files\FirefoxPortable\ LFN=FirefoxPortable.exe zerlegen zu können ("Filename X" kann das per GUI)
Da dacht ich mir folgendes:

Delphi-Quellcode:
var
 sPath, sFile : String;
begin
 sPath := ExtractFilePath( ParamStr(1) );
 sFile := ExtractFileName( ParamStr(2) );
 
 {
UND HIER DIE ENV-VAR SETZEN

SET PATH = sPATH
SET LFN = sFILE

}


end;
... tja, so einfach war das aber dann doch nich, wie man an dem Thread hier sieht

Vermutlich reicht es aber auch, wenn die EnvVar nur in der Sitzung zu Verfügung steht, weil sie ja gleich darauf wieder in einer Batch-Datei weiterverwendet wird. Nur, ist die Variable noch vorhanden, wenn ich meine Konsolenanwendung aus einer Batch ausrufe? Ne, oder? Weil meine Konsolenanwendung ja wieder in einer anderen Instanz als der, der Batch-Datei läuft? Hm...
  Mit Zitat antworten Zitat
Hansa

Registriert seit: 9. Jun 2002
Ort: Saarland
7.554 Beiträge
 
Delphi 8 Professional
 
#8

Re: in KommandozeilenAnwendung DOS-Befehl ausführen

  Alt 25. Jul 2007, 08:46
Zitat von Tyler:
..Nur, ist die Variable noch vorhanden, wenn ich meine Konsolenanwendung aus einer Batch ausrufe? Ne, oder? Weil meine Konsolenanwendung ja wieder in einer anderen Instanz als der, der Batch-Datei läuft? Hm...
Sie ist in der Instanz vorhanden und zwar ab dann, wenn sie gesetzt ist, auch innerhalb des BAT-Laufes. Sie kann also innerhalb der BAT abgefragt werden. Geht ein neues Konsolen-Fenster auf, dann muss sie wieder neu gesetzt werden, weil es eine andere Instanz darstellt.
Gruß
Hansa
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.262 Beiträge
 
Delphi 2006 Professional
 
#9

Re: in KommandozeilenAnwendung DOS-Befehl ausführen

  Alt 25. Jul 2007, 21:45
Moin Hansa,


Zitat von Hansa:
Sie ist in der Instanz vorhanden und zwar ab dann, wenn sie gesetzt ist, auch innerhalb des BAT-Laufes.
Falsch.
Sie ist nur innerhalb des Prozesses gültig, in dem sie gesetzt wird, und dessen Kindprozessen.
Die Konsole bekommt ihr Environment beim Start. Wird aus der Konsole heraus ein anderes Programm gestartet, so bekommt dieses nur ein e Kopie des Environments der Konsole, und kann darin Umgebungsvariablen setzen und löschen wie es gerade nötig ist.
Das Environment der Konsole wird dadurch in keinster Weise beeinflusst.

Wie schon geschrieben:
Microsoft sieht hier als Lösung nur das Erzeugen einer Batchdatei, die dann im Anschluss an das eigene Programm aufgerufen wird, damit die Umgebungsvariablen in der Konsole entsprechend gesetzt werden.
Und da ich nicht bereit war diese Lösung so zu akzeptieren, habe ich mir den anderen Weg überlegt


Zitat von Hansa:
Geht ein neues Konsolen-Fenster auf, dann muss sie wieder neu gesetzt werden, weil es eine andere Instanz darstellt.
Auch falsch
Startet man die Konsole aus einem eigenen Programm, z.B. per CreateProcess, kann sie das, sozusagen ganz normal, das eigene Environment als Kopie erhalten, wie schon oben beschrieben, indem man den Pointer auf einen Environment-Block weglässt, oder aber man baut ein Environment extra für den Aufruf zusammen, und übergibt dessen Pointer. Im ersten Falle würde die Konsole also die neu gesetzte Variable zur Verfügung haben, im zweiten hängt es davon ab, was man in den Block reinschreibt.
Wird die Konsole hingegen aus dem Explorer gestartet, und man hat die Variable so gesetzt, wie in dem verlinkten Beitrag beschrieben, steht der neuen Konsole die Variable zur Verfügung.

Allgemein:
Wird kein spezielles Environment für einen Kindprozess erstellt, so erbt dieser immer das Environment des Elternprozesses, und zwar als Kopie.
Wenn im Elternprozess, vor dem Start eines Kindprozesses, etwas am Environment geändert wird, sei es nun setzen, ändern oder löschen einer Variablen, so erhält der Kindprozess das geänderte Environment.

Einfach mal zum Ausprobieren.
Man nehmen ein Formular, einen Button, und folgenden Code:

Delphi-Quellcode:
uses shellapi;
{$R *.dfm}

procedure TForm1.btn1Click(Sender: TObject);
begin
  ShellExecute(0,'open','cmd.exe',nil,nil,SW_SHOWNORMAL);
  ShowMessage('Jetzt steht der Konsole das derzeitige System und Current-User Environment zur Verfügung.');
  SetEnvironmentVariable('NEUEVARIABLE','MIT EINEM WERT');
  ShellExecute(0,'open','cmd.exe',nil,nil,SW_SHOWNORMAL);
  ShowMessage('und jetzt ist etwas hinzugekommen');
end;
Sobald eine Konsole offen ist, einfach mal Set N eingeben.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Benutzerbild von Tyler
Tyler

Registriert seit: 19. Jun 2003
Ort: Berlin
241 Beiträge
 
#10

Re: in KommandozeilenAnwendung DOS-Befehl ausführen

  Alt 26. Jul 2007, 13:17
also wenn man ganz auf Nummer sicher gehen will, schreibt man die Variable wohl doch am Besten direkt in die Registry. Unter HLM/System/CurrentControlSet/Control/Session Manager/Enviroment werden die systemweiten Variablen gespeichert, und die lassen sich uach in jeder Konsole abrufen. ich denke, darauf werde ich dann zurückgreifen.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 12:38 Uhr.
Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf