Запуск программы на C # из другой программы на C # - PullRequest
2 голосов
/ 06 марта 2019

Благодаря тому, что у меня есть знания по запуску приложений, я знаю, что у вас есть несколько способов запуска приложений в 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 работает нормально. Но всякий раз, когда я пытаюсь даже запустить приложение (даже в новом экземпляре Command-Prompt, запущенном из параметров cmd.exe /? Start cmd.exe?), Это не дает результата.

Что я могу наблюдать, так это то, что приложение пытается открыть. Требуется вечность, чтобы перейти в оконный режим (запуск 3D-среды). По истечении времени ожидания он либо визуализирует пару кадров пустого окна перед закрытием, либо закрывает сразу после открытия окна.

Итак, мой вопрос: кто-нибудь успешно создал приложение запуска для приложения SDL, написанного на C # .NET? Или знает способ отладки этого поведения? Потому что, к сожалению, приложение не отправляет сообщение об ошибке, и, поскольку 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: основанный на senario метода 3. Вам не нужно анализировать аргументы, используя ProcessStartInfo.

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

Редактировать # 2

Не влияет изменение UseShellExecute на true или false

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 ]

2 голосов
/ 06 марта 2019

Общий способ анализа проблем при запуске - это использование SysInternals Process Monitor .

Запишите приложение, которое не запускается должным образом. Используйте фильтр для вашего приложения. Затем просмотрите все элементы, которые не имеют SUCCESS в столбце результатов. Как правило, вы хотите сделать это снизу вверх, так как последняя ошибка останавливает загрузку вашего приложения.

Как это, вы найдете общие проблемы запуска, такие как:

  • отсутствуют библиотеки DLL или другие зависимости
  • старые библиотеки DLL или библиотеки DLL, загруженные из неправильного расположения (например, зарегистрированные компоненты COM)
  • неверный рабочий каталог, например доступ к несуществующим файлам конфигурации
1 голос
/ 06 марта 2019

ОК Для использования в будущем: Путь к файлам может быть правильным, и все может быть в порядке, но если вы используете DLL для импорта. Измените рабочий каталог процесса.

Проект запустится, библиотеки иногда можно найти, но они могут вызвать странную неизвестную ошибку, подобную этой. Поэтому наиболее оптимальный способ запуска другого экземпляра C # с SDL или любой другой библиотекой:

    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" 
            );
    }

Запуск командного файла будет смотреть на его собственный каталог и делает все ссылки локальными, но это не изменит рабочий каталог. (у меня уже были подозрения об изменении рабочего каталога, но я не видел способа вызвать 2 операции в process.start("cmd.exe");)

...