C#判断VC库是否安装

2023-09-26 08:19:10 浏览数 (1)

前言

判断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

该产品既未播发,也未安装。

工具类

代码语言:javascript复制
// ReSharper disable InconsistentNaming
// ReSharper disable once InconsistentNaming
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, // component disabled
        INSTALLSTATE_BADCONFIG = -6, // configuration data corrupt
        INSTALLSTATE_INCOMPLETE = -5, // installation suspended or in progress
        INSTALLSTATE_SOURCEABSENT = -4, // run from source, source is unavailable
        INSTALLSTATE_MOREDATA = -3, // return buffer overflow
        INSTALLSTATE_INVALIDARG = -2, // invalid function argument
        INSTALLSTATE_UNKNOWN = -1, // unrecognized product or feature
        INSTALLSTATE_BROKEN = 0, // broken
        INSTALLSTATE_ADVERTISED = 1, // advertised feature
        INSTALLSTATE_REMOVED = 1, // component being removed (action state, not settable)
        INSTALLSTATE_ABSENT = 2, // uninstalled (or action state absent but clients remain)
        INSTALLSTATE_LOCAL = 3, // installed on local drive
        INSTALLSTATE_SOURCE = 4, // run from source, CD or net
        INSTALLSTATE_DEFAULT = 5, // use default, local or source
    }
}

调用

代码语言:javascript复制
var installstate = ZvcInstallCheckUtils.IsInstall("{1D8E6291-B0D5-35EC-8441-6616F567A0F7}");
Console.WriteLine(installstate);

VC的GUID

代码语言:javascript复制
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的却找不到。

代码语言:javascript复制
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,
                @"SOFTWAREWow6432NodeMicrosoftWindowsCurrentVersionUninstall",
                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才算匹配上。

测试

代码语言:javascript复制
var isInstall = ZvcInstallCheckByRegUtils.IsInstallVc(
    new[]
    {
        "2010",
        "x86"
    }
);
Console.WriteLine(isInstall);

0 人点赞