как отловить процесс командной строки в C # и что-то сделать после этого? - PullRequest
0 голосов
/ 12 октября 2018

Я работаю с голосовыми записями.Мне нужно использовать .exe файл для конвертирования Wav в .mp3 файл.Все хорошо, я могу выполнить этот exe, но мне нужно что-то делать после того, как процесс завершится с моим выходным файлом .mp3.Я знаю свой выходной каталог, но я не могу обработать файл MP3, пока он еще не создан.Я знаю, может быть, мне нужно использовать Thread.sleep(); или что-то в этом роде, потому что я не могу поймать файл, пока он не существует.

Вот мой код:

string mp3GuidName = Guid.NewGuid().ToString();
var mp3FilePath = WavFilePath.Replace("finalWavFile", mp3GuidName).Replace("wav", "mp3");
var extrasFilePath = HttpContext.Current.Server.MapPath("/").Replace("DevApp.Web", "Extras");

string strArguments = "/c start " +  extrasFilePath + "lame.exe --abr 80 -V5 " + WavFilePath + " " + mp3FilePath;

System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.FileName = "cmd.exe";
startInfo.Arguments =  strArguments ;
process.StartInfo = startInfo;
process.Start();
var attactment = new Attachment
    {
        CreatedOn = DateTime.Now,
        UpdatedOn = DateTime.Now,
        Title = mp3GuidName +".mp3",
        Size = _storageProvider.GetFile(mp3FilePath).GetSize(), // here I am trying to get mp3 file but i cant catch it. Because if this wav files size is huge, then convert process is taking time and my mp3 file is not created yet.
        FileExtension = _storageProvider.GetFile(mp3FilePath).GetFileType()
    };
attactment.MimeType = _storageProvider.GetMimeType(attactment.FileExtension);
attactment.FileUrl = mp3GuidName+".mp3";// file.GetName();
attactment.AttachmentFolderId = folder.Id;
_attachmentRepository.Add(attactment);

Я пытался использоватьprocess.WaitForExit(); но я не могу решить эту проблему.Я до сих пор не могу получить доступ к mp3-файлу.

так как я могу поймать, когда процесс завершится?

С наилучшими пожеланиями.

Ответы [ 2 ]

0 голосов
/ 12 октября 2018

Удалите аргумент команды start из строки аргумента, и вы сможете использовать process.WaitForExit();, чтобы дождаться, пока Lame завершит кодировку:

string strArguments = "/c " +  extrasFilePath + "lame.exe --abr 80 -V5 " + WavFilePath + " " + mp3FilePath;


Однако вы можете упроститьсвой код и избегайте этого танца с cmd.exe, запустив lame.exe напрямую:

string strArguments = "--abr 80 -V5 " + WavFilePath + " " + mp3FilePath;
...
startInfo.FileName = extrasFilePath + "lame.exe";
startInfo.Arguments = strArguments;
...



Ниже приведена информация о том, почему используется команда startАргумент в вашем сценарии является контрпродуктивным.

Выполнение консольных приложений, таких как lame.exe, с использованием cmd.exe (или из консольного или пакетного файла) обычно блокирует cmd.exe (или консольный / пакетный файл) до консольного приложенияexits.

Однако использование команды start превращает это обычно блокирующее выполнение консольного приложения в неблокирующее выполнение.С этим аргументом cmd.exe (или консольный / пакетный файл) продолжит выполнение, пока консольное приложение все еще работает.В вашем конкретном случае это означает, что cmd.exe завершит работу сразу после запуска lame.exe (поскольку ему больше нечего выполнять), что саботирует вашу попытку дождаться завершения lame.exe.

0 голосов
/ 12 октября 2018

Отредактировано:

Основываясь на комментариях ниже, я должен дать понять, что рекомендованное мной оригинальное решение не проверяет, является ли файл свободным , но онопроверяет только, существует ли файл !Поэтому я скорее рекомендую следующее:

private bool IsBusy(FileInfo file)
{
    FileStream stream = null;

    try
    {
        stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None);
    }
    catch ()
    {
        return true;
    }
    finally
    {
        if (stream != null)
            stream.Close();
    }
    return false;
}

использование будет:

while(IsBusy(fileinfo))
{
     //just wait
}

ORIGINAL: Вы можете использовать цикл while, чтобы узнать, когда файлготов:

while(!File.Exists(mp3FileName))
{
     //just wait
}
// add the attachment here
...