インストーラがインストールするファイルのバージョンの詳細を問い合わせて、実行中のインストーラに存在する同じファイルのバージョンの詳細と比較しようとしています。実行時の実行ファイルからのバージョン情報の照会
- http://delphidabbler.com/articles?article=20
- How can i read details of file? :詳細は、私がこれを解決するためのWin32 APIを見ても、いくつかのサンプルコードのようなファイルバージョンやPRODUCTVERSIONフィールドではありませんが、InternalNameなど
のような他の分野にすることができ
ただし、これらのコードサンプルで使用されているデータタイプの一部は、Inno Setupでは動作しません。さらに、いくつかのサンプルおよび説明は、言語およびコードページ自体が配列であるが、一部のサンプルでは、言語およびコードページのエントリが1つしかないと仮定して使用することを示しているようである。 私は言語とコードページを見つけようとしていましたが、以下のコメントに基づいて、en-usのためにそれをハードコードしました。
私はInno Setup Pascalのコードサンプルがあるthis答えを参照していますが、lplpBufferCP変数に基づいていない言語とコードページの計算では、その正確性が疑わしいです。
Inno Setup Pascalスクリプトから汎用バージョン情報のプロパティを読み取ることはできますか?もしそうなら、言語とコードページの値を見つける方法について助けてください。
上記の解決策に基づいて私が書いたコードを、問題のある部分のインラインコメントとともに以下に示します。
#ifdef UNICODE
#define AW "W"
#else
#define AW "A"
#endif
function GetFileVersionInfoSize(lptstrFilename: String; lpdwHandle: Integer): Integer;
external 'GetFileVersionInfoSize{#AW}@version.dll stdcall delayload';
function GetFileVersionInfo(lptstrFilename: String; dwHandle, dwLen: Integer; var lpData: Byte): Boolean;
external 'GetFileVersionInfo{#AW}@version.dll stdcall delayload';
function VerQueryValue(var pBlock: Byte; lpSubBlock: String; var lplpBuffer: Byte; var puLen: Integer): Boolean;
external 'VerQueryValue{#AW}@version.dll stdcall delayload';
function GetFileVersionProperty(const FileName, PropertyName: String): String;
var
VerSize: Integer;
VerInfo: array of Byte;
Dummy: Integer;
InternalNameArr: array of Byte;
begin
Result := '';
if not FileExists(FileName) then
begin
Log('File ' + FileName + ' does not exist');
Exit;
end;
VerSize := GetFileVersionInfoSize(FileName, 0);
if not VerSize > 0 then
begin
Log('File ' + FileName + ' has no version information');
Exit;
end;
SetArrayLength(VerInfo, VerSize);
if not GetFileVersionInfo(FileName, 0, VerSize, VerInfo[0]) then
begin
Log('Failed to get version info for ' + FileName);
Exit;
end;
if not GetFileVersionInfo(FileName, 0, VerSize, VerInfo[0]) then
begin
Log('Failed to get version info for ' + FileName);
Exit;
end;
{ Getting 'Version size = 2156' }
Log(Format('Version size = %d', [VerSize]));
{ Hard coded value just for testing }
SetArrayLength(InternalNameArr, 512);
{ 040904E4 hard coded for en-us }
{ Is this the correct way of querying the details ? }
{ If not, what needs to be done here }
{ TODO : InternalName hard coded. Use parameter PropertyName }
if VerQueryValue(VerInfo[0], '\StringFileInfo\040904E4\InternalName', InternalNameArr[0], Dummy) then
begin
Log('Failed to query internal name of ' + FileName);
Exit;
end
else
begin
{ What needs to be done here to convert an array of byte to string ? }
{ Do I need to iterate over the array and do the conversion ?}
{ The following does not work because of SetString() being unavailable : }
{ InternalName = SetString(AnsiStr, PAnsiChar(@InternalNameArr[0]), Len);}
{ Getting 'ProductName = 0000' and 'Dummy = 0' }
Log(Format('ProductName = %d%d', [InternalNameArr[0], InternalNameArr[1], InternalNameArr[2], InternalNameArr[3]]));
Log(Format('Dummy = %d', [Dummy]));
end;
{ TODO : Populate Result with appropriate value }
end;
別のアプローチは、(私は、ファイルの1の1つの特性に興味を持っています)レジストリ内のインストールされたファイルのファイルプロパティを保存することで、新しいファイルのために静的にインストーラで利用可能なプロパティを持つことができます。
@Jens A. Kochさんがコードを試しましたか? –
実際に必要なのは何ですか?あなたの実行ファイルですよね?だからあなたはそのリソースにどのような言語とコードページが使用されているのか知っていますか? –
質問をより明確にするために、実行可能ファイルのバージョン情報のダンプを表示することができます。 –