简体   繁体   English

如何在C#中捕获命令提示符过程并在此之后执行某些操作?

[英]how to catch command prompt process finish in C# and do something after that?

I am working with voice records. 我正在处理语音记录。 I need to use an .exe file for convert Wav to .mp3 file. 我需要使用.exe文件将Wav转换为.mp3文件。 Everything is fine I can execute this exe but I need to do something after when process end with my output .mp3 file. 一切都很好,我可以执行此exe,但是当进程以我的输出.mp3文件结束时,我需要做一些事情。 I know my output directory but i cant handle MP3 file before its not created yet. 我知道我的输出目录,但在尚未创建MP3文件之前无法处理。 I know maybe I need to use Thread.sleep(); 我知道也许我需要使用Thread.sleep(); or something like that because I cant catch a file before its not exist. 或类似的东西,因为我无法在文件不存在之前捕获它。

Here is my code: 这是我的代码:

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

I was try to use process.WaitForExit(); 我试图使用process.WaitForExit(); but I cant solve this problem. 但我不能解决这个问题。 I still cant acces to mp3 file. 我仍然无法访问mp3文件。

so how can I catch when the process finish? 那么如何在过程完成时捕获?

Best Regards. 最好的祝福。

Remove the start command argument from your argument string and you should be able to use process.WaitForExit(); 从参数字符串中删除start命令参数,您应该可以使用process.WaitForExit(); to wait for Lame to finish with encoding: 等待Lame完成编码:

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


However, you can simplify your code and avoid this dance with cmd.exe altogether by starting lame.exe directly: 但是,您可以通过直接启动lame.exe来简化代码并完全避免与cmd.exe发生这种冲突:

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



Below some information about why using the start command argument in your scenario is counterproductive. 下面的一些信息说明为什么在您的方案中使用start命令参数会适得其反。

Executing console applications such as lame.exe using cmd.exe (or from a console or batch file) normally block cmd.exe (or console/batch file) until the console application exits. 使用cmd.exe(或从控制台或批处理文件)执行控制台应用程序(例如lame.exe)通常会阻塞cmd.exe(或控制台/批处理文件),直到控制台应用程序退出。

However, using the start command turns this normally blocking execution of a console application into a non-blocking execution. 但是,使用start命令会将通常阻止控制台程序执行的操作转换为非阻止执行。 With this argument, the cmd.exe (or console/batch file) will continue execution while the console application is still running. 使用此参数,在控制台应用程序仍在运行时,cmd.exe(或控制台/批处理文件)将继续执行。 In your particular case it means cmd.exe will exit right after it has started lame.exe (since it has nothing else to execute), effectively sabotaging your attempt to wait for lame.exe to finish. 在您的特定情况下,这意味着cmd.exe将在启动lame.exe之后立即退出(因为它没有其他要执行的操作),从而有效地破坏了您等待lame.exe完成的尝试。

Edited: 编辑:

Base on the comments below I have to make it clear that the oroginal solution I recommended does not check if the file is free but it checks only if the file exists ! 根据下面的评论,我必须明确指出,我建议的原始解决方案不检查文件是否空闲,而是仅检查文件是否存在 So I rather recommend the following: 因此,我建议以下内容:

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

the usage will be: 用法将是:

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

ORIGINAL: You can use a while loop to find out when the file is ready: 原文:您可以使用while循环来查找文件准备就绪的时间:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM