以编程方式检测已安装的 MSVC 可再发行组件
Detecting installed MSVC redistributables programmatically
有什么办法可以用 C++ 实现吗?我想这样做:
用户启动应用程序 -> 应用程序检查已安装的 redists -> 应用程序告诉用户安装可再发行的 X 以便使用应用程序并关闭
可能你最好的选择是 MsiQueryProductState
这里有两篇好文章:
How to programmatically obtain the installation state of Visual Studio .NET or Visual Studio 2005
Determining if the VC Runtimes Are Installed (Delphi 代码示例):
// API call to msi.dll to determine is a MSI installed packed has been installed.
// It does this by checking the state of the installed package.
// Anything other than a return value of INSTALLSTATE_DEFAULT (5) indicates a broken or
// no installation.
function MsiQueryProductState(szProduct: String): Integer; external 'MsiQueryProductStateA@msi.dll stdcall';
// String constants to pass to the routine.
const
// These constants check for any install of the version specific package
// regardless the service pack or security update. There are specific
// constants for x86, x64 and i64 installations.
VC2005_ANY_x86 = 'vc2005x86';
VC2005_ANY_x64 = 'vc2005x64';
VC2005_ANY_i64 = 'vc2005i64';
...
// All available VC 2005 (version 8.0) installations.
VC2005_x86 = '{A49F249F-0C91-497F-86DF-B2585E8E76B7}';
VC2005_x64 = '{6E8E85E8-CE4B-4FF5-91F7-04999C9FAE6A}';
...
// All available VC 2008 (version 9.0) installations.
VC2008_x86 = '{FF66E9F6-83E7-3A3E-AF14-8DE9A809A6A4}';
VC2008_x64 = '{350AA351-21FA-3270-8B7A-835434E766AD}';
...
function VCRT_IsInstalled(sPackage: String): Integer;
var
nResult: Integer;
begin
// Check for the existence of msi.dll. The poor man's way of checking for the
// installation of the Windows Installation Engine.
If FileExists(ExpandConstant('{sys}\msi.dll')) then begin
// Default return value of -1, which indicated no installation. This is only
// necessary for the VC*_ANY_* flags as individual return values are not captured.
Result := -1;
// Check for the package passed ia the sPackage parameter.
case sPackage of
VC2005_ANY_x86:
begin
If (MsiQueryProductState(VC2005_x86) = 5) or
(MsiQueryProductState(VC2005_SP1_x86) = 5) or
(MsiQueryProductState(VC2005_SP1_SECUP_x86) = 5) then begin
Result := 5;
end;
end;
VC2008_ANY_x86:
begin
If (MsiQueryProductState(VC2008_x86) = 5) or
(MsiQueryProductState(VC2008_SP1_x86) = 5) or
(MsiQueryProductState(VC2008_SP1_SECUP_x86) = 5) then begin
Result := 5;
...
VC2010_ANY_i64:
begin
If MsiQueryProductState(VC2010_i64) = 5 then begin
Result := 5;
end;
end;
// All speific versions are checked here. The return value is passed back
// as the functions return value.
else
begin
Result := MsiQueryProductState(sPackage);
end;
end;
end else begin
// MSI not installed. Pass the specific error number for it.
Result := INSTALLSTATE_MSIABSENT;
end;
end;
这是 MSVS 2015 的可再分发代码列表:
有什么办法可以用 C++ 实现吗?我想这样做:
用户启动应用程序 -> 应用程序检查已安装的 redists -> 应用程序告诉用户安装可再发行的 X 以便使用应用程序并关闭
可能你最好的选择是 MsiQueryProductState
这里有两篇好文章:
How to programmatically obtain the installation state of Visual Studio .NET or Visual Studio 2005
Determining if the VC Runtimes Are Installed (Delphi 代码示例):
// API call to msi.dll to determine is a MSI installed packed has been installed.
// It does this by checking the state of the installed package.
// Anything other than a return value of INSTALLSTATE_DEFAULT (5) indicates a broken or
// no installation.
function MsiQueryProductState(szProduct: String): Integer; external 'MsiQueryProductStateA@msi.dll stdcall';
// String constants to pass to the routine.
const
// These constants check for any install of the version specific package
// regardless the service pack or security update. There are specific
// constants for x86, x64 and i64 installations.
VC2005_ANY_x86 = 'vc2005x86';
VC2005_ANY_x64 = 'vc2005x64';
VC2005_ANY_i64 = 'vc2005i64';
...
// All available VC 2005 (version 8.0) installations.
VC2005_x86 = '{A49F249F-0C91-497F-86DF-B2585E8E76B7}';
VC2005_x64 = '{6E8E85E8-CE4B-4FF5-91F7-04999C9FAE6A}';
...
// All available VC 2008 (version 9.0) installations.
VC2008_x86 = '{FF66E9F6-83E7-3A3E-AF14-8DE9A809A6A4}';
VC2008_x64 = '{350AA351-21FA-3270-8B7A-835434E766AD}';
...
function VCRT_IsInstalled(sPackage: String): Integer;
var
nResult: Integer;
begin
// Check for the existence of msi.dll. The poor man's way of checking for the
// installation of the Windows Installation Engine.
If FileExists(ExpandConstant('{sys}\msi.dll')) then begin
// Default return value of -1, which indicated no installation. This is only
// necessary for the VC*_ANY_* flags as individual return values are not captured.
Result := -1;
// Check for the package passed ia the sPackage parameter.
case sPackage of
VC2005_ANY_x86:
begin
If (MsiQueryProductState(VC2005_x86) = 5) or
(MsiQueryProductState(VC2005_SP1_x86) = 5) or
(MsiQueryProductState(VC2005_SP1_SECUP_x86) = 5) then begin
Result := 5;
end;
end;
VC2008_ANY_x86:
begin
If (MsiQueryProductState(VC2008_x86) = 5) or
(MsiQueryProductState(VC2008_SP1_x86) = 5) or
(MsiQueryProductState(VC2008_SP1_SECUP_x86) = 5) then begin
Result := 5;
...
VC2010_ANY_i64:
begin
If MsiQueryProductState(VC2010_i64) = 5 then begin
Result := 5;
end;
end;
// All speific versions are checked here. The return value is passed back
// as the functions return value.
else
begin
Result := MsiQueryProductState(sPackage);
end;
end;
end else begin
// MSI not installed. Pass the specific error number for it.
Result := INSTALLSTATE_MSIABSENT;
end;
end;
这是 MSVS 2015 的可再分发代码列表: