Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Lokalisierung: Name der geladenen Resource-DLL herausfinden? (https://www.delphipraxis.net/118655-lokalisierung-name-der-geladenen-resource-dll-herausfinden.html)

Deep-Sea 12. Aug 2008 11:01


Lokalisierung: Name der geladenen Resource-DLL herausfinden?
 
Hallöchen erstmal an euch alle ^^
Ich weiß, ich komme auch nur angeschleimt, wenn ich Hilfe brauche - böse von mir :mrgreen:

Ich habe folgendes Problem:

Ich will herausfinden, welche Resource-DLL Delphi geladen hat - genauer eigentlich nur welche Sprache. Jedoch behält die Funktion LoadResourceModule - die ya für das laden verantwortlich ist - das natürlich für sich. :roll:
Nun kann ich zwar mit FindResourceHInstance(HInstance) mir das Handle auf die Resource-DLL holen, was soweit ya auch klappt, aber GetModuleName bzw. GetModuleFileName bringen mir für das Handle einen leeren String zurück (was an der LoadLibraryEx Option LOAD_LIBRARY_AS_DATAFILE liegt).

Nun geistern mir noch verschiedene, mehr oder weniger unschöne und fehleranfällige Möglichkeiten im Kopf rum. Und bevor ich die nutze, wollte ich mal euren Rat einholen :lol:


Vielen Danke schon mal ...

blackdrake 12. Aug 2008 18:48

Re: Lokalisierung: Name der geladenen Resource-DLL herausfin
 
Ich habe bisher immer Sprachpakete mit INI-Dateien gehandelt. Mit Resource-DLLs habe ich noch nicht gearbeitet. Scheinbar stellen dir diese DLLs resourcestrings zur Verfügung, oder? Wäre das der Fall, dann könntest du doch einfach einen Resourcestring/Spracheintrag "language" abfragen, der dann die Sprache des Sprachpakets (German, English) beinhaltet. Vielleicht stellst du auch ein Feld mit Angabe des Übersetzers und der Revision zur Verfügung. Hilft dir der Ansatz etwas?

Gruß
blackdrake

helgew 12. Aug 2008 19:10

Re: Lokalisierung: Name der geladenen Resource-DLL herausfin
 
Oh da klemm ich doch mal dran. Ich denke du kannst mit NtQuerySystemInformation(...) die SYSTEM_HANDLE_INFORMATION gewinnen, das liefert dir ein Array aus records mit Informationen zu aktiven handles, von denen du dann die richtigen ( mit der gewünschten ProcessID ) rausfischen kannst und darauf prüfen, ob sie Module-handles sind und damit den Modulname bekommen.

OldGrumpy 12. Aug 2008 19:16

Re: Lokalisierung: Name der geladenen Resource-DLL herausfin
 
Warum verankerst Du nicht in der Resourcen-DLL eine Resource die den Namen der DLL trägt? :)

//Edith sagt: Heute ist nicht mein Tag, der Vorschlag steht oben schon mal :)

Zitat:

Zitat von helgew
Oh da klemm ich doch mal dran. Ich denke du kannst mit NtQuerySystemInformation(...) die SYSTEM_HANDLE_INFORMATION gewinnen, das liefert dir ein Array aus records mit Informationen zu aktiven handles, von denen du dann die richtigen ( mit der gewünschten ProcessID ) rausfischen kannst und darauf prüfen, ob sie Module-handles sind und damit den Modulname bekommen.

Das wäre doch nichts weiter als auf Umwegen das gleiche was schon im Ursprungspost als nicht funktionierend beschrieben wurde...

helgew 12. Aug 2008 20:15

Re: Lokalisierung: Name der geladenen Resource-DLL herausfin
 
Woah wenn ich schon wieder C-Code übersetzen muss, da könnte ich Bröckchen lachen...


Ich gebs auf. Hinweis siehe bisschen weiter unten..

Apollonius 12. Aug 2008 20:19

Re: Lokalisierung: Name der geladenen Resource-DLL herausfin
 
