Вопрос по inno-setup, msvcrt – Как сделать, чтобы vcredist_x86 переустанавливался, только если еще не установлен?

41

В моем выборе inno установки RUN я принудительно устанавливаю MSVCRT. Интересно, как заставить его установить себя, только если еще не установлен?

Это то, что я сейчас называю:

Filename: {tmp}\vcredist_x86.exe; Parameters: "/passive /Q:a /c:""msiexec /qb /i vcredist.msi"" "; StatusMsg: Installing 2010 RunTime...
Нечто подобное было заданоhere однако я не согласен с ответом, так как он устанавливает фреймворк при запуске мастера, но IMO его следует запускать при нажатии окончательной версииNext Кнопка и установка начинается. Я попытаюсь найти записи реестра, необходимые для этой проверки. А пока взглянем наthis post, Вам нужно использоватьCheck Параметр для этого. TLama

Ваш Ответ

4   ответа
88

Поскольку вы не хотите указывать, какая минимальная версия распространяемого пакета Visual C ++ вам требуется, здесь у вас есть пример кода, из которого вы можете создать его самостоятельно. Обратите внимание, что я понятия не имею, какие версии совместимы с какими и какие более низкие версии должны быть установлены, и я оставлю это на вас.

Единственное, что я могу вам сказать, это то, что вы обязательно должны использоватьCheck условный параметр, решения, пытающиеся установить инфраструктуру или библиотеки времени выполнения при открытии мастера, неверны. Этот условный параметр работает так же, как когда вы возвращаете True, файл устанавливается, если False, он пропускается. Так что вам нужно вернуть TrueVCRedistNeedsInstall Функция, если вы хотите установить библиотеки времени выполнения, если нет, False. Вспомогательная функцияVCVersionInstalled который использует константы, начинающиеся сVC_ здесь возвращает True, когда пакет установлен, False в противном случае.

В качестве источника этого я использовал следующие источники:

  1. How to detect the presence of the VC 8.0 runtime redistributable package
  2. How to detect the presence of the VC 9.0 runtime redistributable package
  3. How to detect the presence of the VC 2010 runtime redistributable package

Следующий код должен быть совместим с версиями Inno Setup для Unicode и ANSI благодаряИдея Кобика об использовании условного определения.

Вот код:

[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 by chuckleplant:

Добавлены коды продуктов VC ++ 2012. Обратите внимание, что распространяемый пакет устанавливает две вещи: минимальное время выполнения и дополнительное время выполнения. Этого должно быть достаточно для поиска минимального времени выполнения. Тестирование на распространяемый код продукта Microsoft Visual C ++ 2012 дастINSTALLSTATE_UNKNOWNвместо этого используйте минимальные коды времени выполнения. Такая же ситуация для VC ++ 2013 и 2015.

Коды продуктов для других версий Visual Studio можно найти вHKEY_CLASSES_ROOT\Installer\Dependencies\, напримерHKEY_CLASSES_ROOT\Installer\Dependencies\Microsoft.VS.VC_RuntimeAdditionalVSU_amd64,v14

@TLama Не могли бы вы обновить свой ответ для VC_REDIST_2012 (microsoft.com/de-de/download/details.aspx?id=30679)? Я думаю, что это "{8e70e4e1-06d7-470b-9f74-a51bef21088e}". Непроверенные.
На всякий случай, если кому-то нужны GUID для VC ++ 2017 // Распространяемый Visual C ++ 2017 14.10.25 VC_2017_REDIST_X86_MIN = & apos; {029DA848-1A80-34D3-BFC1-A6447BFC8E7F} & apos ;; VC_2017_REDIST_X64_MIN = "{8D50D8C6-1E3D-3BAB-B2B7-A5399EA1EBD1}"; VC_2017_REDIST_X86_ADD = "{568CD07E-0824-3EEB-AEC1-8FD51F3C85CF}"; VC_2017_REDIST_X64_ADD = "{C668F044-4825-330D-8F9F-3CBFC9F2AB89}";
Большое спасибо за такой хороший ответ! myWallJSON
Обратите внимание, что иногда, даже когда ОС включает в себя «VC ++ runtime» этого недостаточно для вашей заявки; иногда на ПК разработчика устанавливаются пакеты обновления или исправления, которые в конечном итоге требуют более поздней версии среды выполнения, чем была изначально поставлена с ОС. Как следствие, не забывайте всегда тестировать свое приложение на «чистом» уровне. ПК / ВМ после установки обновлений на ПК разработчика / сборки.
У MS есть официальный способ определить, установлен ли VC ++, проверяяHKEY_LOCAL_MACHINE\SOFTWARE[\Wow6432Node]\Microsoft\DevDiv\vc\Servicing\14.0\RuntimeMinimum : msdn.microsoft.com/en-us/library/…
8

Намного легче:

#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;
Похоже, что последняя версия MSVC 2015 Redist помечена как «Microsoft Visual C ++ 2015 x64 Minimum Runtime - 14.0.23026». поэтому слово «распространяемый» не появляется в строке.
7

Вот версия, которая использует рекомендованный Microsoft способ определения того, установлен ли распространяемый VC. Мне нужен был только VC 2015, поэтому вам нужно будет адаптировать значения и параметры для других версий:

[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;
1

Я знаю, что это очень старый вопрос, но я сталкиваюсь с этой ситуацией, и, поскольку я не смог выполнить проверку winregistry, я применил этот подход,

на основе этого списка файлов:https://matthew-brett.github.io/pydagogue/_sources/python_msvc.rst.txt

я был в состоянии просто проверить, существует ли файл, например, VCRedist 2015/2013 x86 / x64:

2015

C:/Windows/SysWOW64/msvcp140.dll - х64

C:/Windows/System32/msvcp140.dll" - x86

2013

C:/Windows/SysWOW64/msvcp120.dll - х64

C:/Windows/System32/msvcp120.dll" - x86

Будьте осторожны, это неправильно.SysWOW64 содержит 32-битные файлыSystem32 содержит 64-битные файлы. Объяснение здесь:forceflow.be/2012/04/04/…
@ Марко приятно знать! я действительно не знал об этом

Похожие вопросы