XpsocumenWriter挂起Windows服务,但在控制台上运行时工作正常



我有一个窗口服务,用于执行各种作业,其中之一是打印通过WPF生成的文档。当运行控制台应用程序时,它运行良好,但当从windows服务运行时,它只是挂起。

让我稍微解释一下窗口服务。为了最大限度地减少任何可能的副作用,Windows服务只是实际控制台的包装器。因此,当Window Service启动时(在其启动方法中),有一个简单的Process.start调用来调用控制台,如下所示:

Process.Start("[path_to_my_console_exe]");

现在,当调用打印代码时,它只是挂起。我正在使用PrintDialog API打印文档。打印文档的调用很简单:

var printDialog = new PrintDialog();                
printDialog.PrintDocument(doc.DocumentPaginator);

当PrintDocument被命中时,它将阻止执行(方法永远不会结束)。

所以,我做了一些调查。谷歌搜索给了我一些提示,所以

  • 我确保Windows服务使用与独立控制台相同的权限运行
  • 我确保Windows服务作为x64进程运行,与独立控制台相同
  • 我尝试调试PrintDialog.PrintDocument方法。我直接从referencesource下载了代码,它给了我一个新的见解,但不幸的是,这也没有解决问题,它只是进一步指出了哪个方法阻止了执行(它是XpsDocumentWriter.Writer方法,第460行)

现在,在所有这些之后,我确信这一定是关于权限的问题。尽管Windows服务使用同一用户作为独立控制台应用程序(管理员用户)运行,但在我看来,它仍然不具备所需的所有权限。这里的Windows服务有什么特别之处吗?我是不是遗漏了什么,在运行控制台之前,还有其他应该为Windows服务设置的内容吗?

我解决了这个问题,所以如果有人遇到同样的情况,下面是发生的事情。

为了测试该应用程序,我使用的是Microsoft pdf打印机,所以当控制台作为独立应用程序运行时(而不是通过服务),当使用Microsoft pdf打印机时,它会在最后显示一个对话框,询问文件名和位置。这可能会起作用,因为我可以看到一个对话框并按下按钮。但是,当通过Windows服务运行相同的控制台,并使用相同的打印机(Microsof pdf)进行打印时,它会挂起,原因是服务属性"Alow Service to interactive with desktop"。默认情况下,这是错误的,因此在注册服务时,任何用户交互都不可见,在我的情况下,它正是PrintDialog挂起的地方,因为它正在等待用户输入来保存pdf。换成真正的打印机后,一切都像预期的那样运转。

解决这个问题的另一种方法是使用不同的打印API,它可以在没有用户交互的情况下工作(通过编程传递参数)。

相关内容

最新更新