2012-06-21 7 views
36

In meiner INNO Setup RUN Auswahl erzwinge ich die automatische Installation von MSVCRT. Ich frage mich, wie man es selbst installieren kann, wenn es noch nicht installiert ist?Wie wird vcredist_x86 nur dann neu installiert, wenn es noch nicht installiert wurde?

Das ist, was ich jetzt:

Filename: {tmp}\vcredist_x86.exe; Parameters: "/passive /Q:a /c:""msiexec /qb /i vcredist.msi"" "; StatusMsg: Installing 2010 RunTime... 
+1

Etwas Ähnliches wurde gebeten, [ 'hier'] (http://stackoverflow.com/q/10982468/960757) jedoch Ich stimme der Antwort nicht zu, da es das Framework beim Start des Assistenten installiert, aber IMO sollte es ausgeführt werden, wenn Sie die letzte * Next * -Schaltfläche drücken und die Installation beginnt.Ich werde versuchen, die für diese Überprüfung erforderlichen Registrierungseinträge zu finden. In der Zwischenzeit werfen Sie einen Blick auf ['this post'] (http://stackoverflow.com/a/10111173/960757). Sie müssen dafür den Parameter '' Check'' '(http://www.jrsoftware.org/ishelp/topic_scriptcheck.htm) verwenden. – TLama

Antwort

83

Da Sie nicht wollen, was eine minimale Version von Visual C sagen ++ verteilbare Paket, das Sie benötigen, ist hier Sie den Code Probe haben, von dem Sie diese bauen können dein eigenes. Bitte beachten Sie, dass ich keine Ahnung habe, welche Versionen kompatibel sind mit welchen und welche niedrigeren Versionen installiert werden müssen, ich werde dies auf Sie anwenden.

Das einzige, was ich Ihnen sagen kann, ist, dass Sie unbedingt bedingten Parameter Check verwenden sollten, die Lösungen versuchen, das Framework oder Laufzeitbibliotheken zu installieren, wenn der Assistent geöffnet wird, sind falsch. Dieser bedingte Parameter funktioniert wie bei der Rückgabe von True, die Datei wird installiert, bei False wird sie übersprungen. Sie müssen daher die Funktion "Wahr" auf VCRedistNeedsInstall zurückgeben, wenn Sie Ihre Laufzeitbibliotheken installieren möchten, andernfalls "Falsch". Die Hilfsfunktion VCVersionInstalled, die Konstanten verwendet, die mit VC_ beginnen, gibt hier True zurück, wenn das Paket installiert ist, andernfalls False.

Als Quelle für diese habe ich die folgenden Quellen verwendet habe:

  1. How to detect the presence of the VC 8.0 runtime redistributable package
  2. mit Unicode und ANSI-Versionen kompatibel sein von
  3. How to detect the presence of the VC 9.0 runtime redistributable package
  4. How to detect the presence of the VC 2010 runtime redistributable package

Der folgende Code sollte Inno Setup dank kobik's idea to use the conditional define. Hier

ist der Code:

[Files] 
Source: "vcredist_x86.exe"; DestDir: {tmp}; Flags: deleteafterinstall 

[Run] 
; add the Parameters, WorkingDir and StatusMsg as you wish, just keep here 
; the conditional installation Check 
Filename: "{tmp}\vcredist_x86.exe"; Check: VCRedistNeedsInstall 

[Code] 
#IFDEF UNICODE 
    #DEFINE AW "W" 
#ELSE 
    #DEFINE AW "A" 
#ENDIF 
type 
    INSTALLSTATE = Longint; 
const 
    INSTALLSTATE_INVALIDARG = -2; { An invalid parameter was passed to the function. } 
    INSTALLSTATE_UNKNOWN = -1;  { The product is neither advertised or installed. } 
    INSTALLSTATE_ADVERTISED = 1; { The product is advertised but not installed. } 
    INSTALLSTATE_ABSENT = 2;  { The product is installed for a different user. } 
    INSTALLSTATE_DEFAULT = 5;  { The product is installed for the current user. } 

    VC_2005_REDIST_X86 = '{A49F249F-0C91-497F-86DF-B2585E8E76B7}'; 
    VC_2005_REDIST_X64 = '{6E8E85E8-CE4B-4FF5-91F7-04999C9FAE6A}'; 
    VC_2005_REDIST_IA64 = '{03ED71EA-F531-4927-AABD-1C31BCE8E187}'; 
    VC_2005_SP1_REDIST_X86 = '{7299052B-02A4-4627-81F2-1818DA5D550D}'; 
    VC_2005_SP1_REDIST_X64 = '{071C9B48-7C32-4621-A0AC-3F809523288F}'; 
    VC_2005_SP1_REDIST_IA64 = '{0F8FB34E-675E-42ED-850B-29D98C2ECE08}'; 
    VC_2005_SP1_ATL_SEC_UPD_REDIST_X86 = '{837B34E3-7C30-493C-8F6A-2B0F04E2912C}'; 
    VC_2005_SP1_ATL_SEC_UPD_REDIST_X64 = '{6CE5BAE9-D3CA-4B99-891A-1DC6C118A5FC}'; 
    VC_2005_SP1_ATL_SEC_UPD_REDIST_IA64 = '{85025851-A784-46D8-950D-05CB3CA43A13}'; 

    VC_2008_REDIST_X86 = '{FF66E9F6-83E7-3A3E-AF14-8DE9A809A6A4}'; 
    VC_2008_REDIST_X64 = '{350AA351-21FA-3270-8B7A-835434E766AD}'; 
    VC_2008_REDIST_IA64 = '{2B547B43-DB50-3139-9EBE-37D419E0F5FA}'; 
    VC_2008_SP1_REDIST_X86 = '{9A25302D-30C0-39D9-BD6F-21E6EC160475}'; 
    VC_2008_SP1_REDIST_X64 = '{8220EEFE-38CD-377E-8595-13398D740ACE}'; 
    VC_2008_SP1_REDIST_IA64 = '{5827ECE1-AEB0-328E-B813-6FC68622C1F9}'; 
    VC_2008_SP1_ATL_SEC_UPD_REDIST_X86 = '{1F1C2DFC-2D24-3E06-BCB8-725134ADF989}'; 
    VC_2008_SP1_ATL_SEC_UPD_REDIST_X64 = '{4B6C7001-C7D6-3710-913E-5BC23FCE91E6}'; 
    VC_2008_SP1_ATL_SEC_UPD_REDIST_IA64 = '{977AD349-C2A8-39DD-9273-285C08987C7B}'; 
    VC_2008_SP1_MFC_SEC_UPD_REDIST_X86 = '{9BE518E6-ECC6-35A9-88E4-87755C07200F}'; 
    VC_2008_SP1_MFC_SEC_UPD_REDIST_X64 = '{5FCE6D76-F5DC-37AB-B2B8-22AB8CEDB1D4}'; 
    VC_2008_SP1_MFC_SEC_UPD_REDIST_IA64 = '{515643D1-4E9E-342F-A75A-D1F16448DC04}'; 

    VC_2010_REDIST_X86 = '{196BB40D-1578-3D01-B289-BEFC77A11A1E}'; 
    VC_2010_REDIST_X64 = '{DA5E371C-6333-3D8A-93A4-6FD5B20BCC6E}'; 
    VC_2010_REDIST_IA64 = '{C1A35166-4301-38E9-BA67-02823AD72A1B}'; 
    VC_2010_SP1_REDIST_X86 = '{F0C3E5D1-1ADE-321E-8167-68EF0DE699A5}'; 
    VC_2010_SP1_REDIST_X64 = '{1D8E6291-B0D5-35EC-8441-6616F567A0F7}'; 
    VC_2010_SP1_REDIST_IA64 = '{88C73C1C-2DE5-3B01-AFB8-B46EF4AB41CD}'; 

    { Microsoft Visual C++ 2012 x86 Minimum Runtime - 11.0.61030.0 (Update 4) } 
    VC_2012_REDIST_MIN_UPD4_X86 = '{BD95A8CD-1D9F-35AD-981A-3E7925026EBB}'; 
    VC_2012_REDIST_MIN_UPD4_X64 = '{CF2BEA3C-26EA-32F8-AA9B-331F7E34BA97}'; 
    { Microsoft Visual C++ 2012 x86 Additional Runtime - 11.0.61030.0 (Update 4) } 
    VC_2012_REDIST_ADD_UPD4_X86 = '{B175520C-86A2-35A7-8619-86DC379688B9}'; 
    VC_2012_REDIST_ADD_UPD4_X64 = '{37B8F9C7-03FB-3253-8781-2517C99D7C00}'; 

    { Visual C++ 2013 Redistributable 12.0.21005 } 
    VC_2013_REDIST_X86_MIN = '{13A4EE12-23EA-3371-91EE-EFB36DDFFF3E}'; 
    VC_2013_REDIST_X64_MIN = '{A749D8E6-B613-3BE3-8F5F-045C84EBA29B}'; 

    VC_2013_REDIST_X86_ADD = '{F8CFEB22-A2E7-3971-9EDA-4B11EDEFC185}'; 
    VC_2013_REDIST_X64_ADD = '{929FBD26-9020-399B-9A7A-751D61F0B942}'; 

    { Visual C++ 2015 Redistributable 14.0.23026 } 
    VC_2015_REDIST_X86_MIN = '{A2563E55-3BEC-3828-8D67-E5E8B9E8B675}'; 
    VC_2015_REDIST_X64_MIN = '{0D3E9E15-DE7A-300B-96F1-B4AF12B96488}'; 

    VC_2015_REDIST_X86_ADD = '{BE960C1C-7BAD-3DE6-8B1A-2616FE532845}'; 
    VC_2015_REDIST_X64_ADD = '{BC958BD2-5DAC-3862-BB1A-C1BE0790438D}'; 

    { Visual C++ 2015 Redistributable 14.0.24210 } 
    VC_2015_REDIST_X86 = '{8FD71E98-EE44-3844-9DAD-9CB0BBBC603C}'; 
    VC_2015_REDIST_X64 = '{C0B2C673-ECAA-372D-94E5-E89440D087AD}'; 

function MsiQueryProductState(szProduct: string): INSTALLSTATE; 
    external 'MsiQueryProductState{#AW}@msi.dll stdcall'; 

function VCVersionInstalled(const ProductID: string): Boolean; 
begin 
    Result := MsiQueryProductState(ProductID) = INSTALLSTATE_DEFAULT; 
end; 

function VCRedistNeedsInstall: Boolean; 
begin 
    { here the Result must be True when you need to install your VCRedist } 
    { or False when you don't need to, so now it's upon you how you build } 
    { this statement, the following won't install your VC redist only when } 
    { the Visual C++ 2010 Redist (x86) and Visual C++ 2010 SP1 Redist(x86) } 
    { are installed for the current user } 
    Result := not (VCVersionInstalled(VC_2010_REDIST_X86) and 
    VCVersionInstalled(VC_2010_SP1_REDIST_X86)); 
end; 

Update durch chuckleplant:

Added VC++ 2012 Produktcodes. Beachten Sie, dass das Redistributable-Paket zwei Dinge installiert, die minimale Laufzeit und die zusätzliche Laufzeit. Es sollte genug sein, dass Sie nach der minimalen Laufzeit suchen. Beim Testen mit dem Microsoft Visual C++ 2012 Redistributable-Produktcode wird INSTALLSTATE_UNKNOWN verwendet, stattdessen die Minimum-Laufzeitcodes. Es ist die gleiche Situation für VC++ 2013 und 2015

Sie können Produktcodes für andere Visual Studio Versionen in HKEY_CLASSES_ROOT\Installer\Dependencies\ zum Beispiel HKEY_CLASSES_ROOT\Installer\Dependencies\Microsoft.VS.VC_RuntimeAdditionalVSU_amd64,v14

+2

Vielen Dank für so eine Antwort! – myWallJSON

+2

Beachten Sie, dass manchmal, selbst wenn das Betriebssystem die "VC++ Laufzeiten" enthält, es für Ihre Anwendung nicht ausreicht; Gelegentlich werden Service Packs oder Hotfixes auf Ihren dev PCs installiert, die eine spätere Version der Laufzeit erfordern, als ursprünglich mit dem Betriebssystem geliefert wurde. Vergessen Sie daher nicht, Ihre App immer auf einem "sauberen" PC/VM zu testen, nachdem Sie Updates auf Ihren dev/build PCs installiert haben. – Miral

+0

@TLama: Dieser Code funktioniert für 'VC_2008_REDIST_X86', funktioniert aber nicht für 'VC_2008_SP1_REDIST_X86'. Die Installation von VVisual C++ 2008 SP1 Redistributable Package (x86) wird immer durchgeführt. kannst du mir bitte helfen ? – Shoshi

8

Viel einfacher finden:

#define VCmsg "Installing Microsoft Visual C++ Redistributable...." 

[Run] 
Filename: "vc_redist.x86.exe"; StatusMsg: "{#VCmsg}"; Check: not IsWin64 and not VCinstalled 
Filename: "vc_redist.x64.exe"; StatusMsg: "{#VCmsg}"; Check: IsWin64 and not VCinstalled 

[Code] 
function VCinstalled: Boolean; 
// By Michael Weiner <mailto:[email protected]> 
// Function for Inno Setup Compiler 
// 13 November 2015 
// Returns True if Microsoft Visual C++ Redistributable is installed, otherwise False. 
// The programmer may set the year of redistributable to find; see below. 
var 
    names: TArrayOfString; 
    i: Integer; 
    dName, key, year: String; 
begin 
    // Year of redistributable to find; leave null to find installation for any year. 
    year := ''; 
    Result := False; 
    key := 'Software\Microsoft\Windows\CurrentVersion\Uninstall'; 
    // Get an array of all of the uninstall subkey names. 
    if RegGetSubkeyNames(HKEY_LOCAL_MACHINE, key, names) then 
    // Uninstall subkey names were found. 
    begin 
    i := 0 
    while ((i < GetArrayLength(names)) and (Result = False)) do 
    // The loop will end as soon as one instance of a Visual C++ redistributable is found. 
    begin 
     // For each uninstall subkey, look for a DisplayName value. 
     // If not found, then the subkey name will be used instead. 
     if not RegQueryStringValue(HKEY_LOCAL_MACHINE, key + '\' + names[i], 'DisplayName', dName) then 
     dName := names[i]; 
     // See if the value contains both of the strings below. 
     Result := (Pos(Trim('Visual C++ ' + year),dName) * Pos('Redistributable',dName) <> 0) 
     i := i + 1; 
    end; 
    end; 
end; 
+0

Es sieht ms neueste msvc 2015 redist werden "Microsoft Visual C++ 2015 x 64 Minimum Runtime - 14.0.23026" beschriftet, so dass das Wort "Redistributable" nicht in der Zeichenfolge angezeigt wird. –

3

Hier ist eine Version, die die verwendet Microsoft hat empfohlen, festzustellen, ob VC Redistributable installiert ist. Ich habe nur VC benötigt 2015 so müssen Sie die Werte und Parameter für andere Versionen anzupassen:

[Files] 
Source: ".\vc-redist\vc-redist\win64\bin\vc_redist.x64.exe"; DestDir: "{tmp}"; Flags: deleteafterinstall; Check: Is64BitInstallMode 

; FlexLM requires the VC 2015 redistributables so run the installer if this 
; or a later 2015 version is not already present 
[Run] 
Filename: "{tmp}\vc_redist.x64.exe"; Parameters: "/install /passive"; StatusMsg: "{#VCmsg}"; Check: IsWin64 and not VCinstalled 

[Code] 
function VCinstalled: Boolean; 
// Function for Inno Setup Compiler 
// Returns True if same or later Microsoft Visual C++ 2015 Redistributable is installed, otherwise False. 
var 
    major: Cardinal; 
    minor: Cardinal; 
    bld: Cardinal; 
    rbld: Cardinal; 
    key: String; 
begin 
    Result := False; 
    key := 'SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64'; 
    if RegQueryDWordValue(HKEY_LOCAL_MACHINE, key, 'Major', major) then begin 
    if RegQueryDWordValue(HKEY_LOCAL_MACHINE, key, 'Minor', minor) then begin 
     if RegQueryDWordValue(HKEY_LOCAL_MACHINE, key, 'Bld', bld) then begin 
     if RegQueryDWordValue(HKEY_LOCAL_MACHINE, key, 'RBld', rbld) then begin 
      Log('VC 2015 Redist Major is: ' + IntToStr(major) + ' Minor is: ' + IntToStr(minor) + ' Bld is: ' + IntToStr(bld) + ' Rbld is: ' + IntToStr(rbld)); 
      // Version info was found. Return true if later or equal to our 14.0.24212.00 redistributable 
      // Note brackets required because of weird operator precendence 
      Result := (major >= 14) and (minor >= 0) and (bld >= 24212) and (rbld >= 0) 
     end; 
     end; 
    end; 
    end; 
end;