为什么Process.Start(ProcessStartInfo)失败?

问题描述:

我们开发了一个新的WPF应用程序,并且我很难从外部C#脚本启动它。为什么Process.Start(ProcessStartInfo)失败?

虽然调用Process.Start(ProcessStartInfo)方法有与两个WorkingDirectoryFileName成功初始化ProcessStartInfo对象,初始化所述FileName属性仅启动失败。

调用任何其他应用程序时情况并非如此。
我的问题 - 启动过程的不同方法是否有不同的逻辑?

详情请参见代码:

public void LaunchApp(){ 
/********************************/ 
/*  This code PASSES  */ 
/********************************/ 
var pStartInfoCalc1 = new ProcessStartInfo 
    { 
     FileName = @"C:\Windows\system32\calc.exe", 
    }; 

Process.Start(pStartInfoCalc1); 

/*****************************/ 
/* !!!This code FAILS !!! */ 
/*****************************/ 
var pStartInfo1 = new ProcessStartInfo 
    { 
     FileName = @"C:\Program Files\MyAppFolder\MyApp.exe", 
    }; 

Process.Start(pStartInfo1); 

/********************************/ 
/*  This code PASSES  */ 
/********************************/ 
var pStartInfo2 = new ProcessStartInfo 
    { 
     WorkingDirectory = @"C:\Program Files\MyAppFolder", 
     FileName = @"MyApp.exe", 
    }; 

Process.Start(pStartInfo2); 

/********************************/ 
/*  This code PASSES  */ 
/********************************/ 
var pStartInfoCalc2 = new ProcessStartInfo 
    { 
     WorkingDirectory = @"C:\Windows\system32\", 
     FileName = @"calc.exe", 
    }; 

Process.Start(pStartInfoCalc2); }` 

这是图像,因为它崩溃了: enter image description here

而以下是从崩溃截图的问题签名:

Problem signature: 
    Problem Event Name: CLR20r3 
    Problem Signature 01: MyApp.exe 
    Problem Signature 02: 1.0.0.0 
    Problem Signature 03: 51ef9fd8 
    Problem Signature 04: mscorlib 
    Problem Signature 05: 4.0.30319.18052 
    Problem Signature 06: 5173bf28 
    Problem Signature 07: 266d 
    Problem Signature 08: a4 
    Problem Signature 09: System.Windows.Markup.XamlParse 
    OS Version: 6.1.7601.2.1.0.256.4 
    Locale ID: 1033 
    Additional Information 1: 1989 
    Additional Information 2: 1989c043e2e04efdbf18835c58bb867b 
    Additional Information 3: 37d3 
    Additional Information 4: 37d31c18f56cf3083b1c45ca83bbb78e 

Read our privacy statement online: 
    http://go.microsoft.com/fwlink/?linkid=104288&clcid=0x0409 

If the online privacy statement is not available, please read our privacy statement offline: 
    C:\Windows\system32\en-US\erofflps.txt 
+1

我觉得_Program Files_文件夹受OS保护作为默认值。 –

+3

合理的第一个猜测是:有问题的应用程序希望在其工作目录中找到特定的文件 - 如果没有,它会因错误处理不当而崩溃。 – Jon

+0

['UseShellExecute']的值是什么(http://msdn.microsoft.com/zh-cn/library/system.diagnostics.processstartinfo.useshellexecute.aspx)*当UseShellExecute为false时,不使用WorkingDirectory属性找到可执行文件* – V4Vendetta

如果不指定工作目录,则新进程将继承进程的工作目录。也就是说,新进程将继承调用Process.Start()的进程的工作目录。

这是两次尝试启动MyApp的唯一区别。其中一个继承了工作目录,其中一个指定了它。很明显,MyApp不喜欢以最初的工作目录作为父进程的目录运行。

为什么会这样,我不能肯定地说。看起来MyApp在启动时正在尝试一些XML解析。所以也许这个XML解析读取一个推测在工作目录中的文件。但实际上该文件与可执行文件位于同一目录中。

如果是这种情况,那么您需要修改MyApp来解决问题。您不需要为此XML文件使用相对路径,而是需要根据可执行文件的目录构建绝对路径。

MyApp启动代码可以在目录中,像这样:

string ExeDir = System.IO.Path.GetDirectoryName(System.Reflection.Assembly. 
    GetExecutingAssembly().Location)); 

然后你会用Path.Combine形成完整路径XML文件。

+0

感谢您的回复 –

当您不提供工作目录时,它将使用您当前的应用程序。

诸如calc之类的应用程序没有任何外部文件依赖性,因此它们不关心它们从何处启动。他们不需要从工作目录中读取任何文件。

您的MyApp.exe很可能需要来自其自己的工作目录(可能是配置文件)的数据。该测试通过,因为它知道如何寻找在C:\Program Files\MyAppFolder

/********************************/ 
/*  This code PASSES  */ 
/********************************/ 
var pStartInfo2 = new ProcessStartInfo 
{ 
    WorkingDirectory = @"C:\Program Files\MyAppFolder", 
    FileName = @"MyApp.exe", 
}; 

Process.Start(pStartInfo2); 

如果不指定应用程序崩溃的工作目录,因为,因为它试图找到它在你的目录无法加载所需资源启动应用程序。

如果你知道的话,最好在启动应用程序时提供工作目录。

如果您可以更新MyApp.exe它可以使用System.Reflection.Assembly.GetExecutingAssembly().Location来确定它自己的位置,那么您可以读取与此相关的文件路径,从而无需设置工作目录。

+0

我不同意您建议的解决方案。依赖于工作目录中的配置文件是问题的根源。正确的解决方案是查看执行程序集的目录。 –

+0

@DavidHeffernan如果你知道如何提供一个工作目录,你不同意吗?我也建议'MyApp.exe'让自己知道它自己的位置,我也看到你也包含了这个。 – Scott

+0

我不同意MyApp依靠工作目录。这不健壮。您的原始版本没有执行装配的地址。 –