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

时间:2014-07-10 17:47:27

标签: c# wpf windows .net-4.0

我有一个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);                    
    }
}

1 个答案:

答案 0 :(得分:1)

您是否尝试过使用Process.WaitForInputIdle Method

myProcess.WaitForInputIdle();

<强>更新

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

你可以找到有用的东西here

<强>更新

找到this

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# Get process window titles