설치 프로그램이 설치하는 파일의 버전 정보를 쿼리하고 실행중인 설치 프로그램에있는 동일한 파일의 버전 정보와 비교하려고합니다.런타임에 실행 파일에서 버전 정보 쿼리
- http://delphidabbler.com/articles?article=20
- How can i read details of file? : 세부 사항은 내가이 문제를 해결하기 위해는 Win32 API를보고 일부 샘플 코드처럼의 FileVersion 또는 PRODUCTVERSION 분야에서 아니지만 InternalName 등
같은 다른 분야에있을 수 있습니다
그러나 이러한 코드 샘플에 사용 된 일부 데이터 형식은 Inno Setup에서 작동하지 않습니다. 또한 일부 샘플 및 설명은 언어 및 코드 페이지 자체가 배열이되지만 일부 샘플에서는 언어 및 코드 페이지에 대해 하나의 항목 만 사용한다고 표시하는 것 같습니다. 언어 및 코드 페이지를 찾으려고 애썼지 만 아래 주석에 따라 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가 코드를 사용해 보셨습니까? –
실제로 필요한 것은 무엇입니까? 네 실행 파일 맞지? 그래서 당신은 리소스와 리소스에 어떤 언어와 코드 페이지가 사용되는지 알고 있습니다. –
어쩌면 질문을 더 분명하게하기 위해 실행 파일의 버전 정보를 덤프 할 수 있습니다. –