如何使用 C# 自动化一堆打印作业?

发布于 2024-12-11 08:00:08 字数 351 浏览 0 评论 0原文

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

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

I am developing an automation tool which is reading the file path from an Excel workbook and after launching the application I am firing print job using SendKeys.SendWait() for Ctrl+P and Enter key. Now the Problem is, I am facing synchronization issue for launching the application and handling the print procedure keys. Sometimes Applications are launching little late(like Excel and MsWord files), so at that time I am not able to find till how long I have to wait for a successful launch of the Application. Anybody have any Idea how to check this waiting time till how long I should wait to fire CTRL+P and then after getting PrintDialog ENTER button ?

Any help will be appreciate. Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

如此安好 2024-12-18 08:00:08

我最初将这个问题理解为仅打印 MS 类型文件。如果你想打印各种文件,那么我会首先利用 Windows 的“PrintTo”功能。

您可以通过在注册表中搜索 PrintTo 来直接调用命令,您应该会看到 PrintTo 和 Print 的命令。上网了解每个应用程序的具体信息。

另一个可能最简单的选项是将 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”应该只发送到默认设备。

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

I initially read the question as only printing MS type files. If you want to print all kinds of files then I would first leverage Windows 'PrintTo' function.

You can call the commands directly by searching the Registry for PrintTo and you should see commands for PrintTo and also Print. Hit the web for specifics for each application.

The other option that is probably the simplest is to use the PrintTo verb with ShellExecute and let Windows handle the behind the scenes.

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 should allow you to specify the printer while the verb "Print" should just send to the default device.

Keep in mind that not all filetypes support these verbs.

生活了然无味 2024-12-18 08:00:08

为了确定要自动化的应用程序是否准备好接受用户输入(击键),您必须搜索处理您将发送的击键的应用程序窗口。完成该任务需要相当多的互操作。下面您将看到一个自动执行 Excel 文档打印任务的小示例(省略了所有错误处理详细信息)。
我已从 pinvoke.net 复制了互操作签名。

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

  1. 使用 Excel 主窗口的类名搜索 Excel 主窗口。使用spy++等工具来确定类名。
  2. 将 Excel 主窗口置于前台。
  3. CTRL+C 发送到主窗口以打开打印对话框。
  4. 等待打印对话框出现。
  5. ENTER 发送到打印对话框。

其次,让我向您展示一个小代码示例:

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

button_click 方法包括等待 Excel 窗口出现的步骤。如果找到指定的窗口,则发送密钥。

希望这有帮助。

In order to determine whether or not the application to automate is ready to accept user input (key strokes) you have to search for the window of the application processing the key strokes you will send. There is quite a bit interop necessary to accomplish the task. Below you will find a small example automating the task of printing an excel document (all error handling details omitted).
I've copied the interop signatures from pinvoke.net.

First, let me describe the necessary steps:

  1. Search for the excel main window using the class name of the excel main window. Use a tool like spy++ to determine the class name.
  2. Bring the excel main window to the foreground.
  3. Send CTRL+C to the main window to open the print dialog.
  4. Wait for the print dialog to appear.
  5. Send ENTER to the print dialog.

Second, let me show you a small code example:

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

The button_click methods includes the steps to wait for the Excel windows to appear. If the specified window is found the keys are sent.

Hope, this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文