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/)
-   -   Delphi aus Registry Werten den Dateinamen und Pfad ermitteln (https://www.delphipraxis.net/92586-aus-registry-werten-den-dateinamen-und-pfad-ermitteln.html)

daPimP 22. Mai 2007 18:38


aus Registry Werten den Dateinamen und Pfad ermitteln
 
Folgendes Problem:

Bsp: Registry: HKLM....\CurrentVersion\Run\
  • Name..........Wert
    ---------------------------------------------
    LXBTCATS....rundll32 C:\WINDOWS\System32\spool\DRIVERS\W32X86\3\LXBTtim e.dll,_RunDLLEntry@16
    nwiz............nwiz.exe /install
    Tweak UI....RUNDLL32.EXE TWEAKUI.CPL,TweakMeUp
    MMTray.......MMTray.exe

Wie kann ich jetzt den Pfad rausbekommen?

Also C:\Windows\MMTray.exe
oder C:\WINDOWS\System32\spool\DRIVERS\W32X86\3\LXBTtim e.dll

Dazu muss es doch eine Function geben, die ich aber irgendwie noch nicht finden konnte.

Luckie 22. Mai 2007 19:04

Re: aus Registry Werten den Dateinamen und Pfad ermitteln
 
Nein, dafür gibt es keine Funktion. Es wird dir wohl nichts anderes übrigbliben als den String mit copy und pos selber zu zerlegen.

MathiasSimmack 22. Mai 2007 19:51

Re: aus Registry Werten den Dateinamen und Pfad ermitteln
 
Ich bin zu faul, das jetzt direkt auf Delphi umzubauen, aber im Rahmen eines kleinen Inno Setup-Projektes habe ich so was mal gemacht: klick. Es geht darum, den Uninstaller korrekt zu starten, und dazu gehört eben auch, dass man Programm und evtl. vorhandene Parameter ermittelt. Die Funktion heißt "SplitParameters". Müsste sich u.U. sogar 1:1 übernehmen lassen.

daPimP 22. Mai 2007 20:05

Re: aus Registry Werten den Dateinamen und Pfad ermitteln
 
Das kann ich so fast nicht glauben.
Denn um MMTray.exe zu starten, muss Windows ja irgendwo eine Verbindung zum Ordner herstellen können.

Falls du Recht hast, würde das dann so aussehen.
Es werden alle Umgebungsvariablen (also %system32% etc...)durchgespielt um das Verzeichnis zu ermitteln und Windows zerlegt dann auch immer den String? (Autoruns von SysInternals macht das dann wohl auch so)

Um an das Verzeichnis von MMTray.exe zu kommen, nutze ich folgenden Code:

Delphi-Quellcode:
function DateiOpen(Pfad: String): string;
var
  FileName,Directory: string;
  ExecuteFileName: array[0..Max_Path] of char;
  i: Integer;
begin
  FileName:=extractfilename(Pfad) ;        //'DirectX.log';
  Directory:= extractfilepath(Pfad) ;      //'C:\windows\';
  FillChar(ExecuteFileName, SizeOf(ExecuteFileName), ' ');

  SHELLAPI.FindExecutable(@FileName[1], @Directory[1], @ExecuteFileName[1]);

  result:= ExecuteFileName; //log - Dateien werden geöffnet durch C:\...notepad.exe
end;
Erklärung
Die Function macht nix anderes als zu schauen, wer diese Datei öffnet. Und da eine Exe sich selbst
öffnet, komme ich so auch an den Pfad ran.

@MathiasSimmack - schau ich mir mal an

MathiasSimmack 22. Mai 2007 20:12

Re: aus Registry Werten den Dateinamen und Pfad ermitteln
 
Zitat:

Zitat von daPimP
Denn um MMTray.exe zu starten, muss Windows ja irgendwo eine Verbindung zum Ordner herstellen können.

:shock: Da sprechen Leute, die DOS nicht kennen.

Die PATH-Variable sagt dir was? Umgebungsvariablen allgemein? Beispiel: MS-DOS-Eingabeaufforderung öffnen, "PATH" eintippen, ENTER und gucken. Alle Pfade, die hier aufgelistet werden, werden von Windows selbstständig nach einer Datei durchsucht.

Wobei "durchsuchen" nicht das richtige Wort ist. Wie du vermutest, wird bei der Eingabe eines Programms, etwa "notepad", jeder Pfad vorangestellt. Dann wird versucht, das Programm zu starten. Existiert etwa ein "C:\Windows\notepad.exe", dann öffnet sich der Editor. Wenn nicht, dann nimmt das System den nächsten Ordner, usw.

daPimP 22. Mai 2007 20:37

Re: aus Registry Werten den Dateinamen und Pfad ermitteln
 
Meine fehlerhafte Bezeichnung der Pfad-Variablen sehe ich mal eher als Lapsus.

Also hat Lucki wohl (leider) Recht. Nun gut.
Ich denke dann bleibt mir nix anderes übrig, als eine Funktion mit allem Wenn und Aber dafür selber basteln zu müssen.

Stellt im Prinzip kein Problem dar, aber immer dieser Zeitaufwand. Werde das Ergebnis dann hier posten.

@Mathias: Die Anzahl meiner Beiträge sollte nicht auf mein DOS-Wissen übertragen werden.

CLS
ECHO ON
ECHO DOS-Wissen, tut manchmal gut!
TYPE C:\DOS622\oldschool.txt

NicoDE 22. Mai 2007 21:17

Re: aus Registry Werten den Dateinamen und Pfad ermitteln
 
Die API-Funktion SearchPath erledigt die Suche in den relavanten Pfaden und bietet auch gleich einen Zeiger auf den Anfang des Dateinamens (praktisch wenn man ohnehin Pfad und Namen trennen will).
Zwar gibt es sicherlich Shell-Funktionen zum Zerlegen von o.g. Pfaden, allerdings müssen sie erstmal gefunden werden und dokumentiert sein (mir fällt im Moment keine ein).

daPimP 23. Mai 2007 23:35

Re: aus Registry Werten den Dateinamen und Pfad ermitteln
 
So, meine Lösung funktioniert soweit.

Ich habe den Code auskommentiert und ein OpenSourceProject daraus gemacht.

Hier der Link: OpenSource

Bild

Für faule hier ein Ausschnitt (Das Projekt laden= besser, weil macht die Sache auch recht anschaulich)

Delphi-Quellcode:
(*Prüft den String und versucht, den Klarpfad anzuzeigen*)
function DATEIOPEN(Pfad: String): string;
var
  FileName,Directory: string;
  ExecuteFileName: array[0..Max_Path] of char;
  i: Integer;
begin
  // Pfad-string zerlegen wenn möglich
  FileName:=extractfilename(Pfad) ;
  Directory:= extractfilepath(Pfad) ;
  FillChar(ExecuteFileName, SizeOf(ExecuteFileName), ' ');

  //FindExecutabel versucht die Datei zu finden - alles unter 32 ist ein Fehler
  if SHELLAPI.FindExecutable(@FileName[1], @Directory[1], @ExecuteFileName[0]) > 32 then
    result:= ExecuteFileName
  else //bei Fehler
    result:= 'failed';
end;


(*Dateien ohne Verzeichnis werden hier wieder hergestellt
  Bsp: aus Antivir - wird C:\Windows\System32\Antivir.exe
  oder aus rundll32 C:\WINDOWS\LXBTtime.dll,_RunDLLEntry@16 - wird C:\WINDOWS\LXBTtime.dll
  Falls Parameter existieren, werden diese an Parameters übergeben*)
function FileFromRegistry(Memo: TMemo; str: string; out Parameters: string): string;
var
    i, Quotestart, QuoteEnd: integer;
    InQuote     : boolean;
    Foundquotes : boolean;
    Sprungstelle : integer;
begin
 result:= str;
 //Datei im Klartext eingetragen
 if FileExists(result) then
   Exit;

 //Prüfe auf rundll32 oder rundll32.exe als loader
 if (Pos('rundll32', AnsilowerCase(str)) = 1) then begin
   if str[9]=' ' then
     str:= copy(str,10,length(str))
   else
     if (Pos('rundll32.exe', AnsilowerCase(str)) = 1) then
       if str[13]=' ' then
         str:= copy(str,14,length(str));
   result:= str;

   Memo.lines.add('rundll32 befreit: '+str);
   if FileExists(str) then
     Exit;
   //Prüfe ob Einsprungpunkt vorhanden (alles nach dem Komma)
   //Problem: Auch in Dateinamen dürfen Kommata vorkommen - ist aber unwahrscheinlich
   Sprungstelle:= Pos(',', str);
   if Sprungstelle >0 then begin
     str:= copy(str, 1, Sprungstelle-1);
     Memo.lines.add('Sprungstelle bereinigt: '+str);
   end;
 end;


 //Prüfe auf PATH-Variable (%...% und Verzeichnislose Konstrukte) (eventuelle PARAMETER noch nicht abgeschnitten)
 result:= DATEIOPEN(str);
 Memo.lines.add('DATEIOPEN (keine Parameterüberprüfung): '+result);
 if FileExists(Result) then
   Exit;


 //Prüfe auf Quotationmarks ("")
 InQuote   := false;
 QuoteStart := 0;
 QuoteEnd  := length(str);
 Foundquotes:= false;
          i := 0;
 while i <= length(str) do begin
   if str[i] = '"' then begin
     FoundQuotes:= true;
     if InQuote= false then
       QuoteStart:= i
     else
       QuoteEnd:= i;
     InQuote := not InQuote;
   end;

   if (str[i] = ' ') and (not Inquote) then begin
     break;
   end;
   inc(i);
 end;
 //eventuelle Parameter vom Dateinamen trennen
 Parameters := Copy(str, i + 1, length(str));
 //Wenn Anführungszeichen gefunden "..." - eleminieren, sonst nur von eventuellen Parametern trennen
 if Foundquotes= true then
   str := Copy(str, 1+QuoteStart, quoteEnd-QuoteStart-1)
 else
   str := Copy(str, 1, i-1);
 Memo.lines.add('Parameterbereinigt: '+str);

 result:= str;
 if FileExists(result) then
   Exit;

 //Prüfe NOCHMAL auf PATH-Variable (%...% und Verzeichnislose Konstrukte) (HIER PARAMETER abgeschnitten)
 result:= DATEIOPEN(str);
 Memo.lines.add('DATEIOPEN (Parameterbereinigt): '+result);

 if FileExists(Result) then
   Exit
 else
   result:= 'Datei nicht gefunden!';

(*weitere Gedanken zum optimieren und verbessern:*)
(*Die Funktion ProcessPath zerlegt einen Pfad in Laufwerksbuchstaben-, Verzeichnisnamen- und Dateinamen-Teile.*)
(*um an alle virtuellen ordner ranzukommen - ShGetSpecialFolderLocation*)
(*SearchPath wäre auch noch interessant*)
end;

MathiasSimmack 24. Mai 2007 05:57

Re: aus Registry Werten den Dateinamen und Pfad ermitteln
 
Zitat:

Zitat von daPimP
@Mathias: Die Anzahl meiner Beiträge sollte nicht auf mein DOS-Wissen übertragen werden.

Die Anzahl deiner Beiträge habe ich jetzt erst gesehen, nachdem du mich darauf aufmerksam gemacht hast. :roll: Ich beurteile nur nach dem, was ich lese. Und das gab mir in deinem Fall zu denken.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:08 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