2009-07-08 3 views
1

기존 패키지를 조건부로 업그레이드하기위한 설치 패키지를 개발하려고합니다. 설치할 소프트웨어 버전과 기존 소프트웨어 버전을 비교하고 싶습니다. 이를 위해서는 버전 문자열을 비교해야합니다.Inno Setup Script에서 문자열 버전 값을 숫자 값으로 변환하는 방법은 무엇입니까?

어떻게 Inno 설정 스크립트에서 문자열 값을 숫자 값으로 변환 할 수 있습니까?

RegQueryStringValue(HKEY_LOCAL_MACHINE, 'Software\Blah blah', 'Version', version) 
version = 'V1.R2.12'; 
numVersion := ??string_to_numerical_value??(version); 
+0

마지막으로 비교 한 번호 (.12)가 있습니까? 'R'은 릴리스를 의미한다고 가정하면 하나의 빌드 번호 만 연결되므로 솔리드 릴리스 프로세스가있는 경우이를 무시할 수 있습니다. – Treb

답변

4

'V1.R2.12'및 'V0.R15.42'와 같은 버전을 올바르게 처리하려는 경우 조금 더 까다 롭습니다. 다른 대답에서 간단한 변환을 사용하면 1212와 1542를 얻을 수 있습니다. , 그것은 당신이 기대하는 방식을 비교하지 않을 것입니다.

버전 번호의 각 부분의 크기를 결정하고 해당 값을 곱하여 올바른 끝 번호를 가져와야합니다. 이런 식으로 뭔가 :

[Code] 
function string_to_numerical_value(AString: string; AMaxVersion: LongWord): LongWord; 
var 
    InsidePart: boolean; 
    NewPart: LongWord; 
    CharIndex: integer; 
    c: char; 
begin 
    Result := 0; 
    InsidePart := FALSE; 
    // this assumes decimal version numbers !!! 
    for CharIndex := 1 to Length(AString) do begin 
    c := AString[CharIndex]; 
    if (c >= '0') and (c <= '9') then begin 
     // new digit found 
     if not InsidePart then begin 
     Result := Result * AMaxVersion + NewPart; 
     NewPart := 0; 
     InsidePart := TRUE; 
     end; 
     NewPart := NewPart * 10 + Ord(c) - Ord('0'); 
    end else 
     InsidePart := FALSE; 
    end; 
    // if last char was a digit the last part hasn't been added yet 
    if InsidePart then 
    Result := Result * AMaxVersion + NewPart; 
end; 

는 다음과 같은 코드를 사용하여이 문제를 테스트 할 수 있습니다 : 당신이 AMaxVersion 10, 100 또는 1000를 전달하는

function InitializeSetup(): Boolean; 
begin 
    if string_to_numerical_value('V1.R2.12', 1) < string_to_numerical_value('V0.R15.42', 1) then 
    MsgBox('Version ''V1.R2.12'' is not as recent as version ''V0.R15.42'' (false)', mbConfirmation, MB_OK); 
    if string_to_numerical_value('V1.R2.12', 100) > string_to_numerical_value('V0.R15.42', 100) then 
    MsgBox('Version ''V1.R2.12'' is more recent than version ''V0.R15.42'' (true)', mbConfirmation, MB_OK); 
    Result := FALSE; 
end; 

는 버전 번호 부품의 수와 범위에 따라 달라집니다. 최대 값이 2^32 - 1 인 LongWord 결과 변수를 오버플로해서는 안됩니다.

0

나는 것을 시도하지 않은 (내 파스칼 지식이 약간 녹슨입니다)하지만, 다음과 같이 작동합니다 :

function NumericVersion(s: String): Integer; 
var 
    i: Integer; 
    s1: String; 
begin 
    s1 := ''; 
    for i := 0 to Length(s)-1 do 
    if (s[i] >= '0') and (s[i] <= '9') then 
     s1 := s1 + s[i]; 

    Result := StrToIntDef(s1, 0); 
end; 

당신이 함께 플레이해야하지하시기 바랍니다 i에 대한 시작 및 끝 값으로, 0부터 시작하는지 여부는 확실하지 않습니다 (s[0]은 "파스칼 문자열"인 경우 문자열의 길이를 포함 할 수 있음).

+0

파스칼 스트링은 하나의 기반을 가지고 있지만, 고정되어 있더라도 해결책은 코너 경우에는 실패합니다. 제 대답을보십시오. – mghie

+0

당신은 물론 맞습니다 - 저는 OP를 올바른 방향으로 향하고 싶었습니다. 내 솔루션이 문제를 전적으로 처리 할 것이라고 기대하지 않았다 ;-) 나에게 답을 줄 때 upvote를 얻을 것이다. –

0

복잡성을 극복하기 위해 레지스트리에 두 개의 버전 문자열 (실제로 하나의 문자열과 하나의 DWORD 값)을 구현했습니다.

displayversion="v1.r1.0" 
version="10100" (=1*10^4 + 1*10^2 + 0*10^0) 

간단합니다. 그러나이 질문에 대한 대답은 아니지만, 단순한 방법으로 피할 수있는 복잡성에 직면했을 때 다른 방향으로 생각할 수도 있습니다.

관련 문제