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 Ressourcen mit WinAPI laden (https://www.delphipraxis.net/72892-ressourcen-mit-winapi-laden.html)

3_of_8 8. Jul 2006 19:13


Ressourcen mit WinAPI laden
 
Morgen. Ich bastel grade für mich ein Programm, das ein JAR als Textressource hat und das dann beim Ausführen abspeichert und ausführt.

Da habe ich jetzt folgendes Problem: Momentan nutze ich noch nen TResourceStream, der allerdings mit Classes ordentlich auf die Dateigröße schlägt.

Daher wäre WinAPI deutlich effizienter.

Allerdings blicke ich bei LoadResource nicht ganz durch. Momentan sieht das ganze so aus:

(Buffer ist ein PChar)

Buffer:=Pointer(LoadResource(HINSTANCE, FindResource(HINSTANCE,
'jardata', 'text')));

Das ganze gibt keine AccessViolation, daher scheint Buffer zumindest mal nicht ins Speichernirvana zu zeigen. Allerdings ist Buffer bei Ausgabe in ner MessageBox leer.

marabu 8. Jul 2006 19:41

Re: Ressourcen mit WinAPI laden
 
Hallo Manuel,

LoadResource() liefert ein Handle und keinen Pointer. Die korrekte Reihenfolge der benötigten API Funktionen kannst du u.a. in der Demo sehen, welche ich an Beitrag #4 angehängt habe.

Grüße vom marabu

3_of_8 8. Jul 2006 19:45

Re: Ressourcen mit WinAPI laden
 
Hmm, ich habe es mal selber rumprobiert und hab meinen Code nach so abgeändert:

Delphi-Quellcode:
program JavaLaunch;

{$R 'jardata.res'}

uses
   Windows,
  ShellAPI,
  Classes;

var f: HFILE;
     Path, FileName: array[0..Max_Path] of char;
     hRes : HRSRC;
     hGlob : HGLOBAL;
      Buffer: String;
    dummy: DWORD;
    fstruct: _OFSTRUCT;
begin
  try
    hRes:=FindResource(HINSTANCE,'jardata', 'text');
    setlength(Buffer, SizeOfResource(HINSTANCE, hRes));
    hGlob:=LoadResource(HINSTANCE, hRes);
    Buffer:=String(PChar(LockResource(hGlob)));
  except
    on EResNotFound do exit;
  end;
  GetTempPath(Max_Path,Path);
  GetTempFileName(Path, '~tm', 0, FileName);
  Path:='C:\';
  FileName:='C:\blubb.jar';
  fstruct.cBytes:=sizeof(fstruct);
  f:=OpenFile(@FileName[0], fstruct, OF_WRITE);
  WriteFile(f, buffer, length(buffer), dummy, nil);
  CloseHandle(f);
  ShellExecute(0, 'open', 'java', PChar('-jar '+FileName), Path, 0);
end.
Was ist daran falsch? Buffer ist nur 4 Bytes lang und die Datei wird gar nicht geschrieben.

Der_Unwissende 8. Jul 2006 22:13

Re: Ressourcen mit WinAPI laden
 
Hi,

Zitat:

Zitat von 3_of_8
Delphi-Quellcode:
  try
    hRes:=FindResource(HINSTANCE,'jardata', 'text');
Was ist daran falsch?

Also ich würde sagen schon diese Zeile. Das letzte Argument von FindResource sollte der Typ der Ressource sein, 'text' ist eigentlich kein wirklich vordefinierter Typ. Wenn ich also die Größe (in Byte) eines 4 Zeichen Strings betrachte, erklärt es dir vielleicht schon einiges (ohne jetzt den Rest anzuschauen)

Gruß Der Unwissende

marabu 8. Jul 2006 22:16

Re: Ressourcen mit WinAPI laden
 
Überlege mal: seit wann ist ein JAR-File eine Text-Resource? Schau dir dein JAR-File mal mit einem HEX-Editor an - alles bis zum ersten low value (#0) ist dein String.

marabu

mkinzler 8. Jul 2006 22:21

Re: Ressourcen mit WinAPI laden
 
Zitat:

Überlege mal: seit wann ist ein JAR-File eine Text-Resource?
Ne JAR-Datei ist ein Zip-Archiv.

3_of_8 8. Jul 2006 23:17

Re: Ressourcen mit WinAPI laden
 
ARGH

Ich hab nicht an das nullterminierte gedacht.

Übrigens: Mit RCDATA funktionierts gar nicht mehr.

Olli 9. Jul 2006 00:55

Re: Ressourcen mit WinAPI laden
 
Uralt und funzt immernoch:
Delphi-Quellcode:
function ExtractResTo(Instance: hInst; BinResName, NewPath, ResType: string):
  boolean;
(*******************************************************************************
 Function:  ExtractResTo
 Returns:   Boolean (true=success)
 Version:   Function version 3.0

 Parameters
 Instance:  is the instance handle of the module containing the resource. if not
             current module, use LLoadLibrary() and FreeLibrary() to load and free
             the module containing the resource.
 BinResName: is the name of the resource to extract. this would even work with
             icons, cursors, texts, yaddayadda ...
 NewPath:   path of the file to create from the resource (where to put the
             file)
 ResType:   resource type. pre-defined values can be found in Windows.pas
             e.g. RT_RCDATA
 *******************************************************************************)
var
  ResSize,
    HG,
    HI,
    SizeWritten,
    hFileWrite: Cardinal;
begin
  result := false;
  HI := FindResource(Instance, @binresname[1], @ResType[1]);
  if HI <> 0 then begin
    HG := LoadResource(Instance, HI);
    if HG <> 0 then
    try
      ResSize := SizeOfResource(Instance, HI);
      hFileWrite := CreateFile(@newpath[1], GENERIC_READ or GENERIC_WRITE,
        FILE_SHARE_READ or FILE_SHARE_WRITE, nil, CREATE_ALWAYS,
        FILE_ATTRIBUTE_ARCHIVE, 0);
      if hFileWrite <> INVALID_HANDLE_VALUE then
      try
        result := (WriteFile(hFileWrite, LockResource(HG)^, ResSize,
          SizeWritten, nil) and (SizeWritten = ResSize));
      finally
        CloseHandle(hFileWrite);
      end;
    except;
    end;
  end;
end;
siehe auch hier und Hier im Forum suchenExtractResTo sowie Hier im Forum suchenPutBinResTo ...

Übrigens sind selbst Delphi-Strings (AnsiString, LongString, WideString) keine nullterminierten Zeichenketten, somit ist es absolut irrelevant für die Funktion ob die zu extrahierenden Daten nun Text sind oder nicht. Man kann sich auch gut vorstellen eine Liste von nullterminierten Strings als Ressource einzubinden, oder?!
Auch für Strings habe ich schon vor Jahren was geschrieben, finde es aber im Moment nicht. Ist aber sowieso nur eine Modifikation des ursprünglichen Codes der obigen Funktion gewesen.

Übrigens lautet die Konstante ja auch: RT_RCDATA, nur mal so ...

Denn wie wir alle wissen ist RT_RCDATA wie folgt deklariert:
Code:
#define RT_RCDATA          MAKEINTRESOURCE(10)
oder delphianisch:
Delphi-Quellcode:
const RT_RCDATA = PChar(10);

himitsu 9. Jul 2006 01:55

Re: Ressourcen mit WinAPI laden
 
Und wenn ich mir das richtig gemerkt hab, dann sind Strings (TEXT) in den Resourcen anders definiert, als der Rest ... nämlich als ResourcenTabellen.

jeweils 16 Strings
der erste Teil des Identifier's ist sozusagen für die Tabelle und die niedrigsten 4 Bit für den String in det Tabelle.


Also, selbst wenn man es schaft per TEXT an etwas anderes ranzukommen, wäre es eh inkompatibel ;)

Olli 9. Jul 2006 11:54

Re: Ressourcen mit WinAPI laden
 
Zitat:

Zitat von himitsu
[...] Also, selbst wenn man es schaft per TEXT an etwas anderes ranzukommen, wäre es eh inkompatibel ;)

Das ist wohl wahr. Ich meinte aber eher eingebettete Textdateien (z.B. für die Aboutbox - Luckie benutzte da was von mir - für Lizenztexte usw.), die ja auch wie Binärdateien behandelt werden, wenn man es nur von daher sieht wie sie eingebunden werden.


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