Delphi “快速报告抛出”;当前没有选择默认打印机";例外情况

Delphi “快速报告抛出”;当前没有选择默认打印机";例外情况,delphi,windows-services,printing,Delphi,Windows Services,Printing,我已经创建了一个Delphi服务来打印TQuickReports。如果编译并作为Windows应用程序运行,则一切正常。但是当转换为作为服务运行时,尝试创建包含TQuickRep组件的表单会引发异常 这项服务在许多其他盒子上都可以正常运行,但在这一个盒子上就不行了。以下是一些细节: 使用QuickReport 4.07版 Box是Windows Server 2008操作系统 使用Delphi2007 打印机.Printers.Count正在返回正值。事实上,我可以列出所有的打印机 我已经尝试

我已经创建了一个Delphi服务来打印TQuickReports。如果编译并作为Windows应用程序运行,则一切正常。但是当转换为作为服务运行时,尝试创建包含TQuickRep组件的表单会引发异常

这项服务在许多其他盒子上都可以正常运行,但在这一个盒子上就不行了。以下是一些细节:

  • 使用QuickReport 4.07版
  • Box是Windows Server 2008操作系统
  • 使用Delphi2007
  • 打印机.Printers.Count正在返回正值。事实上,我可以列出所有的打印机
  • 我已经尝试使用本地系统帐户和以管理员身份登录来运行该服务

会话0中是否设置了默认打印机?请记住,在Vista/Server 2008/Windows 7下,服务在单独的会话中运行。登录用户是否具有默认打印机设置并不相关-这是每个会话的设置,不会影响会话0


您能否重新编写代码,以优雅地处理该异常并选择要使用的打印机?

您可以为用户提供一种选择服务打印机的方法。Windows服务可能没有默认打印机设置


设置
TQuickRep.PrinterSettings.PrinterIndex
以设置打印机编号。然后,
TQuickRep.Print
打印报告。

一位同事最终找到了解决方案。我应该加上这些是“网络”打印机,而不是本地打印机(当时我认为这与问题无关)。因此,该服务需要在“登录”选项卡下安装“NetworkService”作为用户帐户。从Windows帮助:

要指定服务使用网络服务帐户,请单击此帐户,然后单击 然后键入NT AUTHORITY\NetworkService


如果在多个会话中使用terminal services 2008,则应查看以下内容:

HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows\SessionDefaultDevices\Session_ID 
而不是

HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows\

我们这里有一个类似的问题。使用TS服务器、Citrix和Powerfuse 9。 Powerfuse的所有打印机都是大写的,但它们是混合使用的。 这种组合导致Delphi/QReport崩溃


当所有打印机在同一情况下从printserver到powerfuse时(不重要的上限或下限,甚至不混合),问题就消失了

您可以通过创建一个新的dwordUserSelectedDefault来解决此问题,该值为:1 in HKEY\U当前\U用户\软件\ Microsoft\Windows NT\CurrentVersion\Windows\SessionDefaultDevices\Session\U ID

确保选择了本地打印机。

实际上这是一个Delphi(5)问题。可用打印机与默认打印机的比较区分大小写(printers.pas):

将比较更改为: 如果
小写(tpinterdevice(Objects[I]).Device)=小写(Device)

解决了这个问题。

我解决了一个类似的问题:如果Delphi应用程序(或服务)使用QuickReport,它将在系统加载默认打印机之前运行

  • 当QuickReport执行
    TQRPrinter.Init
    时,
    printer.printers.count
    为零
  • 系统加载后不久,
    printer.printers.count
    是打印机的数量
  • 但是
    tqrprinter.int
    已经执行,因此
    tqrprinter.FPrinterOK
    为false
  • 然后,当您尝试打开QuickReport时,会看到此错误

我的解决方案是等待打印机加载后再启动应用程序(在citrix和终端服务器中)。我用两种方法解决了这个问题,一种是覆盖
tqrprinter
,另一种是延迟
dpr
,事实上这正是我们要做的。本质上,打印机是由名称指定的,然后我们有一个例程,它将扫描printer.Printers数组并返回整数。问题是我甚至不能达到这一点;我甚至不能创建TQuickRep实例。@M Schenkel似乎是个bug,但解决方法可能是在创建TQuickRep对象之前设置默认打印机。您能在错误发生的地方发布代码吗?我们在Marcus Adams建议的通过Windows服务打印快速报告的解决方案上实现了一个变体,并且没有看到您在Windows 2008上所做的错误。这对我来说是新的。不,我不知道有“会议”。我如何处理特定的“会话”?我认为另一个答案解决了问题。但请记住这一点。使用本地打印机(即使没有实际连接的打印机)可以解决此问题。
if TPrinterDevice(Objects[I]).Device = Device then
begin
   with TPrinterDevice(Objects[I]) do
      SetPrinter(PChar(Device), PChar(Driver), PChar(Port), 0);
   Exit;
end;