Einzelnen Beitrag anzeigen

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, 22: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