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

Launching C# program from another C# program

由于我了解启动应用程序,我知道您可以通过多种方式在 C# .NET 中启动应用程序,但我 运行 遇到了尝试启动 SDL2 时出现的问题申请。

我尝试使用过程 class 进行以下操作:

我观察到的是应用程序尝试打开。启动到 Window 模式(启动 3D 环境)需要很长时间。超时后,它会在关闭之前渲染几帧空白 window 或在打开 window.

后立即关闭

所以我的问题是,有没有人成功地为用 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]}");
}

方法一:

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

方法二:

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

方法三:

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

方法四: 基于方法 3 的 senario。您不必使用 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"
            );
    }

好的供将来参考: 文件的路径可能是正确的,一切都可能是有序的,但如果您使用 DLL 进行导入。更改进程的工作目录。

该项目将 运行,可以 "sometimes" 找到库,但可能会导致像这样的奇怪的未知错误。因此,运行使用 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 个操作的方法)

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

记录未正常启动的应用程序。为您的应用程序使用过滤器。然后遍历结果列中没有 SUCCESS 的所有项目。通常您希望自下而上执行此操作,因为最后一个错误会阻止您的应用程序加载。

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

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