DLL verzió lekérdezés
2021-04-02T16:33:14+02:00
2021-04-03T16:40:26+02:00
2022-08-12T01:50:30+02:00
pluszs
Sziasztok!
Egy régebben 32 bites környezetre megírt DLL-t kívánnék "átírni" 64 bites verzióra az EMBARCADERO-t használva erre. A DLL elkészült, azzal nincs is gond. Viszont a 32 bites DLL verzióját le tudom kérdezni a "GetFileVersionInfoSize" majd a "GetFileVersionInfo" híváspárossal. A 64 bites verzióban (bár hozzá van - ahhoz is - téve a verziószám,) már az első hívás is hibára fut. A hiba kódja: 1813 (A megadott erőforrástípus nem található a programkódban.) Ha az első hívást kihagyom, és egy naaaaagy puffert biztosítva neki, meghívom a "GetFileVersionInfo"-t, akkor is ilyen hibával utasít vissza.
Kérlek segítsetek, hogy hol, mit kellene tennem, hogy a 64 bites DLL verzióját is le lehessen kérdezni.
Nyugodtan telő, vírusmentes húvéti ünnepeket kívánok nektek.
Mutasd a teljes hozzászólást!
Ez azt jelenti, hogy a powershell a jó értéket adja vissza?

Csinálsz egy új Dynamic Library project-et, és egy új Application projectet, mindenben a default értéket hagyd meg, és lefordítod win64 platformra, akkor jól lefut? (Nekem RS10.3.3 alatt igen)

Itt a méret miatt kivettem a SysUtils és a Classes unitokat.

