如何使用 NSIS 安装 Visual C++ Redist

How to Install the Visual C++ Redist Using NSIS

我的 C++ 应用程序需要安装 Visual Studio C++ 可再发行组件。我使用的是 Visual Studio 2019 社区版。我使用 NSIS(3.04 版)来创建我的安装程序。我是否应该尝试检测是否安装了 redist 并且只在它不是最新的时候才安装它?

关于如何做到这一点有很多答案,包括许多如何检测是否安装了 redist 的方法。我不会说 所有 它们是不完整的并且在未来的证明方法中不起作用,但我没有用它们取得成功。所以,我认为最好的办法就是始终安装 redist,让 Microsoft 来处理它。截至 2020 年 3 月,这将为您的安装程序增加 14MB,但也许在这个高速互联网时代,这已经不是什么大不了的事了。幸运的是,这很简单,希望这个问题能让您避免关注我所做的所有过时的参考资料和链接。

可在此处找到有关 Microsoft redist 的说明:Redistributing Visual C++ Files

要将其转换为 NSIS:

在 Visual Studio 安装中找到要重新分发的文件。对我来说是:

C:\Program Files (x86)\Microsoft Visual Studio19\Community\VC\Redist\MSVC.25.28508\vcredist_x86.exe

版本号将来肯定会更改 (14.25.28508),可能就在您安装更新到 Visual Studio 时,因此请记住,您需要在安装程序时更新该路径休息。您还需要在 vcredist_x86.exe 和 vcredist_x64.exe 之间进行选择,具体取决于您将应用程序构建为 32 位还是 64 位。

将这样的部分添加到您的 NSIS 安装文件中,可能在您进行主要安装之前。它所做的只是将redist文件复制到文件系统中,运行它,等待完成,然后删除redist文件。

Section "Visual Studio Runtime"
  SetOutPath "$INSTDIR"
  File "C:\Program Files (x86)\Microsoft Visual Studio19\Community\VC\Redist\MSVC.25.28508\vcredist_x86.exe"
  ExecWait "$INSTDIR\vcredist_x86.exe"
  Delete "$INSTDIR\vcredist_x86.exe"
SectionEnd

替换为您要使用的 redist 文件的正确路径。

如所写(和当前的 redist 程序行为),这将弹出一个对话框,用户必须按照该对话框安装 redist。您可以替代静音模式:

ExecWait '"$INSTDIR\vcredist_x86.exe" /quiet'

但是我并没有得到很好的结果。 YMMV.

要让额外的开关起作用,请将它们包括在引号中。 所以上面的 ExecWait 命令如下:

ExecWait "$INSTDIR\vcredist_x86.exe /install /quiet"

我目前正在使用它,但是使用“/quiet”开关时,实际的 NSI 安装程序进程会挂起,直到安装 redist。

改用“/passive”将提供有关 redist 安装的进度报告

我同意 gdunbar 的观点,即检测方法既复杂又不太可靠,此线程中对此类方法进行了很好的总结:Detect if Visual C++ Redistributable for Visual Studio 2012 is installed 但是我不想总是在安装程序中包含 VC redist,因为它会显着增加安装程序的大小(例如 VC++ 2019 可再发行版是 24Mb,而我的安装程序没有它是 1Mb)。所以我最终使用了我认为非常可靠的方法来尝试 运行 可执行文件,并在需要时即时下载安装程序。下面是 VC++ 2019 可再发行版的详细信息:

  1. 创建控制台 windows 应用程序,例如Visual Studio 2019 向导创建此代码:

    #include <iostream>
    
    int main()
    {
        std::cout << "Hello World!\n";
        return 0;
    }
    

    此应用程序的大小为 12K(使用“偏爱小尺寸”选项编译)。

  2. 在 NSIS 中使用以下代码 运行 它并根据需要下载安装程序:

    InitPluginsDir
    ;the hello word console app
    ;need to use nsExec plugin to prevent error popup (if redist is missing)
    File /oname=$PLUGINSDIR\checkRedist.exe checkRedist.exe
    nsExec::Exec '"$PLUGINSDIR\checkRedist.exe"'
    Pop [=11=]
    
    ${If} [=11=] != 0
        DetailPrint "VC++ Redistributable package is missing!"
        inetc::get "https://aka.ms/vs/16/release/vc_redist.x64.exe" $PLUGINSDIR\vcredist.exe
        DetailPrint "Installing Visual Studio Redistributable package..."
        ExecWait '"$PLUGINSDIR\vcredist.exe" /q /norestart'
        DetailPrint "Done"
    ${Else}
        DetailPrint "VC++ Redistributable already installed"
    ${EndIf}