![]() |
Interface implementieren...
Hallo,
ich versuche immer noch meine Klasse für die 'FileInfo' zu erstellen. Hier ein Teil des Codes:
Delphi-Quellcode:
Kann jemand helfen? Ich versuche die File info im Konstruktor in die Variable 'StandardKeys' zu schreiben...
unit Versioninfo;
interface uses Types,windows,SysUtils; type TVersionInfo=class private FStandardKeys:array[0..9] of String; // Beinhaltet Alle FileInfos function GetVersioninfo(Index: Integer): String; function GetKey(KeyName: String): String; procedure SetVersionInfo(const Index: Integer; const Value: String); function GetBuildNumber: String; public constructor Create (ThisSourceFile: String); destructor Destroy; override; property Key[KeyName: String]: String read GetKey; property CompanyName: String index 0 read GetVersionInfo write SetVersionInfo; property FileDescription: String index 1 read GetVersionInfo; property FileVersion: String index 2 read GetVersionInfo; property InternalName: String index 3 read GetVersionInfo; property Copyright: String index 4 read GetVersionInfo; property TradeMarks: String index 5 read GetVersionInfo; property OriginalFileName: String index 6 read GetVersionInfo; property ProductName: String index 7 read GetVersionInfo write SetVersionInfo; property ProductVersion: String index 8 read GetVersionInfo write SetVersionInfo; property Comments: String index 9 read GetVersionInfo; property BuildNumber: String read GetBuildNumber; // Hier versuche ich auf die Eigenschaften zuzugreifen. Leider schlägt das Kompilieren fehl: // [Error] Versioninfo.pas(35): Incompatible types property StandardKeys[index: Integer]: String read GetVersionInfo write SetVersionInfo; end; implementation { TVersionInfo } const MaxVersionKeys= 9; constructor TVersionInfo.Create(ThisSourceFile: String); const VersionkeyNames: array[0..MaxVersionKeys] of String = ('CompanyName', 'FileDescription','FileVersion','InternalName','Copyright','TradeMarks', 'OriginalFileName','ProductName','ProductVersion','Comments'); var ThisInfo: Integer; InfoLength: UInt64; Len, Handle: DWord; PCharset: PLongint; LangCharset: String; InfoAvailable: Boolean; begin inherited Create; // Get size of version info Len:= GetFileVersionInfoSize(PChar(ThisSourceFile),Handle); // Allocate VersionInfo buffer size SetLength(VersionInfo, Len+1); //Get version info if GetFileVersionInfo(PChar(ThisSourceFile), Handle,Len,Pointer(VersionInfo)) then begin if VerQueryValue(Pointer(VersionInfo),'\VarFileInfo\Translation', Pointer(PCharSet),Len)then begin LangCharset:= Format('%.4x%.4x',[LoWord(PCharset^),HiWord(PCharset^)]); InfoAvailable:= true; for ThisInfo:=0 to MaxVersionKeys do begin // Hier sollen die Informationen übernommen werden... StandardKeys[ThisInfo]:= GetKey(VersionKeyNames[ThisInfo]); end; end; end; end; destructor TVersionInfo.Destroy; begin inherited; end; function TVersionInfo.GetBuildNumber: String; begin end; function TVersionInfo.GetKey(KeyName: String): String; var begin end; function TVersionInfo.GetVersioninfo(Index: Integer): String; begin result:= FStandardKeys[Index] end; procedure TVersionInfo.SetVersionInfo(const Index: Integer; const Value: String); begin FStandardKeys[Index]:= Value; end; end. |
Re: Interface implementieren...
Ich habe jetzt mal schnell eine alte Funktion
![]() ![]() Evtl. kommst du mit einer ähnlichen Methode besser weg. Sprich: Aus dem Constructor würde ich den Code rausnehmen und lieber auslagern und dann die Properties gleich zuweisen. Ohne diesen Umweg über das Array "FStandardKeys". |
Re: Interface implementieren...
Hi,
nett von Dir aber ich möchte es auf diese Weise implementieren. Kannst Du zu meinem Code etwas sagen? Wo liegt mein Fehler? |
Re: Interface implementieren...
Ich wollte dich keinesfalls in deinem Eifer bremsen. Wenn du mich nach deinem Code fragst, dann muss ich gestehen, dass ich den Sinn der Zeile
Zitat:
Ich habe eben mal auf der Basis deiner Unit eine Klasse zusammengezimmert, die sowohl mit einzelnen Strings als auch mit einem String-Array arbeitet (Compilerswitch). Was soll ich sagen? Keine Probleme. btw: Das einzige, das mir im Moment wirklich als Problem auffällt, ist "Copyright". Das müsstest du in "LegalCopyright" ändern (im VersionkeyNames-Array), sonst liest du alles mögliche aus, aber nicht das Copyright. ;) |
Re: Interface implementieren...
Hallo,
ich habe deine Einwände bedacht und geändert. Kannst Du mir die 'zusammengezimmerte Klasse' einmal zeigen? Ich habe Probleme das so zu verstehen... Danke! |
Re: Interface implementieren...
Delphi-Quellcode:
:mrgreen: Ich hoffe, du kommst mit den Compilerschaltern klar. Im Moment werden die einzelnen Strings benutzt. Willst du mit dem String-Array arbeiten, dann entferne den Punkt in der Zeile
unit VersionInfo;
{.$DEFINE USEARRAY} interface uses Windows, SysUtils; type TVersionInfo=class private FInfo : PVSFixedFileInfo; {$IFDEF USEARRAY} FInfoKeys : array[0..9]of string; {$ELSE} FCompanyName, FFileDescription, FFileVersion, FInternalName, FCopyright, FTrademarks, FOriginalFileName, FProductName, FProductVersion, FComments, {$ENDIF} FVersionNumber : string; function FormatVersionNumber: string; {$IFDEF USEARRAY} function GetKey(Idx: integer): string; {$ENDIF} public constructor Create(const SourceFile: string); procedure LoadProperties(const SourceFile: string); {$IFDEF USEARRAY} property CompanyName: string index 0 read GetKey; property FileDescription: string index 1 read GetKey; property FileVersion: string index 2 read GetKey; property InternalName: string index 3 read GetKey; property Copyright: string index 4read GetKey; property Trademarks: string index 5 read GetKey; property OriginalFileName: string index 6 read GetKey; property ProductName: string index 7 read GetKey; property ProductVersion: string index 8 read GetKey; property Comments: string index 9 read GetKey; {$ELSE} property CompanyName: string read FCompanyName; property FileDescription: string read FFileDescription; property FileVersion: string read FFileVersion; property InternalName: string read FInternalName; property Copyright: string read FCopyright; property Trademarks: string read FTrademarks; property OriginalFileName: string read FOriginalFileName; property ProductName: string read FProductName; property ProductVersion: string read FProductVersion; property Comments: string read FComments; {$ENDIF} property VersionNumber: string read FVersionNumber; end; implementation {$IFNDEF USEARRAY} function GetFileInfo(const FileName, BlockKey: string): string; var vis, dummy : dword; vi, translation, ip : pointer; begin Result := ''; vis := GetFileVersionInfoSize(pchar(FileName),dummy); if(vis > 0) then begin GetMem(vi,vis); try GetFileVersionInfo(pchar(Filename),0,vis,vi); if(vi = nil) then exit; // get language code VerQueryValue(vi,'\\VarFileInfo\\Translation',translation,vis); if(translation = nil) then exit; ip := nil; VerQueryValue(vi, pchar(Format('\\StringFileInfo\\%.4x%.4x\\%s', [LOWORD(longint(translation^)),HIWORD(longint(translation^)), BlockKey])),ip,vis); if(ip = nil) then exit; SetString(Result,pchar(ip),vis - 1); finally FreeMem(vi); end; end; end; {$ENDIF} function GetDefaultFileInfo(const FileName: string): PVSFixedFileInfo; var vis, dummy : dword; vi : pointer; begin Result := nil; vis := GetFileVersionInfoSize(pchar(FileName),dummy); if(vis > 0) then begin GetMem(vi,vis); try GetFileVersionInfo(pchar(FileName),0,vis,vi); if(vi = nil) then exit; VerQueryValue(vi,'\\',pointer(Result),dummy); finally FreeMem(vi); end; end; end; // -- TVersionInfo ------------------------------------------------------------- constructor TVersionInfo.Create(const SourceFile: string); begin inherited Create; self.LoadProperties(SourceFile); end; procedure TVersionInfo.LoadProperties(const SourceFile: string); {$IFDEF USEARRAY} const DefaultInfoKey : array[0..9]of string = ('CompanyName','FileDescription','FileVersion','InternalName', 'LegalCopyright','TradeMarks','OriginalFileName','ProductName', 'ProductVersion','Comments'); var vis, dummy : dword; vi, translation, ip : pointer; i : integer; {$ENDIF} begin {$IFDEF USEARRAY} vis := GetFileVersionInfoSize(pchar(SourceFile),dummy); if(vis > 0) then begin GetMem(vi,vis); try GetFileVersionInfo(pchar(SourceFile),0,vis,vi); if(vi = nil) then exit; // get language code VerQueryValue(vi,'\\VarFileInfo\\Translation',translation,vis); if(translation = nil) then exit; for i := low(DefaultInfoKey) to high(DefaultInfoKey) do begin ip := nil; VerQueryValue(vi, pchar(Format('\\StringFileInfo\\%.4x%.4x\\%s', [LOWORD(longint(translation^)),HIWORD(longint(translation^)), DefaultInfoKey[i]])),ip,vis); if(ip = nil) then FInfoKeys[i] := '' else SetString(FInfoKeys[i],pchar(ip),vis - 1); end; finally FreeMem(vi); end; end; {$ELSE} // fill properties FCompanyName := GetFileInfo(SourceFile,'CompanyName'); FFileDescription := GetFileInfo(SourceFile,'FileDescription'); FFileVersion := GetFileInfo(SourceFile,'FileVersion'); FInternalName := GetFileInfo(SourceFile,'InternalName'); FCopyright := GetFileInfo(SourceFile,'LegalCopyright'); FTrademarks := GetFileInfo(SourceFile,'TradeMarks'); FOriginalFileName := GetFileInfo(SourceFile,'OriginalFileName'); FProductName := GetFileInfo(SourceFile,'ProductName'); FProductVersion := GetFileInfo(SourceFile,'ProductVersion'); FComments := GetFileInfo(SourceFile,'Comments'); {$ENDIF} FInfo := GetDefaultFileInfo(SourceFile); FVersionNumber := self.FormatVersionNumber; end; function TVersionInfo.FormatVersionNumber: string; const FormatStr = '%d.%d.%d.%d'; begin Result := Format(FormatStr, [(FInfo^.dwFileVersionMS and $FFFF0000) shr 16, FInfo^.dwFileVersionMS and $0000FFFF, (FInfo^.dwFileVersionLS and $FFFF0000) shr 16, FInfo^.dwFileVersionLS and $0000FFFF]); end; {$IFDEF USEARRAY} function TVersionInfo.GetKey(Idx: integer): string; begin Result := FInfoKeys[Idx]; end; {$ENDIF} end.
Delphi-Quellcode:
Ach so, ein Beispiel vllt. noch, damit du weißt warum ich das Laden der Properties in eine separate Funktion gepackt habe:
{.$DEFINE USEARRAY}
Delphi-Quellcode:
btw: Weil du das
procedure TForm1.Button1Click(Sender: TObject);
var vi : TVersionInfo; begin vi := TVersionInfo.Create('c:\pctools\smc.exe'); try Memo1.Lines.Add(vi.CompanyName); Memo1.Lines.Add(vi.VersionNumber); Memo1.Lines.Add(''); vi.LoadProperties('c:\pctools\hed.exe'); Memo1.Lines.Add(vi.ProductName); Memo1.Lines.Add(vi.Copyright); finally FreeAndNil(vi); end; end; ![]() |
Re: Interface implementieren...
Hallo,
ich dachte Du hast das nach meinem Quellcode implementiert? Ich verfüge bereits über Beispiele, wie man die Info ermittelt. Ich würde gern wissen wo mein Fehler in meinem Quellcode liegt! Hast Du da einen Tip? Quellcode: ![]() |
Re: Interface implementieren...
Natürlich war deine Unit die Grundlage. Bloß warum soll ich deine Fehler übernehmen? Ich hab´s so gestaltet, dass es für mich einfach zu handhaben war. Außerdem hast du mir immer noch nicht die Frage beantwortet, warum du unbedingt das String-Array als öffentliche Eigenschaft haben willst. Welchen Sinn soll das machen?
|
Re: Interface implementieren...
Hallo,
das habe ich bereits entfernt. Ich verstehe, dass du wenig Arbeithaben willst aber mein Ziel ist es nicht anderen Code zu übernehmen sondern meinen zum Laufen zu kriegen... Der Fehler steckt im Aufruf im Konstruktor:
Delphi-Quellcode:
Ich denke die Wahl meiner Parameter und deren Initialisierung ist falsch. Ich weiß nur nicht was falsch ist. Auch nach durchsicht deines Codes habe ich den Fehler noch nicht gefunden.
... // Diese liefert mir immer false, obwohl Informationen vorhanden sind.
if VerQueryValue(Pointer(ThisSourceFile),'\VarFileInfo\Translation', Pointer(PCharSet),Len) then begin //LangCharset:= Format('%.4x%.4x',[LoWord(PCharset^),HiWord(PCharset^)]); InfoAvailable:= true; ... |
Re: Interface implementieren...
Ich finde das wirklich gut, dass du es allein hinbekommen willst. Das ist mehr, als manch andere wollen. Aber andererseits: Ich habe meine Umsetzung erst absichtlich nicht gepostet, eben weil du es selbst machen wolltest. Dann hast du darum gebeten, und ich hab sie dir gezeigt.
Und da ich keine Probleme mit dem Auslesen der Versionsnummer habe, und weil ich notgedrungen die gleichen Befehle verwenden muss wie du (logisch, oder? ;)), spricht IMHO nichts dagegen, wenn du dir einfach mal nur diesen Teil meiner Umsetzung ansiehst. Genauer gesagt: Ich habe das Rückgabeergebnis von "VerQueryValue" ignoriert und stattdessen geschaut ob meine pointer-Variable ungleich nil ist.
Delphi-Quellcode:
Wie gesagt, Null Probleme.
VerQueryValue(vi,
pchar(Format('\\StringFileInfo\\%.4x%.4x\\%s', [LOWORD(longint(translation^)),HIWORD(longint(translation^)), BlockKey])),ip,vis); if(ip = nil) then exit; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:38 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