当 运行 来自另一个程序的程序时无法加载配置文件
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";
因此,当应用程序为 运行 时,它将首先使用 FileStream
和 XMLSerializer
加载配置文件,如下所示:
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
现在好了。
我创建了一个 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";
因此,当应用程序为 运行 时,它将首先使用 FileStream
和 XMLSerializer
加载配置文件,如下所示:
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
现在好了。