Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用C#自动化大量打印作业?_C#_Vb.net_Visual Studio_Printing_Automation - Fatal编程技术网

如何使用C#自动化大量打印作业?

如何使用C#自动化大量打印作业?,c#,vb.net,visual-studio,printing,automation,C#,Vb.net,Visual Studio,Printing,Automation,我正在开发一个自动化工具,它正在从Excel工作簿读取文件路径,启动应用程序后,我正在使用SendKeys.SendWait()forCtrl+p和Enter键启动打印作业。现在的问题是,我面临启动应用程序和处理打印过程键的同步问题。有时应用程序启动有点晚(如Excel和MsWord文件),所以在那个时候,我无法找到我要等待多久才能成功启动应用程序。有没有人知道如何检查这个等待时间,直到我需要等待多长时间才能启动CTRL+P,然后在获得PrintDialog输入按钮之后 任何帮助都将不胜感激。提

我正在开发一个自动化工具,它正在从Excel工作簿读取文件路径,启动应用程序后,我正在使用
SendKeys.SendWait()
for
Ctrl+p
Enter键启动打印作业。现在的问题是,我面临启动应用程序和处理打印过程键的同步问题。有时应用程序启动有点晚(如Excel和MsWord文件),所以在那个时候,我无法找到我要等待多久才能成功启动应用程序。有没有人知道如何检查这个等待时间,直到我需要等待多长时间才能启动
CTRL+P
,然后在获得
PrintDialog
输入
按钮之后


任何帮助都将不胜感激。提前谢谢。

我最初认为这个问题只是打印MS类型的文件。如果你想打印所有类型的文件,那么我会首先利用Windows的“PrintTo”功能

您可以通过在注册表中搜索PrintTo直接调用这些命令,您应该可以看到PrintTo和Print的命令。点击web了解每个应用程序的详细信息

另一个可能最简单的选项是将PrintTo动词与ShellExecute一起使用,并让Windows处理幕后事务

System.Diagnostics.Process print = new System.Diagnostics.Process();
print.StartInfo.FileName = @"c:\test\test.pdf";
print.StartInfo.Verb = "PrintTo";
print.StartInfo.CreateNoWindow = True;
print.StartInfo.Arguments = printerName;
print.StartInfo.UseShellExecute = True;
print.Start();
print.WaitForExit();
PrintTo应允许您指定打印机,而动词“Print”应仅发送到默认设备


请记住,并非所有文件类型都支持这些动词。

为了确定要自动执行的应用程序是否准备好接受用户输入(按键),您必须搜索处理要发送的按键的应用程序窗口。完成这项任务需要相当多的互操作。下面是一个自动打印excel文档的小示例(所有错误处理细节都被省略)。 我已经从中复制了互操作签名

首先,让我描述一下必要的步骤:

  • 使用excel主窗口的类名搜索excel主窗口。使用spy++之类的工具确定类名
  • 将excel主窗口置于前台
  • CTRL+C发送到主窗口以打开打印对话框
  • 等待打印对话框出现
  • 发送进入打印对话框
  • 其次,让我向您展示一个小代码示例:

    private enum WindowShowStyle : uint    
    {     
      Hide = 0,
      ShowNormal = 1,
      ShowMinimized = 2,
      ShowMaximized = 3,
      Maximize = 3,
      ShowNormalNoActivate = 4,
      Show = 5,
      Minimize = 6,
      ShowMinNoActivate = 7,
      ShowNoActivate = 8,
      Restore = 9,
      ShowDefault = 10,
      ForceMinimized = 11
    }
    
    [DllImport("user32.dll", SetLastError = true)]
    private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    
    [DllImport("user32.dll")]
    private static extern bool ShowWindow(IntPtr hWnd, WindowShowStyle nCmdShow);
    
    [DllImport("user32.dll")]
    private static extern bool BringWindowToTop(IntPtr hWnd);
    
    [DllImport("kernel32.dll")]
    private static extern uint GetCurrentThreadId();
    
    [DllImport("user32.dll")]
    private static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);
    
    [DllImport("user32.dll")]
    private static extern IntPtr GetForegroundWindow();       
    
    [DllImport("user32.dll", SetLastError = true)]
    private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
    
    private static void BringWindowToForeground(IntPtr hWnd)
    {
      uint foregroundThread, currentThread;
    
      uint pid;
      foregroundThread = GetWindowThreadProcessId(GetForegroundWindow(), out pid);
      currentThread    = GetCurrentThreadId();
    
      if (foregroundThread != currentThread)
      {
        AttachThreadInput(foregroundThread, currentThread, true);
    
        BringWindowToTop(hWnd);
        ShowWindow(hWnd, WindowShowStyle.ShowMaximized);                
        AttachThreadInput(foregroundThread, currentThread, false);
      }
      else
      {
        BringWindowToTop(hWnd);
        ShowWindow(hWnd, WindowShowStyle.ShowMaximized);
      }
    }
    
    private void button1_Click(object sender, EventArgs e)
    {
       // Find excel window.
       IntPtr hWnd;
       while (true) 
       {
         hWnd = FindWindow("XLMAIN", null); // XLMAIN is the class name
                                            // of the main excel window.
         if (hWnd != IntPtr.Zero)
           break;
       }
    
       BringWindowToForeground(hWnd);
       SendKeys.SendWait("^p"); // Send CTRL+P to main excel window
    
       // Find print dialog.
       while (true)
       {
         hWnd = FindWindow("bosa_sdm_XL9", null); // bosa_sdm_XL9 is the class name
                                                  // of the print dialog.
         if (hWnd != IntPtr.Zero)
           break;
       }
    
       BringWindowToForeground(hWnd);
    
       SendKeys.SendWait("~"); // Send ENTER to print dialog.
     }
    
    单击按钮的
    方法包括等待Excel窗口出现的步骤。如果找到指定的窗口,则会发送密钥


    希望,这有帮助。

    像这样的东西怎么样:[[1]:是的,很酷。但我们仍然只打印Excel工作表,我们如何打印所有类型的文档,如pdf、msWord等…+1,用于隐藏解决方案,而不仅仅是回答问题。@Douglas Anderson:非常感谢您的帮助,但它将直接打印,我不想打印。我想打开应用程序并处理它“印刷品”打印对话框的按钮。@SharpUrBrain:那么您希望打印对话框出现,然后按Enter键?这不是达到相同的结果吗?还是希望用户进行干预?@Douglas Anderson:不,它没有达到相同的结果,因为我正在连接打印机驱动程序,以获取打印信息来更新一个xml文件,所以如果我正在打印直接打印文档时,我无法连接打印机驱动程序,也无法获取打印信息。而且,我也无法使用web应用程序打印它们。