C# 在发送打印命令(按“Ctrl&”x2B“P”按钮)后,我如何知道应该等待PrintDialog多长时间?

C# 在发送打印命令(按“Ctrl&”x2B“P”按钮)后,我如何知道应该等待PrintDialog多长时间?,c#,vbscript,automation,console,C#,Vbscript,Automation,Console,我正在使用C#编写一个控制台应用程序,其中通过代码启动打印作业。我的问题是,在发送打印命令后,我不知道应该等待打印对话框多长时间。目前我正在使用1000毫秒的线程睡眠 //Sending Commands to Print(to press "Ctrl+P" button). SendKeys.SendWait("^(p)"); Thread.Sleep(1000); //Sending Commands to Print(to press "Enter" Button). Send

我正在使用C#编写一个控制台应用程序,其中通过代码启动打印作业。我的问题是,在发送打印命令后,我不知道应该等待打印对话框多长时间。目前我正在使用1000毫秒的线程睡眠

//Sending Commands to Print(to press "Ctrl+P" button).
 SendKeys.SendWait("^(p)");

 Thread.Sleep(1000);

 //Sending Commands to Print(to press "Enter" Button).
 SendKeys.SendWait("{ENTER}");
有人能帮我解决这个问题吗。任何帮助都将不胜感激

提前谢谢

更新:

这是我的全部代码:

//Launch the file from the location specified in.
White.Core.Application application =White.Core.Application.Launch(@path);

Console.WriteLine("launch is done");

Thread.Sleep(_delayOfPrint);

//Sending Commands to Print(to press "Ctrl+P" button).
SendKeys.SendWait("^(p)");

Thread.Sleep(1000);

//Sending Commands to Print(to press "Enter" Button).
SendKeys.SendWait("{ENTER}");

//Get the current time as the document fired for print job.
_printedTime = DateTime.Now;

Thread.Sleep(1500);

//Closing the window.
SendKeys.SendWait("%{F4}");

我将有几秒钟的最大等待时间,但在这段时间内,我会定期使用Win32函数FindWindowEx来查看打印对话框是否确实出现,如果出现,请继续。您可以使用如下代码获得进程的主窗口:

Process[] processes = Process.GetProcessesByName(appName);
foreach (Process p in processes)
{
     IntPtr pFoundWindow = p.MainWindowHandle;
}
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className,  IntPtr windowTitle);
然后,您可以将找到的主窗口句柄传递给FindWindowEx,以仔细查看子窗口以检查打印对话框。FindWindowEx的PInvoke签名如下:

Process[] processes = Process.GetProcessesByName(appName);
foreach (Process p in processes)
{
     IntPtr pFoundWindow = p.MainWindowHandle;
}
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className,  IntPtr windowTitle);
编辑2:因为OP似乎要求我提供一个完美的工作函数,所以我编写了一个通用函数来实现这个技巧并进行了测试。这里是等待任何子窗口的通用代码。在这种情况下,以WaitForChildWindow(“myApp”,“Print”,5000)的身份调用:

/// <summary>
/// Wait for a child window of an application to appear
/// </summary>
/// <param name="appName">Application name to check (will check all instances)</param>
/// <param name="childWindowName">Name of child window to look for (titlebar)</param>
/// <param name="timeout">Maximum time, in milliseconds, to wait</param>
/// <returns>True if the window was found; false if it wasn't.</returns>
public static bool WaitForChildWindow(string appName, string childWindowName, int timeout)
{
    int sleepTime = timeout;
    while (sleepTime > 0)
    {
        Process[] processes = Process.GetProcessesByName(appName);
        foreach (Process p in processes)
        {
            IntPtr pMainWindow = p.MainWindowHandle;
            IntPtr pFoundWindow = FindWindowEx(pMainWindow, IntPtr.Zero, null, childWindowName);
            if (pFoundWindow != IntPtr.Zero)
                return true;
        }
        Thread.Sleep(100);
        sleepTime -= 100;
    }

    // Timed out!
    return false;
}

