当 运行 来自另一个程序的程序时无法加载配置文件

Cannot load config files when running the program from another program

我创建了一个 WinFrom 应用程序,版本 .exe 位于某个目录中,比方说,

C:\App\bin\Release\WinFormApp.exe

在应用程序目录中,我有一些配置文件以 XML 格式编写并存储在目录的 Config 子文件夹中:

C:\App\bin\Release\Config\MyConfig1.xml
C:\App\bin\Release\Config\MyConfig2.xml
C:\App\bin\Release\Config\MyConfig3.xml

然后我在应用程序的 .cs 文件中有一个 private field 存储配置文件所在的默认子目录名称:

private string configFoldername = "Config";

因此,当应用程序为 运行 时,它将首先使用 FileStreamXMLSerializer 加载配置文件,如下所示:

filestream = new FileStream(Path.Combine(configFoldername, "MyConfig1.xml"), FileMode.Open, FileAccess.Read, FileShare.Read);
serializer = new XmlSerializer(typeof(MyAppConfig1));

//... some others

filestream = new FileStream(Path.Combine(configFoldername, "MyConfig2.xml"), FileMode.Open, FileAccess.Read, FileShare.Read);
serializer = new XmlSerializer(typeof(MyAppConfig2));

//... some others

filestream = new FileStream(Path.Combine(configFoldername, "MyConfig3.xml"), FileMode.Open, FileAccess.Read, FileShare.Read);
serializer = new XmlSerializer(typeof(MyAppConfig3));

//... some others

到目前为止一切顺利。应用程序 运行 没有问题。但随后我为我的应用程序创建了一个简单的 watcher 程序来检查它是否 运行ning 正常,如果不是,则观察者将重新启动该程序。我的watcher程序中的相关部分如下所示:

//In the Watcher program
Process process = new Process();
process.StartInfo.FileName = @"C:\App\bin\Release\WinFormApp.exe";          
process.Start();

当我发现我的应用程序这次无法加载配置文件时,我感到很惊讶。序列化器失败,显示文件不存在。但是,如果我 运行 程序不是来自 watcher,而是直接 运行ning 应用程序,则完全没有问题。

尝试替换:

private string configFoldername = "Config";

与:

private string configFoldername = Path.Combine(Application.StartupPath, "Config");

或设置process.StartInfo.WorkingDirectory:

process.StartInfo.WorkingDirectory = @"C:\App\bin\Release\";

问题出在 FileStream 调用:

filestream = new FileStream(Path.Combine(configFoldername, "MyConfig1.xml"), FileMode.Open, FileAccess.Read, FileShare.Read);

给定的路径使用相对路径,仅给出 configFoldername 而不是完整路径。

因此,令人惊讶的是,当 WinForm 程序是 运行 来自另一个程序(Watcher)时 FileStream默认路径将是 Watcher 的应用程序路径而不是 WinForm 的应用程序路径,这使得 FileStream 无法从正确的文件夹中获取文件。

为了解决这个问题,我使用绝对路径而不是相对路径。在WinForm应用程序的初始化中,我使用Application.StartupPath获取WinForm应用程序的绝对路径。

private string configFoldername = "Config";
private string configFolderpath; //declare new variable here

...and in the initialization

string root = Application.StartupPath;
configFolderpath = Path.Combine(root, configFoldername); //making this having the absolute path.

然后新的反序列化看起来像这样:

filestream = new FileStream(Path.Combine(configFolderpath, "MyConfig1.xml"), FileMode.Open, FileAccess.Read, FileShare.Read);
serializer = new XmlSerializer(typeof(MyAppConfig1));

//... some others

filestream = new FileStream(Path.Combine(configFolderpath, "MyConfig2.xml"), FileMode.Open, FileAccess.Read, FileShare.Read);
serializer = new XmlSerializer(typeof(MyAppConfig2));

//... some others

filestream = new FileStream(Path.Combine(configFolderpath, "MyConfig3.xml"), FileMode.Open, FileAccess.Read, FileShare.Read);
serializer = new XmlSerializer(typeof(MyAppConfig3));

//... some others

现在好了。