library Project2; {$R *.res} begin end. unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); var Prg : string; Size, Handle : DWord; Buffer: TBytes; FixedPtr: PVSFixedFileInfo; S : string; begin Prg := ParamStr(0); Prg := 'Project2.dll'; Size := GetFileVersionInfoSize(PChar(Prg), Handle); if Size = 0 then RaiseLastOSError; SetLength(Buffer, Size); if not GetFileVersionInfo(PChar(Prg), Handle, Size, Buffer) then RaiseLastOSError; if not VerQueryValue(Buffer, '', Pointer(FixedPtr), Size) then RaiseLastOSError; S := Format('%s %d.%d.%d.%d (%s)', [Prg, LongRec(FixedPtr.dwFileVersionMS).Hi, // major LongRec(FixedPtr.dwFileVersionMS).Lo, // minor LongRec(FixedPtr.dwFileVersionLS).Hi, // release LongRec(FixedPtr.dwFileVersionLS).Lo, // build {$IFDEF WIN32} 'Win32' {$ENDIF} {$IFDEF WIN64} 'Win64' {$ENDIF} ]); ShowMessage(S); end; end.
Mutasd a teljes hozzászólást!

  • Bizonyára más DLL-eket is kipróbáltál, azokkal sikerült?
    Mutasd a teljes hozzászólást!
  • Nem próbáltam. Hogy tudom egy (más) meglévő DLL-ről azt, hogy 64 bites-e vagy 32 bites?
    Mutasd a teljes hozzászólást!
  • A "C:\WINDOWS\SysWOW64\aadtb.dll" (már ha 64 bites) rendben válaszol.
    Mutasd a teljes hozzászólást!
  • A C:\windows\syswow64 alatt mindenki 32-bites. Viszont ha a programod tudja kezelni ezeket a fájlokat, akkor a programod is 32-bites.
    A 64-bites fájlok a c:\windows\system32-ben vannak. De csak akkor, ha 64-bites program kérdezi. (Ezt a kavarást a Microsoft felhasználóbarát megkönnyítésnek nevezi.)

    PS: Ha van WSL a gépen, akkor egyszerű megtudni az igazat:

    $ file /mnt/c/windows/system32/ws2_32.dll /mnt/c/windows/syswow64/ws2_32.dll /mnt/c/windows/system32/ws2_32.dll: PE32+ executable (DLL) (console) x86-64, for MS Windows /mnt/c/windows/syswow64/ws2_32.dll: PE32 executable (DLL) (console) Intel 80386, for MS Windows
    Mutasd a teljes hozzászólást!
  • Hmm. Mi az a "WSL"? A programom amivel lekrdezem az 64 bites, de melyiket kérdezzem le?
    Mutasd a teljes hozzászólást!
  • Ha a C:\windows\system32\ws2_32.dll az 64 bites, azt le tudom kérdezni.
    Mutasd a teljes hozzászólást!
  • Itt egy "egyszerűbb" módszer a bitek meghatározására: valamilyen fájlnézegetővel (vagy akár notepad-dal) nézd meg az exe vagy dll elejét, ha van benne olyan, hogy PE..d, akkor 64-bites, ha PE..L van, akkor 32-bites.
    Mutasd a teljes hozzászólást!
    Csatolt állomány
  • Hát a C:\windows\system32\ws2_32.dll valóban 64 bites, és le tudom kérdezni. Nyilván (??) az EMBARCADERO valamilyen beállítását rontom el, pedig (melléklet) "bizony isten" beletettem. Próbáltam a DLL mezőt kipipálva, anélkül, nincs különbség.
    Mutasd a teljes hozzászólást!
    Csatolt állomány
  • A powershell-ben a "(Get-Command C:\PATH\FILENAME.dll).FileVersionInfo.FileVersion" mit ad vissza?

    Ha jót, akkor a lekérdezésed rossz, ha nem jót, akkor a dll.

    EMBARCADERO valamilyen beállítását rontom el

    A default beállítással működnie kell.
    Mutasd a teljes hozzászólást!
  • Ez az a bizonyos kódrész:

    exenam := 'C:\windows\system32\ws2_32.dll';
    dwi := GetFileVersionInfoSizeW(PChar(exenam), dwj);
    exenam := 'C:\EMBARCADERO\GENKEY\LNGKEY.dll';
    dwi := GetFileVersionInfoSizeW(PChar(exenam), dwj);

    A dwj és dwi Dword típus. Az első esetben rendben fut, a második esetben a hibakód a már említett 1813. (Ha elírom a nevet akkor persze 2.)
    Mutasd a teljes hozzászólást!
  • Ez azt jelenti, hogy a powershell a jó értéket adja vissza?

    Csinálsz egy új Dynamic Library project-et, és egy új Application projectet, mindenben a default értéket hagyd meg, és lefordítod win64 platformra, akkor jól lefut? (Nekem RS10.3.3 alatt igen)

    Itt a méret miatt kivettem a SysUtils és a Classes unitokat.

    library Project2; {$R *.res} begin end. unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); var Prg : string; Size, Handle : DWord; Buffer: TBytes; FixedPtr: PVSFixedFileInfo; S : string; begin Prg := ParamStr(0); Prg := 'Project2.dll'; Size := GetFileVersionInfoSize(PChar(Prg), Handle); if Size = 0 then RaiseLastOSError; SetLength(Buffer, Size); if not GetFileVersionInfo(PChar(Prg), Handle, Size, Buffer) then RaiseLastOSError; if not VerQueryValue(Buffer, '', Pointer(FixedPtr), Size) then RaiseLastOSError; S := Format('%s %d.%d.%d.%d (%s)', [Prg, LongRec(FixedPtr.dwFileVersionMS).Hi, // major LongRec(FixedPtr.dwFileVersionMS).Lo, // minor LongRec(FixedPtr.dwFileVersionLS).Hi, // release LongRec(FixedPtr.dwFileVersionLS).Lo, // build {$IFDEF WIN32} 'Win32' {$ENDIF} {$IFDEF WIN64} 'Win64' {$ENDIF} ]); ShowMessage(S); end; end.
    Mutasd a teljes hozzászólást!
  • Köszi az útmutatást.
    Ha nem is a problémára mutattál rá, de a megoldásra rávezettél.
    Csináltam egy próba DLL-t, és azt simán kezelte a GetFileVersionInfoSize.
    No, hamar belemásoltam a saját forrásomat, (simán csak Copy-Paste) ettől megint nem kezelte.
    De akkor már el kezdtem szőrözni, hogy ezek szerint a forrás soraiban van a probléma.
    Aztán a végére meg is találtam, bár "nem hiszem el", hogy az volt a gond.
    Az "exports" leírás előtt (ami után a belépő hívások nevei vannak) hiányzot a "{$R *.res}" sor.
    Annyira nem hittem el, hogy visszamentem az eredeti DLL forrásába, és beleírtam, hát láss csudát, onnantól lekérdezhető lett. Ha //-t tettem elé, akkor megint nem volt sikeres a hívás.
    Még most sem hiszem el, de a probléma megoldva.
    Még egyszer köszi az útmutatást.
    Mutasd a teljes hozzászólást!
  • Szívesen.

    "nem hiszem el", hogy az volt a gond, ... hiányzot a "{$R *.res} sor"

    A hiányzó sor miatt a fordító nem linkelte be a resource filet (amiben a FileVersionInfo van), emiatt amikor a program megpróbálta elérni, akkor az általad írt hibaüzenet jelentkezett.
    Mutasd a teljes hozzászólást!
abcd