Weder HModules noch HWnds sind Handles von Kernel-Objekten. Ich bezweifle daher, dass sie in der Liste auftauchen.

helgew 12. Aug 2008 20:23

Re: Lokalisierung: Name der geladenen Resource-DLL herausfin
 
Dann muss man sich mal näher mit psAPI und Toolhelp32 auseinandersetzen. Stimmt, es kann sein, dass die so aufgezählten Handles nur die GDI-Handles sind

Apollonius 12. Aug 2008 20:28

Re: Lokalisierung: Name der geladenen Resource-DLL herausfin
 
:roll: GDI-Handles sind auch keine Handles von Kernel-Objekten. Es gibt drei Klassen von Handles: User, GDI und Kernel. HModules sind keine echten Handles sondern Zeiger.

helgew 12. Aug 2008 21:36

Re: Lokalisierung: Name der geladenen Resource-DLL herausfin
 
Boah... Wald vor lauter Bäumen nicht gesehen.. psAPI hat da was feines:

Delphi-Quellcode:
psAPI.EnumProcessModules(hProcess: THandle; lphModule: LPDWORD; cb: DWORD;
:wall:

wenn das klappt, müsstest du doch auch die FileNames bekommen :gruebel:
ok, msdn meint : "The EnumProcessModules function does not retrieve handles for modules that were loaded with the LOAD_LIBRARY_AS_DATAFILE flag." Es kann also sein, dass Windows gerade die für dich interessanten Infos in die Tonne haut, auf nimmerwiedersehn ;)

Eine Möglichkeit, dann etwas herauszufinden wären ShellNotify Infos, man kann sich ja benachrichtigen lassen, welche Dateien geöffnet und geladen werden. Dann hast du eine Art "debugging" ;)

OldGrumpy 12. Aug 2008 21:50

Re: Lokalisierung: Name der geladenen Resource-DLL herausfin
 
Zitat:

Zitat von helgew
Boah... Wald vor lauter Bäumen nicht gesehen..[...]

Delphi-Quellcode:
psAPI.EnumProcessModules(hProcess: THandle; lphModule: LPDWORD; cb: DWORD;

Zitat:

Zitat von Deep-Sea
[...]aber GetModuleName bzw. GetModuleFileName bringen mir für das Handle einen leeren String zurück (was an der LoadLibraryEx Option LOAD_LIBRARY_AS_DATAFILE liegt).

[Hervorhebung von mir]

Liest Du eigentlich auch mal was im Thread so geschrieben wird? Verifizierst Du Deine Vorschläge eigentlich mal?

helgew 12. Aug 2008 21:53

Re: Lokalisierung: Name der geladenen Resource-DLL herausfin
 
@OldGrumpy ja schande über mich... ich mach das nebenher, daher editiere ich meine Beiträge im Laufe der Zeit auch ein paarmal, siehe oben. ;)

Um meine Verpeiltheit wieder gut zu machen hier nun ein Vorschlag, um das ausgängliche Problem des Threadstellers zu illustrieren:
Delphi-Quellcode:
procedure EnumModulesOf(pid : Cardinal);
var
  hProcess: Cardinal;
  Modules: Array[0..65535] of hModule;
  cbNeeded:Cardinal;
  i: integer;
begin
  hProcess := OpenProcess(PROCESS_ALL_ACCESS,false,pid);
  if hProcess <> 0 then
  begin
    EnumProcessModules(hProcess,@Modules,65536,cbNeeded);
    if 65536 < cbNeeded div SizeOf(HModule) then writeln('Too many modules loaded. Not all modules will be displayed.');
    for i := 1 to cbNeeded div SizeOf(HModule)-1  do
    begin
      if _GetModuleFileName(Modules[i]) <> '' then
        writeln('  ',inttohex(Modules[i],8),' : ',_GetModuleFileName(Modules[i]))
      else
        writeln('  ',inttohex(Modules[i],8),' : unknown');
    end;
    CloseHandle(hProcess);
  end
  else
    writeln('could not open process #',pid);
  readln;