我将有几秒钟的最大等待时间,但在这段时间内,我会定期使用Win32函数FindWindowEx来查看打印对话框是否确实出现,如果出现,请继续。您可以使用如下代码获得进程的主窗口:

Process[] processes = Process.GetProcessesByName(appName);
foreach (Process p in processes)
{
     IntPtr pFoundWindow = p.MainWindowHandle;
}
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className,  IntPtr windowTitle);
然后,您可以将找到的主窗口句柄传递给FindWindowEx,以仔细查看子窗口以检查打印对话框。FindWindowEx的PInvoke签名如下:

Process[] processes = Process.GetProcessesByName(appName);
foreach (Process p in processes)
{
     IntPtr pFoundWindow = p.MainWindowHandle;
}
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className,  IntPtr windowTitle);
编辑2:因为OP似乎要求我提供一个完美的工作函数,所以我编写了一个通用函数来实现这个技巧并进行了测试。这里是等待任何子窗口的通用代码。在这种情况下,以WaitForChildWindow(“myApp”,“Print”,5000)的身份调用:

/// <summary>
/// Wait for a child window of an application to appear
/// </summary>
/// <param name="appName">Application name to check (will check all instances)</param>
/// <param name="childWindowName">Name of child window to look for (titlebar)</param>
/// <param name="timeout">Maximum time, in milliseconds, to wait</param>
/// <returns>True if the window was found; false if it wasn't.</returns>
public static bool WaitForChildWindow(string appName, string childWindowName, int timeout)
{
    int sleepTime = timeout;
    while (sleepTime > 0)
    {
        Process[] processes = Process.GetProcessesByName(appName);
        foreach (Process p in processes)
        {
            IntPtr pMainWindow = p.MainWindowHandle;
            IntPtr pFoundWindow = FindWindowEx(pMainWindow, IntPtr.Zero, null, childWindowName);
            if (pFoundWindow != IntPtr.Zero)
                return true;
        }
        Thread.Sleep(100);
        sleepTime -= 100;
    }

    // Timed out!
    return false;
}

我想你想等到论文出来再继续吗?使用计时来跟踪非常重要,尤其是在网络打印机中。有一个打印机假脱机,或者更确切地说是一个打印队列。所以如果有文件的话,时间肯定不准确。网络打印机必须考虑这个+网络latency@C_Rance:谢谢你的评论,但我的模块只是自动打印一些文档,我不会为打印机滑阀处理任何事情。我想你想等到纸张用完后再继续吗?使用计时来跟踪非常重要,尤其是在网络打印机中。有一个打印机假脱机,或者更确切地说是一个打印队列。所以如果有文件的话,时间肯定不准确。网络打印机必须考虑这个+网络latency@C_Rance:谢谢你的评论,但是我的模块只是自动打印一些文档,我没有为打印机spool处理任何事情。谢谢你的回答,但我仍然不清楚。你能给我一些更具描述性的回答吗?我更新了我上面的问题以供参考。Process[]processs=Process.GetProcessesByName(“记事本”);这是我需要打印的应用程序的进程列表吗?是的,而且oops,这是一个打字错误,应该是appName。让我来编辑。对不起,但是FindWindowEx(pFoundWindow,null,null,“Print”);抛出错误“FindWindowEx的最佳重载方法(System.IntPtr,System.IntPtr,string,System.IntPtr)有一些无效参数”好的,虽然这应该是我给你的想法,但我编写并测试了一个通用版本,因为我发现它很有用。我现在的答案是这样的。谢谢你的回答,但我还是不清楚。你能给我一些更具描述性的回答吗?我更新了我上面的问题以供参考。Process[]processs=Process.GetProcessesByName(“记事本”);这是我需要打印的应用程序的进程列表吗?是的,而且oops,这是一个打字错误,应该是appName。让我来编辑。对不起,但是FindWindowEx(pFoundWindow,null,null,“Print”);抛出错误“FindWindowEx的最佳重载方法(System.IntPtr,System.IntPtr,string,System.IntPtr)有一些无效参数”好的,虽然这应该是我给你的想法,但我编写并测试了一个通用版本,因为我发现它很有用。我现在的答案是这样的。