从另一个C#程序启动C#程序

时间:2019-03-06 10:47:57

标签: c# .net sdl sdl-2

由于我具有启动应用程序的知识,因此我知道您可以通过多种方式在C#.NET中启动应用程序,但是我遇到了尝试启动SDL2应用程序时出现的问题。

我尝试使用Process类进行以下操作:

  • 启动构建的.exe文件。
  • 使用“ cmd.exe /K”或“ cmd.exe /c”后跟“ exec”或“ call”或“ start”后跟“ {path to file}”或“ {path to batch file to launch the application}”。通过批处理文件和CMD启动应用程序可以正常工作。但是,每当我尝试启动应用程序时(即使在从cmd.exe /?启动cmd.exe?params启动的命令提示符的新实例中),也不会产生任何结果。

我可以看到的是该应用程序尝试打开。永远需要进入Window模式(启动3D环境)。超时后,它将在关闭前渲染空白窗口的几帧,或者在打开窗口后立即关闭。

所以我的问题是,是否有人成功为用C#.NET编写的SDL应用程序创建了启动器应用程序?还是知道一种调试此行为的方法?不幸的是,由于该应用程序不会发出错误消息,并且由于SDL安全地关闭了该应用程序,所以我也无法观察到崩溃。

编辑#1

我对参数没有任何幻想,因为应该没有任何参数。我已经有另一个功能可以启动普通的C#应用​​程序,因为启动器需要打开2个程序。 1个SLD应用程序,1个COM:VBA控制应用程序。 鉴于:

string audioSpectrumProgram = "AudioSpectrum.exe";
string audioSpectrumBatchProgram = "AudioSpectrum.bat";

private void BtnLaunchPPTApp_OnClick()
{
    //Powerpoint controlling application
    pVBAApp = Process.Start(presenterProgram, $"\"{this.path}\" {this.audioFormatParams[0]} {((this.ckboxGenerate.Checked) ? "--create" : "")} lang={this.languageCodesParams[this.cboxLanguage.SelectedIndex]}");
}

方法1:

private void BtnLaunchSDLApp_OnClick()
{
    pVizualizer = Process.Start(audioSpectrumProgram); //file launched from local path (is correct)
}

方法2:

pVizualizer = Process.Start(audioSpectrumBatchProgram); //file launched from local path (is correct)

方法3:

ProcessStartInfo info = new ProcessStartInfo("cmd.exe");
FileInfo spectrumFileInfo = new FileInfo(audioSpectrumProgram);
if (spectrumFileInfo.Exists)
   info.Arguments = $"/c \"{spectrumFileInfo.FullName}\"";
pVizualizer = Process.Start(info);

方法4: 基于方法3的方法。您不必使用ProcessStartInfo解析参数。

pVizualizer = Process.Start($"cmd.exe /K call \"{spectrumFileInfo.FullName}\"") //to observe what happens to the application

编辑#2

不受UseShellExecute更改为truefalse

的影响
private void btnOpenVisualizer_Click(object sender, EventArgs e)
    {
        FileInfo spectrumFileInfo = new FileInfo(audioSpectrumProgram);
        ProcessStartInfo info = new ProcessStartInfo(spectrumFileInfo.FullName);
        info.UseShellExecute = true;
        pVizualizer = new Process();
        pVizualizer.StartInfo = info;
        pVizualizer.EnableRaisingEvents = true;
        pVizualizer.Exited += new EventHandler(myProcess_Exited);
        pVizualizer.Start();
    }

    private void myProcess_Exited(object sender, System.EventArgs e)
    {
        Console.WriteLine(
            $"Exit time    : {pVizualizer.ExitTime}\n" +
            $"Exit code    : {pVizualizer.ExitCode}\n"
            );
    }

2 个答案:

答案 0 :(得分:2)

分析启动问题的一般方法是使用SysInternals Process Monitor

记录未正确启动的应用程序。为您的应用程序使用过滤器。然后在结果列中浏览所有没有SUCCESS的项目。通常,您要自下而上,因为最后一个错误是阻止您的应用程序加载的错误。

像这样,您会发现常见的启动问题,例如:

  • 缺少DLL或其他依赖项
  • 旧DLL或从错误位置加载的DLL(例如注册的COM组件)
  • 错误的工作目录,例如访问不存在的配置文件

答案 1 :(得分:1)

确定以备将来参考: 指向文件的路径可能是正确的,并且一切可能都井然有序,但是如果您使用DLL进行导入。更改进程的工作目录。

该项目将运行,可以“有时”找到库,但可能会导致类似这样的奇怪的未知错误。因此,使用SDL或任何其他类型的库运行另一个C#实例的最佳方法是:

    private void RunSDLProgram()
    {
        FileInfo spectrumFileInfo = new FileInfo("pathToFile.exe");
        ProcessStartInfo info = new ProcessStartInfo(spectrumFileInfo.FullName);
        info.RedirectStandardOutput = true;
        info.RedirectStandardError = true;
        info.UseShellExecute = false;
        info.WorkingDirectory = spectrumFileInfo.DirectoryName;
        pVizualizer = new Process();
        pVizualizer.StartInfo = info;
        pVizualizer.EnableRaisingEvents = true;
        pVizualizer.Exited += new EventHandler(myProcess_Exited);
        pVizualizer.Start();
    }

    private void myProcess_Exited(object sender, System.EventArgs e)
    {
        Console.WriteLine(
            $"Exit time    : {pVizualizer.ExitTime}\n" +
            $"Exit code    : {pVizualizer.ExitCode}\n" +
            $"output    : {pVizualizer.StandardOutput}\n" +
            $"err    : {pVizualizer.StandardError}\n" 
            );
    }

运行批处理文件将查看它自己的目录,并将所有引用设为本地,但不会更改工作目录。 (我已经怀疑要更改工作目录,但是我没有看到在process.start("cmd.exe");中调用2种操作的方法)