using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace ryCommon
{
    /// <summary>
    /// 运行库检测类
    /// </summary>
    public static class RedistCheck
    {
        #region C++运行库判断模块
        [DllImport("msi.dll")]
        private static extern INSTALLSTATE MsiQueryProductState(string product);
        /// <summary>
        /// 获取产品状态
        /// </summary>
        /// <param name="product"></param>
        /// <returns></returns>
        private static INSTALLSTATE GetProcuct(string product)
        {
            INSTALLSTATE state = MsiQueryProductState(product);
            return state;
        }
        private static bool HaveInstallVc(string GUID)
        {

            if (MsiQueryProductState(GUID) == INSTALLSTATE.INSTALLSTATE_DEFAULT)
            { return true; }
            else
            {
                return false;
            }

        }
        private static bool HaveInstallVc(InstallBit installBit,string GUID_x86,string GUID_X64)
        {
            if (installBit == InstallBit.All)
            {
                return HaveInstallVc(GUID_x86) && HaveInstallVc(GUID_X64);
            }
            else if (installBit == InstallBit.X86)
            {
                return HaveInstallVc(GUID_x86);
            }
            else if (installBit == InstallBit.X64)
            {
                return HaveInstallVc(GUID_X64);
            }
            return false;
        }
        private static bool HaveInstallVc(InstallBit installBit, string[] GUID_x86, string[] GUID_X64)
        {
            if (installBit == InstallBit.All)
            {
                var result_x86 = false;
                for (int i = 0; i < GUID_x86.Length; i++)
                {
                    if (HaveInstallVc(GUID_x86[i])) { result_x86 = true;break; }
                }
                var result_x64 = false;
                for (int i = 0; i < GUID_X64.Length; i++)
                {
                    if (HaveInstallVc(GUID_X64[i])) { result_x64 = true; break; }
                }
                return result_x86 && result_x64;
            }
            else if (installBit == InstallBit.X86)
            {
                var result_x86 = false;
                for (int i = 0; i < GUID_x86.Length; i++)
                {
                    if (HaveInstallVc(GUID_x86[i])) { result_x86 = true; break; }
                }
                return result_x86;
            }
            else if (installBit == InstallBit.X64)
            {
                var result_x64 = false;
                for (int i = 0; i < GUID_X64.Length; i++)
                {
                    if (HaveInstallVc(GUID_X64[i])) { result_x64 = true; break; }
                }
                return result_x64;
            }
            return false;
        }
        /// <summary>
        /// 判断是否已安装VC运行库
        /// </summary>
        /// <returns></returns>
        private static bool IsInstall_VC(InstallBit installBit,string vcdll,double min_softver,double min_rever)
        {
            if (Environment.Is64BitOperatingSystem)
            {
                if (installBit == InstallBit.All)
                {
                    var path_x64 = RyFiles.GetRealPath(@"<sys>\"+ vcdll);
                    var path_x86 = RyFiles.GetRealPath(@"<sys_x86>\"+ vcdll);
                    if (System.IO.File.Exists(path_x64) && System.IO.File.Exists(path_x86))
                    {
                        var ver_x64 = RySoft.GetVersionStr(path_x64);
                        RySoft.GetVerByVerStr(ver_x64, out var _softver_x64, out var _rever_x64);
                        var ver_x86 = RySoft.GetVersionStr(path_x86);
                        RySoft.GetVerByVerStr(ver_x86, out var _softver_x86, out var _rever_x86);
                        if (RySoft.CompareVer(min_softver, min_rever,_softver_x64, _rever_x64)>=0 && RySoft.CompareVer(min_softver, min_rever, _softver_x86, _rever_x86) >= 0)
                        {
                            return true;
                        }
                    }
                }
                else if (installBit == InstallBit.X86)
                {
                    var path_x86 = RyFiles.GetRealPath(@"<sys_x86>\"+ vcdll);
                    if (System.IO.File.Exists(path_x86))
                    {
                        var ver_x86 = RySoft.GetVersionStr(path_x86);
                        RySoft.GetVerByVerStr(ver_x86, out var _softver_x86, out var _rever_x86);
                        if (RySoft.CompareVer(min_softver, min_rever, _softver_x86, _rever_x86) >= 0)
                        {
                            return true;
                        }
                    }
                }
                else if (installBit == InstallBit.X64)
                {
                    var path_x64 = RyFiles.GetRealPath(@"<sys>\"+ vcdll);
                    if (System.IO.File.Exists(path_x64))
                    {
                        var ver_x64 = RySoft.GetVersionStr(path_x64);
                        RySoft.GetVerByVerStr(ver_x64, out var _softver_x64, out var _rever_x64);
                        if (RySoft.CompareVer(min_softver, min_rever, _softver_x64, _rever_x64) >= 0)
                        {
                            return true;
                        }
                    }
                }
            }
            else
            {
                var path = RyFiles.GetRealPath(@"<sys>\"+ vcdll);
                if (System.IO.File.Exists(path))
                {
                    var ver_x86 = RySoft.GetVersionStr(path);
                    RySoft.GetVerByVerStr(ver_x86, out var _softver_x86, out var _rever_x86);
                    if (RySoft.CompareVer(min_softver, min_rever, _softver_x86, _rever_x86) >= 0)
                    {
                        return true;
                    }
                }
            }
            return false;
        }
        /// <summary>
        /// 判断是否已安装VC运行库
        /// </summary>
        /// <returns></returns>
        public static bool IsInstall_VC(InstallBit installBit, string vcdll)
        {
            if (Environment.Is64BitOperatingSystem)
            {
                if (installBit == InstallBit.All)
                {
                    var path_x64 = RyFiles.GetRealPath(@"<sys>\"+ vcdll);
                    var path_x86 = RyFiles.GetRealPath(@"<sys_x86>\"+ vcdll);
                    if (System.IO.File.Exists(path_x64) && System.IO.File.Exists(path_x86))
                    {
                        return true;
                    }
                }
                else if (installBit == InstallBit.X86)
                {
                    var path_x86 = RyFiles.GetRealPath(@"<sys_x86>\"+ vcdll);
                    if (System.IO.File.Exists(path_x86)) { return true; }
                }
                else if (installBit == InstallBit.X64)
                {
                    var path_x64 = RyFiles.GetRealPath(@"<sys>\"+ vcdll);
                    if (System.IO.File.Exists(path_x64)) { return true; }
                }
            }
            else
            {
                var path = RyFiles.GetRealPath(@"<sys>\"+ vcdll);
                if (System.IO.File.Exists(path)) { return true; }
            }
            return false;
        }
        /// <summary>
        /// 安装状态
        /// </summary>
        private enum INSTALLSTATE
        {
            /// <summary>
            /// 组件禁用
            /// </summary>
            INSTALLSTATE_NOTUSED = -7,  // component disabled
            /// <summary>
            /// 配置数据已损坏
            /// </summary>
            INSTALLSTATE_BADCONFIG = -6,  // configuration data corrupt
            /// <summary>
            /// 安装已暂停或正在进行
            /// </summary>
            INSTALLSTATE_INCOMPLETE = -5,  // installation suspended or in progress
            /// <summary>
            /// 从源运行，源不可用
            /// </summary>
            INSTALLSTATE_SOURCEABSENT = -4,  // run from source, source is unavailable
            /// <summary>
            /// 返回缓冲区溢出
            /// </summary>
            INSTALLSTATE_MOREDATA = -3,  // return buffer overflow
            /// <summary>
            /// 无效的参数传递给该函数。
            /// </summary>
            INSTALLSTATE_INVALIDARG = -2,  // invalid function argument
            /// <summary>
            /// 不公布或者未安装该产品。
            /// </summary>
            INSTALLSTATE_UNKNOWN = -1,  // unrecognized product or feature
            /// <summary>
            /// 损坏
            /// </summary>
            INSTALLSTATE_BROKEN = 0,  // broken
            /// <summary>
            /// 该产品已公布但尚未安装。
            /// </summary>
            INSTALLSTATE_ADVERTISED = 1,  // advertised feature
            /// <summary>
            /// 正在移除的组件（操作状态，不可设置）
            /// </summary>
            INSTALLSTATE_REMOVED = 1,  // component being removed (action state, not settable)
            /// <summary>
            /// 不同的用户安装该产品。
            /// </summary>
            INSTALLSTATE_ABSENT = 2,  // uninstalled (or action state absent but clients remain)
            /// <summary>
            /// 安装在本地驱动器上
            /// </summary>
            INSTALLSTATE_LOCAL = 3,  // installed on local drive
            /// <summary>
            /// 从源代码、CD或网络运行
            /// </summary>
            INSTALLSTATE_SOURCE = 4,  // run from source, CD or net
            /// <summary>
            /// 为当前用户安装该产品。
            /// </summary>
            INSTALLSTATE_DEFAULT = 5,  // use default, local or source
        } 
        /// <summary>
        /// 安装的版本,是x86还是x64，还是全部安装了
        /// </summary>
        public enum InstallBit
        {
            /// <summary>
            /// 判断32位和64位运行库是否已安装
            /// </summary>
            All=0,
            /// <summary>
            ///判断32位运行库是否已安装
            /// </summary>
            X86 = 1,
            /// <summary>
            /// 判断64位运行库是否已安装
            /// </summary>
            X64 = 2
        }
        #endregion
        /// <summary>
        /// 判断是否已安装VC2005运行库
        /// </summary>
        /// <returns></returns>
        public static bool IsInstall_VC2005(InstallBit installBit)
        {
            return HaveInstallVc(installBit,new string[] { "{A49F249F-0C91-497F-86DF-B2585E8E76B7}" },
                new string[] { "{6E8E85E8-CE4B-4FF5-91F7-04999C9FAE6A}", "{ad8a2fa1-06e7-4b0d-927d-6e54b3d31028}" });
        }
        /// <summary>
        /// 判断是否已安装VC2005SP1运行库
        /// </summary>
        /// <returns></returns>
        public static bool IsInstall_VC2005SP1(InstallBit installBit)
        {
            return HaveInstallVc(installBit, "{7299052B-02A4-4627-81F2-1818DA5D550D}", "{071C9B48-7C32-4621-A0AC-3F809523288F}");
        }
        /// <summary>
        /// 判断是否已安装VC2008运行库
        /// </summary>
        /// <returns></returns>
        public static bool IsInstall_VC2008(InstallBit installBit)
        {
            return HaveInstallVc(installBit,new string[] { "{FF66E9F6-83E7-3A3E-AF14-8DE9A809A6A4}" },
                new string[] { "{350AA351-21FA-3270-8B7A-835434E766AD}", "{5FCE6D76-F5DC-37AB-B2B8-22AB8CEDB1D4}" });
        }
        /// <summary>
        /// 判断是否已安装VC2008SP1运行库
        /// </summary>
        /// <returns></returns>
        public static bool IsInstall_VC2008SP1(InstallBit installBit)
        {
            return HaveInstallVc(installBit,new string[] { "{9A25302D-30C0-39D9-BD6F-21E6EC160475}", "{9BE518E6-ECC6-35A9-88E4-87755C07200F}" },new string[] { "{8220EEFE-38CD-377E-8595-13398D740ACE}" });
        }
        /// <summary>
        /// 判断是否已安装VC2010运行库
        /// </summary>
        /// <returns></returns>
        public static bool IsInstall_VC2010(InstallBit installBit)
        {
            return HaveInstallVc(installBit, "{196BB40D-1578-3D01-B289-BEFC77A11A1E}", "{DA5E371C-6333-3D8A-93A4-6FD5B20BCC6E}");
        }
        /// <summary>
        /// 判断是否已安装VC2010SP1运行库
        /// </summary>
        /// <returns></returns>
        public static bool IsInstall_VC2010SP1(InstallBit installBit)
        {
            return HaveInstallVc(installBit, "{F0C3E5D1-1ADE-321E-8167-68EF0DE699A5}", "{1D8E6291-B0D5-35EC-8441-6616F567A0F7}");
        }
        /// <summary>
        /// 判断是否已安装VC2012运行库
        /// </summary>
        /// <returns></returns>
        public static bool IsInstall_VC2012(InstallBit installBit)
        {
            return IsInstall_VC(installBit, "mfc110.dll");
        }
        /// <summary>
        /// 判断是否已安装VC2013运行库
        /// </summary>
        /// <returns></returns>
        public static bool IsInstall_VC2013(InstallBit installBit)
        {
            return IsInstall_VC(installBit, "mfc120.dll");
        }
        /// <summary>
        /// 判断是否已安装VC2015或以上运行库
        /// </summary>
        /// <returns></returns>
        public static bool IsInstall_VC2015(InstallBit installBit)
        {
            return IsInstall_VC(installBit, "vcruntime140.dll");
        }
        /// <summary>
        /// 判断是否已安装VC2017运行库或以上运行库
        /// </summary>
        /// <returns></returns>
        public static bool IsInstall_VC2017(InstallBit installBit)
        {
            return IsInstall_VC(installBit, "vcruntime140.dll", 14.16, 27024);
        }
        /// <summary>
        /// 判断是否已安装VC2019运行库或以上运行库
        /// </summary>
        /// <returns></returns>
        public static bool IsInstall_VC2019(InstallBit installBit)
        {
            return IsInstall_VC(installBit, "vcruntime140.dll", 14.22, 27821);
        }
        /// <summary>
        /// 判断是否已安装VC2022运行库或以上运行库
        /// </summary>
        /// <returns></returns>
        public static bool IsInstall_VC2022(InstallBit installBit)
        {
            return IsInstall_VC(installBit, "vcruntime140.dll", 14.30, 30708);
        }
        /// <summary>
        /// 判断当前系统是否安装了WebView2组件
        /// </summary>
        /// <returns></returns>
        public static bool IsInstall_WebView2()
        {
            if (Environment.Is64BitOperatingSystem)
            {
                var result1 = RyRegedit.ExistKey(Microsoft.Win32.RegistryHive.LocalMachine,
                    Microsoft.Win32.RegistryView.Registry64, @"SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}");
                var result2 = RyRegedit.ExistKey(Microsoft.Win32.RegistryHive.CurrentUser,
                    Microsoft.Win32.RegistryView.Registry64, @"Software\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}");
                return result1 || result2;
            }
            else
            {
                var result1 = RyRegedit.ExistKey(Microsoft.Win32.RegistryHive.LocalMachine,
                    Microsoft.Win32.RegistryView.Registry32, @"SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}");
                var result2 = RyRegedit.ExistKey(Microsoft.Win32.RegistryHive.CurrentUser,
                    Microsoft.Win32.RegistryView.Registry32, @"Software\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}");
                return result1 || result2;
            }
        }
        /// <summary>
        /// 判断当前系统是否安装了.NET 4.8
        /// </summary>
        /// <returns></returns>
        public static bool IsInstall_NET48()
        {
            if (Environment.Is64BitOperatingSystem)
            {
                return RyRegedit.ExistKey(Microsoft.Win32.RegistryHive.LocalMachine,
                    Microsoft.Win32.RegistryView.Registry64, @"SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.8");
            }
            else
            {
                return RyRegedit.ExistKey(Microsoft.Win32.RegistryHive.LocalMachine,
                   Microsoft.Win32.RegistryView.Default, @"SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,Version=v4.8");
            }
        }
    }
}
