为什么使用Process.Start会使启动的应用从父应用位置运行,而不是从启动的应用';的实际位置
本文关键字:应用 位置 启动 Process Start 运行 为什么 | 更新日期: 2023-09-27 18:26:05
我遇到了一个问题,在另一个应用程序的exe文件上使用Process.Start
会导致该应用程序警告丢失的文件,然后崩溃。经过一点测试和调试,在使用Process.Start
时,它看起来像是从启动它的父程序的位置运行目标exe,而不是从该exe实际所在的位置运行。
为什么会发生这种情况?这是故意设计的吗?不用说,这完全打乱了你运行的目标应用程序,那么应该如何使用这种启动另一个exe的方法呢?
这里有一个例子来说明这个问题:
让我们创建一个简单的小应用程序,搜索文件并打印"成功"(如果找到)和"失败"(如果没有)。
using System;
using System.IO;
using System.Windows.Forms;
namespace Testapp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
if (File.Exists(@".'test'test.txt"))
{
MessageBox.Show("Program executed successfully");
}
else
{
MessageBox.Show("Program failed to execute properly");
}
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
}
上述程序的预期文件夹结构如下:
Testapp Folder
->Testapp.exe
->Test Folder
->test.txt
程序进入Test文件夹(如果存在),并搜索Test.txt文件。
现在,让我们制作一个快速启动应用程序,用于运行我们的测试应用程序:
using System;
using System.Diagnostics;
using System.Windows.Forms;
namespace LaunchTestApp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
Process.Start(@".'Testapp.exe");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
}
上面的应用程序旨在与我们的Testapp.exe位于同一目录中。当以这种方式运行时,一切都会非常顺利。Launchapp
运行我们的Testapp
,我们可以点击Testapp
中的按钮,看到一个消息框,表明程序已成功执行。
但是,现在让我们对我们的启动应用程序进行一点更改。我们的启动应用程序现在将位于Testapp.exe之上的一个目录级别上,如下所示:
Launching App Folder
->Launchapp.exe
->Testapp Folder
->Testapp.exe
->Test Folder
->Test.txt
当然,我们也会将Launchapp更改为将Testapp.exe定位在不同的目录中,如下所示:
Process.Start(@".'Testapp'Testapp.exe");
现在,当Launchapp
运行,并因此运行Testapp.exe
时,我们按下按钮,Testapp.exe
将显示一条消息,表明程序未能正确运行。
在这一点上,如果我们回到Testapp
代码,并将搜索test.txt的位置从.'test'test.txt'
更改为.'Testapp'test'test.txt
,那么程序将成功运行。
这表明Testapp
exe似乎是从Launchapp
的位置运行的,而不是从Testapp
exe实际所在的位置运行。
为什么会发生这种情况,我该如何防止这种情况发生?我希望能够运行与调用应用程序所在文件夹不同的文件夹中的应用程序,因此,启动的进程从该进程所在的位置运行,而不是从调用应用程序的位置运行显然很重要。
进程默认继承启动它们的进程的工作文件夹。这只是windows的工作方式(是的,它是故意这样做的,其他操作系统的行为也一样)。
可以使用ProcessStartInfo
的.WorkingDirectory
属性从其他路径启动它。http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo(v=vs.110).aspx
在没有任何其他明确指令的情况下,它将始终使用父进程的环境。这就是它的工作原理。如果要为新进程指定文件系统上的工作位置,请使用接受ProcessStartInfo
实例的重载。这允许您设置工作文件夹以及许多其他值。
您滥用了术语"run from"。
运行任何程序时,除非另有指定,否则其当前目录是其父进程的当前目录。
通常(从资源管理器或命令提示符),这是包含EXE文件的目录。
如果您从自己的程序启动它,它将是程序的当前目录。
您可以在StartOptions中显式传递任意当前目录。
这样使用:
ProcessStartInfo startInfo=新的ProcessStartInfo();
startInfo.UseShellExecute=false;
startInfo.WorkingDirectory=@"目录";
Process.start(startInfo);