Process.Start() 报错:系统找不到指定文件

Posted Nemo_XP

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Process.Start() 报错:系统找不到指定文件相关的知识,希望对你有一定的参考价值。

今天在工作中遇到调用浏览器打开页面,代码报错:System.ComponentModel.Win32Exception:“系统找不到指定的文件。”
代码如下:

                ProcessStartInfo info = new ProcessStartInfo(@"chrome.exe");
                // 打开一个新的chrome独立窗体启动
                info.Arguments = " --new-window  --start-maximized  --kiosk  " + m_Url;
                // 使用环境变量,可以读取配置了环境变量文件夹内的chrome.exe
                info.UseShellExecute = true;
                info.WindowStyle = ProcessWindowStyle.Minimized;
                System.Diagnostics.Process.Start(info);

这段代码,若不报错,有着苛刻的条件,如
1.安装了chrome后,chrome自动或个人手动把chrome.exe的文件夹路径配置到环境变量Path里。如下:

2.安装的chrome可能在System32文件夹内产生Chrome.exe
这也就是,写了这样的代码有的机器能正常调出浏览器,有些则会报错的原因。

经过多次尝试,我们使用Win+R运行Chrome.exe,在任何情况都可以调出浏览器,可能它会通过注册表获取浏览器的安装路径,找到Chrome.exe打开,而我们的Process.Start(info)却没有这么智能。所以我们的解决方案就是要通过注册表找到浏览器的绝对路径,然后打开它。
以下是helper类

  public static class BrowserHelper
    
        #region 打开浏览器
        /// <summary>
        /// 打开浏览器
        /// </summary>
        /// <param name="url">uri地址</param>
        /// <param name="browser">浏览器类型</param>
        public static void OpenBrowserUrl(string url, BrowserType browser = BrowserType.Default)
        
            //FuncLog4Helper.Error($"调用浏览器:browser.ToString() url地址:url", "IPNW");
            try
            
                switch (browser)
                
                    case BrowserType.Chrome:
                        OpenChrome(url);
                        break;
                    case BrowserType.InternetExplorer:
                        OpenInternetExplorer(url);
                        break;
                    case BrowserType.FireFox:
                        OpenFireFox(url);
                        break;
                    case BrowserType.Default:
                    default:
                        OpenDefaultBrowserUrl(url);
                        break;
                
            
            catch (Exception ex)
            
                LoggerHelper.Error("调用浏览器报错", ex);
            
        
        #endregion

        #region 调用谷歌浏览器
        /// <summary>
        /// 调用谷歌浏览器
        /// </summary>
        /// <param name="url">打开网页的链接</param>
        private static void OpenChrome(string url)
        
            try
            
                string appPath = GetChromePath();
                var result = default(Process);
                if (!string.IsNullOrWhiteSpace(appPath) && File.Exists(appPath))
                    result = Process.Start(appPath, url);
                if (result == null)
                
                    result = Process.Start("chrome.exe", url);
                    if (result == null)
                    
                        OpenDefaultBrowserUrl(url);
                    
                
            
            catch
            
                // 出错调用用户默认设置的浏览器,还不行就调用IE
                OpenDefaultBrowserUrl(url);
            
        
        #endregion

        #region 用IE打开浏览器
        /// <summary>
        /// 用IE打开浏览器
        /// </summary>
        /// <param name="url"></param>
        private static void OpenInternetExplorer(string url)
        
            try
            
                Process.Start("iexplore.exe", url);
            
            catch (Exception ex)
            
                LoggerHelper.Error("调用浏览器报错", ex);
                // IE浏览器路径安装:C:\\Program Files\\Internet Explore
                try
                
                    string executeName = "iexplore.exe";
                    string iePath = $@"C:\\Program Files\\Internet Explorer\\executeName";
                    if (!File.Exists(iePath))
                    
                        iePath = $@"C:\\Program Files (x86)\\Internet Explorer\\executeName";
                        if (!File.Exists(iePath))
                        
                            iePath = GetExecutePath(executeName);
                            if (!File.Exists(iePath))
                                iePath = string.Empty;
                        
                    

                    if (string.IsNullOrWhiteSpace(iePath))
                    
                        if (MessageBox.Show(@"系统未安装IE浏览器,是否下载安装?", null, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) == DialogResult.Yes)
                        
                            // 打开下载链接,从微软官网下载
                            OpenDefaultBrowserUrl("http://windows.microsoft.com/zh-cn/internet-explorer/download-ie");
                        
                        return;
                    

                    ProcessStartInfo processStartInfo = new ProcessStartInfo
                    
                        FileName = iePath,
                        Arguments = url,
                        UseShellExecute = false,
                        CreateNoWindow = true
                    ;
                    Process.Start(processStartInfo);
                
                catch (Exception e)
                
                    MessageBox.Show(e.Message);
                
            
        
        #endregion

        #region 打开系统默认浏览器(用户自己设置了默认浏览器)
        /// <summary>
        /// 打开系统默认浏览器(用户自己设置了默认浏览器)
        /// </summary>
        /// <param name="url"></param>
        private static void OpenDefaultBrowserUrl(string url)
        
            Process result = null;
            try
            
                result = Process.Start(url);
            
            catch (Exception ex)
            
                LoggerHelper.Error("调用浏览器报错", ex);
                OpenInternetExplorer(url);
            
        
        #endregion

        #region 火狐浏览器打开网页
        /// <summary>
        /// 火狐浏览器打开网页
        /// </summary>
        /// <param name="url"></param>
        private static void OpenFireFox(string url)
        
            try
            
                var result = default(Process);
                string executeName = "firefox.exe";
                string appPath = GetExecutePath(executeName);
                if (!string.IsNullOrWhiteSpace(appPath) && File.Exists(appPath))
                
                    result = Process.Start(appPath, url);
                
                if (result == null)
                
                    //64位注册表路径
                    var openKey_64 = @"SOFTWARE\\Wow6432Node\\Mozilla\\Mozilla Firefox";
                    RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(openKey_64);
                    appPath = registryKey?.GetValue(string.Empty)?.ToString();
                    if (string.IsNullOrWhiteSpace(appPath))
                    
                        //32位注册表路径
                        var openKey_32 = @"SOFTWARE\\Mozilla\\Mozilla Firefox";
                        registryKey = Registry.LocalMachine.OpenSubKey(openKey_32);
                        appPath = registryKey?.GetValue(string.Empty)?.ToString();
                    
                    if (!string.IsNullOrWhiteSpace(appPath))
                        result = Process.Start(appPath, url);
                
                // 谷歌浏览器就用谷歌打开,没找到就用系统默认的浏览器
                // 谷歌卸载了,注册表还没有清空,程序会返回一个"系统找不到指定的文件。"的bug
                if (result == null)
                
                    result = Process.Start(executeName, url);
                    if (result == null)
                    
                        OpenDefaultBrowserUrl(url);
                    
                
            
            catch
            
                // 出错调用用户默认设置的浏览器,还不行就调用IE
                OpenDefaultBrowserUrl(url);
            
        
        #endregion

        #region 注册表中获取可执行文件路径
        /// <summary>
        /// 注册表中获取可执行文件路径
        /// </summary>
        /// <param name="executeName">可执行文件名称</param>
        /// <returns></returns>
        public static string GetExecutePath(string executeName)
        
            if (string.IsNullOrWhiteSpace(executeName))
                return string.Empty;
            string strKeyName = string.Empty;
            string appPath = string.Empty;
            if (executeName.IndexOf(".exe", StringComparison.OrdinalIgnoreCase) == -1)
                executeName = $"executeName.exe";
            string softPath = $@"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\executeName";
            RegistryKey regSubKey = Registry.LocalMachine.OpenSubKey(softPath, false);
            if (regSubKey != null)
            
                object objResult = regSubKey.GetValue(strKeyName);
                RegistryValueKind regValueKind = regSubKey.GetValueKind(strKeyName);
                if (regValueKind == RegistryValueKind.String)
                
                    appPath = objResult?.ToString();
                
            
            return appPath;
        
        #endregion

        #region 获取Chorme浏览器路径
        /// <summary>
        /// 获取Chorme浏览器路径
        /// </summary>
        /// <returns></returns>
        public static string GetChromePath()
        
            string chormePath = string.Empty;
            try
            
                string chromeAppKey = @"\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe";
                chormePath = (Registry.GetValue("HKEY_LOCAL_MACHINE" + chromeAppKey, "", null) ?? Registry.GetValue("HKEY_CURRENT_USER" + chromeAppKey, "", null))?.ToString();
                if (!string.IsNullOrWhiteSpace(chormePath) && File.Exists(chormePath))
                    return chormePath;
                chormePath = $@"Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)\\Google\\Chrome\\Application\\chrome.exe";
                //win10默认安装路径
                if (!string.IsNullOrWhiteSpace(chormePath) && File.Exists(chormePath))
                    return chormePath;
                string executeName = "chrome.exe";
                chormePath = GetExecutePath(executeName);
                if (!string.IsNullOrWhiteSpace(chormePath) && File.Exists(chormePath))
                    return chormePath;
                // 64位注册表路径
                var openKey_64 = @"SOFTWARE\\Wow6432Node\\Google\\Chrome";
                RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(openKey_64);
                chormePath = registryKey?.GetValue(string.Empty)?.ToString();
                if (!string.IsNullOrWhiteSpace(chormePath) && File.Exists(chormePath))
                    return chormePath;

                var openKey_32 = @"SOFTWARE\\Google\\Chrome";
                registryKey = Registry.LocalMachine.OpenSubKey(openKey_32);
                chormePath = registryKey?.GetValue(string.Empty)?.ToString();
                if (!string.IsNullOrWhiteSpace(chormePath) && File.Exists(chormePath))
                    return chormePath;
            
            catch (Exception e)
            
                Console.WriteLine(e);
                throw;
            
            return chormePath;
        
        #endregion
    
    public enum BrowserType
    
        [Description("客户默认浏览器")]
        Default = 0,
        [Description("谷歌浏览器")]
        Chrome = 1,
        [Description("IE浏览器")]
        InternetExplorer = 2,
        [Description("火狐浏览器")]
        FireFox = 3,
    

以下是调用代码

BrowserHelper.OpenBrowserUrl("www.baidu.com", BrowserType.Chrome);

以上是关于Process.Start() 报错:系统找不到指定文件的主要内容,如果未能解决你的问题,请参考以下文章

Process.Start 为什么会引发“系统找不到指定的文件”异常

使用 ChildProcess 启动进程时“系统找不到指定的文件”

csharpcodeprovider:不能使用 Process.Start()

Process.Start(url) 失败

Process.Start 问题启动我的游戏

是否有任何与 Process.Start 等效的异步?