前言
判断VC是否安装有两种方式
- 通过软件的GUID判断,这种方式比较准确,但需要知道程序的GUID,推荐使用。
- 通过注册表中卸载程序的名称判断,这种方式并不太可靠。
下载地址
https://learn.microsoft.com/zh-CN/cpp/windows/latest-supported-vc-redist?view=msvc-170#visual-studio-2010-vc-100-sp1-no-longer-supported
通过GUID方式
https://learn.microsoft.com/zh-cn/windows/win32/api/msi/nf-msi-msiqueryproductstatea?redirectedfrom=MSDN
返回值
| 值 |
含义 |
| INSTALLSTATE_ABSENT |
已为另一用户安装该产品。 |
| INSTALLSTATE_ADVERTISED |
该产品已播发,但未安装。 |
| INSTALLSTATE_DEFAULT |
已为当前用户安装该产品。 |
| INSTALLSTATE_INVALIDARG |
向该函数传递了无效参数。 |
| INSTALLSTATE_UNKNOWN |
该产品既未播发,也未安装。 |
工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
namespace env_monitor.Utils { using System.Runtime.InteropServices;
public class ZvcInstallCheckUtils { public static bool IsInstall(string msiid) { return GetProcuct(msiid) == INSTALLSTATE.INSTALLSTATE_DEFAULT; }
[DllImport("msi.dll")] private static extern INSTALLSTATE MsiQueryProductState(string product);
private static INSTALLSTATE GetProcuct(string product) { INSTALLSTATE state = MsiQueryProductState(product); return state; } }
public enum INSTALLSTATE { INSTALLSTATE_NOTUSED = -7, INSTALLSTATE_BADCONFIG = -6, INSTALLSTATE_INCOMPLETE = -5, INSTALLSTATE_SOURCEABSENT = -4, INSTALLSTATE_MOREDATA = -3, INSTALLSTATE_INVALIDARG = -2, INSTALLSTATE_UNKNOWN = -1, INSTALLSTATE_BROKEN = 0, INSTALLSTATE_ADVERTISED = 1, INSTALLSTATE_REMOVED = 1, INSTALLSTATE_ABSENT = 2, INSTALLSTATE_LOCAL = 3, INSTALLSTATE_SOURCE = 4, INSTALLSTATE_DEFAULT = 5, } }
|
调用
1 2
| var installstate = ZvcInstallCheckUtils.IsInstall("{1D8E6291-B0D5-35EC-8441-6616F567A0F7}"); Console.WriteLine(installstate);
|
VC的GUID
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| Visual C++ 2005 Redistributable Package (x86) {A49F249F-0C91-497F-86DF-B2585E8E76B7}
Visual C++ 2005 Redistributable Package (x64) {6E8E85E8-CE4B-4FF5-91F7-04999C9FAE6A}
Visual C++ 2005 Redistributable Package (ia64) {03ED71EA-F531-4927-AABD-1C31BCE8E187}
Visual C++ 2005 SP1 Redistributable Package (x86) {7299052B-02A4-4627-81F2-1818DA5D550D}
Visual C++ 2005 SP1 Redistributable Package (x64) {071C9B48-7C32-4621-A0AC-3F809523288F}
Visual C++ 2005 SP1 Redistributable Package (ia64) {0F8FB34E-675E-42ED-850B-29D98C2ECE08}
Visual C++ 2008 Redistributable Package (x86) {FF66E9F6-83E7-3A3E-AF14-8DE9A809A6A4}
Visual C++ 2008 Redistributable Package (x64) {350AA351-21FA-3270-8B7A-835434E766AD}
Visual C++ 2008 Redistributable Package (ia64) {2B547B43-DB50-3139-9EBE-37D419E0F5FA}
Visual C++ 2008 SP1 Redistributable Package (x86) {9A25302D-30C0-39D9-BD6F-21E6EC160475}
Visual C++ 2008 SP1 Redistributable Package (x86 9.0.30729.6161) {9BE518E6-ECC6-35A9-88E4-87755C07200F}
Visual C++ 2008 SP1 Redistributable Package (x64) {8220EEFE-38CD-377E-8595-13398D740ACE}
Visual C++ 2008 SP1 Redistributable Package (ia64) {5827ECE1-AEB0-328E-B813-6FC68622C1F9}
Visual C++ 2010 Redistributable Package (x86) {196BB40D-1578-3D01-B289-BEFC77A11A1E}
Visual C++ 2010 Redistributable Package (x64) {DA5E371C-6333-3D8A-93A4-6FD5B20BCC6E}
Visual C++ 2010 Redistributable Package (ia64) {C1A35166-4301-38E9-BA67-02823AD72A1B}
Visual C++ 2010 SP1 Redistributable Package (x86 10.0.40219) {F0C3E5D1-1ADE-321E-8167-68EF0DE699A5}
Visual C++ 2010 SP1 Redistributable Package (x64) {1D8E6291-B0D5-35EC-8441-6616F567A0F7}
Visual C++ 2010 SP1 Redistributable Package (ia64) {88C73C1C-2DE5-3B01-AFB8-B46EF4AB41CD}
Visual C++ 2013 Redistributable Package (x86 12.0.21005) {13A4EE12-23EA-3371-91EE-EFB36DDFFF3E} and {F8CFEB22-A2E7-3971-9EDA-4B11EDEFC185}
Visual C++ 2013 Redistributable Package (x64) {929FBD26-9020-399B-9A7A-751D61F0B942} and {A749D8E6-B613-3BE3-8F5F-045C84EBA29B}
|
通过注册表方式
这种方式并不能准确找到,测试的时候我查找2010 x86可以找到,但是2010 x64的却找不到。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| namespace env_monitor.Utils { using System; using System.Collections.Generic; using System.Linq; using Microsoft.Win32;
public class ZvcInstallCheckByRegUtils { public static bool IsInstallVc(string[] keywords) { List<string> lists = new List<string>(); RegistryKey key = Registry.LocalMachine; GetRegistry( key, @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall", ref lists ); if (lists.Count > 0) { string vcName = null; foreach (var s1 in lists.Where(x => keywords.All(x.Contains))) { vcName = s1; break; } Console.WriteLine(vcName); return !string.IsNullOrEmpty(vcName); } return false; }
private static void GetRegistry ( RegistryKey keyR, string str, ref List<string> list ) { RegistryKey aimdir = keyR.OpenSubKey(str); if (aimdir != null) { var subvalueNames = aimdir.GetValueNames(); foreach (string valueName in subvalueNames) { if (valueName.ToLower().Equals("displayname") || valueName.ToLower().Equals("productname")) { if (aimdir.GetValue(valueName) != null && aimdir.GetValue(valueName).ToString().ToLower().Contains("microsoft visual c++")) { list.Add(aimdir.GetValue(valueName).ToString()); } } } var subkeyNames = aimdir.GetSubKeyNames(); foreach (string keyName in subkeyNames) { GetRegistry( aimdir, keyName, ref list ); } } } } }
|
注意这里之所以使用数组来过滤是因为微软的名称命名也太不规范了。
比如"Microsoft Visual C++ 2010 x86 Redistributable - 10.0.40219",2010和x86之间竟然是2个空格,所以使用数组来判断,不但包含2010,而且包含x86才算匹配上。
测试
1 2 3 4 5 6 7 8
| var isInstall = ZvcInstallCheckByRegUtils.IsInstallVc( new[] { "2010", "x86" } ); Console.WriteLine(isInstall);
|