确定进程是否已完成打开文件

本文关键字:文件 已完成 是否 进程 | 更新日期: 2023-09-27 18:12:17

我有一个c#表单(WPF/XAML),它通过默认的文件关联触发一个新的进程来使用第三方应用程序(SAS JMP)打开一个文件:

System.Diagnostics.Process myProcess = new System.Diagnostics.Process();
myProcess.StartInfo.FileName = @"C:'temp'test.jsl";
myProcess.Start();

我正在寻找一种方法来报告回我的应用程序,进程已经启动,文件已经完成打开,或者至少,新进程的应用程序窗口已经出现。

我试图等待myProcess.Responding返回true,但在我甚至看到应用程序窗口出现之前就立即发生了。

基于Marcos Vqz de Rdz输入的方案:

bool alreadyOpen = Process.GetProcesses().Where(p => p.MainWindowHandle != IntPtr.Zero && p.ProcessName == "jmp").Count() > 0;
Process myProcess = new Process();
myProcess.StartInfo.FileName = @"C:'temp'test.jsl";
myProcess.Start();
if (!alreadyOpen)
{
    bool wait = true, timeout = false;
    DateTime start = DateTime.Now;
    while (!timeout && wait)
    {          
        timeout = (DateTime.Now - start).TotalSeconds > 10;
        var window = Process.GetProcesses().Where(p => p.Id == myProcess.Id).FirstOrDefault();
        if (window != null)
            wait = string.IsNullOrEmpty(window.MainWindowTitle);                    
    }
}

确定进程是否已完成打开文件

您试过使用Process吗?WaitForInputIdle方法?

myProcess.WaitForInputIdle();

好了,我现在唯一能想到的就是搜索新的应用程序窗口。

你可以在这里找到一些有用的东西。

发现:

var openWindowProcesses = System.Diagnostics.Process.GetProcesses().Where(p => p.MainWindowHandle != IntPtr.Zero);

在启动进程之前使用计时器来等待第三方应用程序窗口显示。

foreach (var item in openWindowProcesses)
{
    Console.WriteLine(GetWindowTitle(item.MainWindowHandle));
}
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
public static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam, uint fuFlags, uint uTimeout, out IntPtr lpdwResult);
private static string GetWindowTitle(IntPtr windowHandle)
{
    uint SMTO_ABORTIFHUNG = 0x0002;
    uint WM_GETTEXT = 0xD;
    int MAX_STRING_SIZE = 32768;
    IntPtr result;
    string title = string.Empty;
    IntPtr memoryHandle = System.Runtime.InteropServices.Marshal.AllocCoTaskMem(MAX_STRING_SIZE);
    System.Runtime.InteropServices.Marshal.Copy(title.ToCharArray(), 0, memoryHandle, title.Length);
    SendMessageTimeout(windowHandle, WM_GETTEXT, (IntPtr)MAX_STRING_SIZE, memoryHandle, SMTO_ABORTIFHUNG, (uint)1000, out result);
    title = System.Runtime.InteropServices.Marshal.PtrToStringAuto(memoryHandle);
    System.Runtime.InteropServices.Marshal.FreeCoTaskMem(memoryHandle);
    return title;
}

来源:c#获取进程窗口标题