zoukankan      html  css  js  c++  java
  • 警惕使用System.Environment.CurrentDirectory遇到的坑

    今天调试程序的时候遇到一个大坑,程序A(exe)通过Process Start启动程序B(exe)进程,总是报错。

    from clipboard

    上图是程序结构,为了让所有的程序B实例共享配置,所以把app.ini放在了bin的上级目录。

    启动进程代码:

     

    1. System.Diagnostics.Process p = new System.Diagnostics.Process();
    2. p.StartInfo = new ProcessStartInfo(fileName);
    3. p.Start();

    最后定位到配置文件路径读取问题。这是System.Environment.CurrentDirectory遇到大坑。

    程序B中有一下代码是用于获取app.ini中的配置:

     

    1. DirectoryInfo topDir = Directory.GetParent(System.Environment.CurrentDirectory);
    2. string iniFileName = Path.Combine(topDir.FullName, "app.ini");

    问题症状:

    通过程序A启动B,报错。但是通过单独启动程序B正常。

    后来发现System.Environment.CurrentDirectory确实是获取当前目录没错,但是如果A程序调用B程序,当B程序里使用了System.Environment.CurrentDirectory获取目录。那么这个B程序里获取的这个目录就不再是B的应用程序所在目录了;而变成了A所在的目录了。

    解决方案:

    1、使用Application.StartupPath获取目录,需要引用:using System.Windows.Forms,因此这个方法只能用于winform程序。

    2、使用AppDomain.CurrentDomain.BaseDirectory,通用方案,可以用于类库。

    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    后来发现很多网友和我遇到过一样的问题。

    下面引用一下网友写的文章:

    https://blog.csdn.net/albert528108/article/details/102958457

    1. // 获取程序的基目录。
    2. System.AppDomain.CurrentDomain.BaseDirectory
    3. // 获取模块的完整路径。
    4. System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName
    5. // 获取和设置当前目录(该进程从中启动的目录)的完全限定目录。
    6. System.Environment.CurrentDirectory
    7. // 获取应用程序的当前工作目录。
    8. System.IO.Directory.GetCurrentDirectory()
    9. // 获取和设置包括该应用程序的目录的名称。
    10. System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase
    11. // 获取启动了应用程序的可执行文件的路径。
    12. System.Windows.Forms.Application.StartupPath
    13. // 获取启动了应用程序的可执行文件的路径及文件名
    14. System.Windows.Forms.Application.ExecutablePath

    我以前写的代码中获取当前路径基本上都是使用的System.Environment.CurrentDirectory。

    但是最近在用另外一个程序A去调用以前的程序B的时候就出现问题了,程序A的作用只是单纯调取程序B的exe文件,在B执行过程中总是真到当前路径这块就出现了问题,实际找到的路径是程序A的路径。

        程序A目录:D:a
        程序B目录:D:
        当程序A调用程序B时,程序B中的Environment.CurrentDirectory结果是D:a,而不是D:!!

    经反复测试发现System.Environment.CurrentDirectory确实是获取当前目录没错,但是如果A程序调用B程序 B程序里使用了System.Environment.CurrentDirectory获取目录。那么这个B程序里获取的这个目录就不再是B的应用程序所在目录了;而变成了A所在的目录了。这也就不难发现我在开机时弹出的目录是C:WindowsSystem32 因为开机自启动程序也是由windows的某个进程调用的。

    当遇到这样的情况时,我自己的解决方案是:

    把所有System.Environment.CurrentDirectory改成System.AppDomain.CurrentDomain.BaseDirectory。

    网上也有很多人说针对winform可以改成Application.StartupPath。

    C# WinForm中AppDomain.CurrentDomain.BaseDirectory与Application.StartupPath的区别示例如下:

        1. AppDomain.CurrentDomain.BaseDirectory 返回结果为: D:xxx
        Application.StartupPath 返回结果为: D:xxx
        2. Application.StartupPath 只能用于WinForm窗体中,而AppDomain.CurrentDomain.BaseDirectory既可以用于WinForm窗体中,也可以用于类库DLL文件中。

  • 相关阅读:
    搭建vue项目脚手架
    vue项目中的iconfont图标下载及配置
    vue-awesome-swiper 轮播图的使用
    IDEA自动生成Mapper和实体文件
    云服务器通过IP如何访问项目
    社保,步入社会的第一步
    Memcached安装与启动
    IDEA提示非法字符,你不懂的UTF-8
    MyEclipse导入eclipse的web项目,将WebRoot切换为WebContent
    Myeclipse2017删除tomcat后,项目全部报错的解决办法
  • 原文地址:https://www.cnblogs.com/soundcode/p/13987007.html
Copyright © 2011-2022 走看看