end;
in der Tat gibt es viele Module, die keinen Dateinamen haben, obwohl sie aufgelistet wurden

OldGrumpy 12. Aug 2008 22:00

Re: Lokalisierung: Name der geladenen Resource-DLL herausfin
 
Joah, ganz dolle. Natürlich kann man das Problem fast beliebig komplex lösen, aber wozu das? Oben im Thread gibts den ganz schlichten Vorschlag den Dateinamen innerhalb der Resourcen-DLL zu verankern, so steht er praktisch automatisch zur Verfügung. Warum dann noch unglaubliche Klimmzüge veranstalten? Weil man es kann? :roll:

helgew 12. Aug 2008 22:45

Re: Lokalisierung: Name der geladenen Resource-DLL herausfin
 
Mir ist auch nicht ganz klar, wass der Threadersteller mit
Delphi-Quellcode:
Ich will herausfinden, welche Resource-DLL Delphi geladen hat - genauer eigentlich nur welche Sprache.
meint. Ich hab dazu folgendes gefunden.
Damit kämen wir dann auch zu dem Vorschlag von OldGrumpy, einen Namensstring oder eine TellMyName() Funktion zu exportieren und das Problem wäre gelöst, oder?

marabu 13. Aug 2008 07:27

Re: Lokalisierung: Name der geladenen Resource-DLL herausfin
 
Hallo Chris,

Zitat:

Zitat von Deep-Sea
... Ich will herausfinden, welche Resource-DLL Delphi geladen hat - genauer eigentlich nur welche Sprache. ...

LoadLibraryEx() mit der Option LOAD_LIBRARY_AS_DATAFILE erzeugt effektiv einen memory mapped file. Du kannst dir den Namen also so besorgen:

Delphi-Quellcode:
function ResFileName(mmf: HMODULE; var fn: TFileName): Boolean;
var
  modName: array [0..MAX_PATH] of Char;
  n: Integer;
begin
  n := GetMappedFileName(GetCurrentProcess, Pointer(mmf), modName, SizeOf (modName));
  Result := n > 0;
  if Result then
    SetString(fn, modName, n);
end;
Freundliche Grüße

Deep-Sea 13. Aug 2008 07:34

Re: Lokalisierung: Name der geladenen Resource-DLL herausfin
 
Ich habs! :bounce1: [edit] Aber marabu war schneller :mrgreen: thx [/edit]
Die Lösung liegt in der Funktion GetMappedFileName (zu finden in der PsAPI).
Nett von MS, immer zu schreiben wie es nicht geht, aber nicht ein mal zu erwähnen wie es geht ...



Zitat:

Zitat von helgew
Mir ist auch nicht ganz klar, wass der Threadersteller mit
Delphi-Quellcode:
Ich will herausfinden, welche Resource-DLL Delphi geladen hat - genauer eigentlich nur welche Sprache.
meint. Ich hab dazu folgendes gefunden.
Damit kämen wir dann auch zu dem Vorschlag von OldGrumpy, einen Namensstring oder eine TellMyName() Funktion zu exportieren und das Problem wäre gelöst, oder?

Ich will nun einmal wissen, unter welcher Sprache meine Applikation läuft. Dies brauche ich für andere zu lokalisierende Dinge, die nicht in der Resource-DLL enthalten sind (Ordner mit Texten drin z.B.). :wink:
Die Funktion von deinem Link setzt zwar welche Sprache Delphi nutzen sollte, dass heißt aber noch lange nicht, dass er das auch tut. Existiert z.B. die angegebene Datei nicht oder kann nicht geladen werden, sucht er nach Dateien die der aktuellen "Thread-Sprache" (GetThreadLocale) entsprechen. Welche Datei nun letztendlich geladen ist, weiß man so nie.


Zu den Posts mit "String mit der Sprache in die Resource-DLL packen": Ya, sowas hatte ich auch schon im Kopf :-D ...



Nun ja, so klappt es ya doch noch wie gewünscht, danke an euch für eure Hilfe :P


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