Als erstes würde ich einen anderen Namen für die Funktion vorschlagen, da GetVersion() bekanntlich eine ältliche Kernel32-
API ist, die man nutzt um die Windowsversion zu ermitteln
Keine Ahnung was du mit dem Aufruf bezweckst, aber im
PSDK steht es ganz deutlich beschrieben. Und genau das scheinst du zu ignorieren. Es steht dort eindeutig, daß es sich um ein Array von DWORDs handelt. Was immer dich auch geritten hat dort eine komplett andere Struktur anzugeben, es ist falsch. Manchmal bringt es mich zum Grübeln, wenn du einerseits Leute im Forum zusammensch.... und andererseits selber nicht die Doku liest
... ich meine du schreibst Tutorials, willst anderen was beibringen. Klar kann nicht jeder alles wissen, aber die Doku lesen ...
Delphi-Quellcode:
function GetVersionInfo(
var VersionString, Description:
String): DWORD;
type
PDWORDArr = ^DWORDArr;
DWORDArr =
array[0..0]
of DWORD;
var
VerInfoSize: DWORD;
VerInfo: Pointer;
VerValueSize: DWORD;
VerValue: PVSFixedFileInfo;
LangInfo: PDWORDArr;
LangID: DWORD;
Desc: PChar;
s:
String;
i: Integer;
begin
result := 0;
VerInfoSize := GetFileVersionInfoSize(PChar(ParamStr(0)), LangID);
if VerInfoSize <> 0
then
begin
VerInfo := Pointer(GlobalAlloc(GPTR, VerInfoSize));
if Assigned(VerInfo)
then
try
if GetFileVersionInfo(PChar(ParamStr(0)), 0, VerInfoSize, VerInfo)
then
begin
if VerQueryValue(VerInfo, '
\', Pointer(VerValue), VerValueSize)
then
begin
with VerValue^
do
begin
VersionString := Format('
%d.%d.%d.%d', [dwFileVersionMS
shr 16, dwFileVersionMS
and $FFFF,
dwFileVersionLS
shr 16, dwFileVersionLS
and $FFFF]);
end;
end
else
VersionString := '
';
// Description
if VerQueryValue(VerInfo, '
\VarFileInfo\Translation', Pointer(LangInfo), VerValueSize)
then
begin
if (VerValueSize > 0)
then
begin
// Divide by element size since this is an array
VerValueSize := VerValueSize
div sizeof(DWORD);
// Number of language identifiers in the table
(********************************************************************)
for i:= 0
to VerValueSize-1
do
begin
// Swap words of this DWORD
LangID := (LoWord(LangInfo[i])
shl 16)
or HiWord(LangInfo[i]);
Writeln(Format('
Habe gefunden: %8.8x', [LangID]));
// Query value ...
if VerQueryValue(VerInfo, @Format('
\StringFileInfo\%8.8x\FileDescription', [LangID])[1], Pointer(Desc), VerValueSize)
then
Description := Desc;
end;
(********************************************************************)
end;
end
else
Description := '
';
end;
finally
GlobalFree(THandle(VerInfo));
end
else // GlobalAlloc
result := GetLastError;
end
else // GetFileVersionInfoSize
result := GetLastError;
end;
Wenn du GMEM_FIXED benutzt, brauchst du auch kein GlobalLock() - nur so nebenbei.
Du solltest dir auch klarmachen, daß es mehrere Blöcke geben kann. Deswegen ist es irrsinnig davon auszugehen, daß es nur einen gibt, wie du das in deinem Code zu tun schienst. Ich habe die FOR-Schleife oben hervorgehoben, damit du siehst was ich meine. Es macht also keinen Sinn irgendeinen Wert anzufordern ohne genau zu spezifizieren welchen du willst.
Ich würde dir empfehlen noch einen Parameter an die Funktion zu übergeben und dann auf diesen zu testen (innerhalb der FOR-Schleife und bevor du die Stringvariable Description belegst). Ansonsten als Standardwert 0 übergeben, sollte eigentlich gehen, hab's aber nicht getestet.