从.Net Windows服务打印tiff文件

时间:2022-10-30 21:22:25

We have built an application that receives several files in different formats, pdf, tiff, jpeg, doc, etc. After received, they are converted to tiff files using a third party printing driver which is installed locally on the server and set up as the default printer. In order to do that we open a System.Diagnostics.Process with the command line and arguments to print the file with the appropriate application.

我们已经构建了一个应用程序,它接收多个不同格式的文件,pdf,tiff,jpeg,doc等。收到后,它们将使用第三方打印驱动程序转换为tiff文件,该驱动程序本地安装在服务器上并设置为默认打印机。为此,我们使用命令行和参数打开System.Diagnostics.Process,以使用适当的应用程序打印文件。

Now the new version needs to be a Windows Service and so far everything is working fine, except the printing part. Whenever the process starts, it never raises an exception and everything seems to be working fine, but the file is never printed out. If I open Task Manager I can see that MS Paint was executed (in case of a jpeg file), but no output tiff file.

现在新版本需要是一个Windows服务,到目前为止一切正常,除了打印部分。每当进程启动时,它都不会引发异常,一切似乎都正常,但文件永远不会被打印出来。如果我打开任务管理器,我可以看到MS Paint已执行(如果是jpeg文件),但没有输出tiff文件。

As a side note, the final file needs to be a tiff file because of another third party tool our customer uses and that is the only format it supports.

作为旁注,最终文件需要是一个tiff文件,因为我们的客户使用的是另一个第三方工具,这是它支持的唯一格式。

Any help will be greatly appreciated. Sergio Romero

任何帮助将不胜感激。塞尔吉奥罗梅罗

The code we're using is as follows:

我们使用的代码如下:

private const string PROCESS_COMMAND = "mspaint.exe";  
private const string PROCESS_ARGUMENTS = @"""{0}""";  

Process proc = new Process();  
ProcessStartInfo startInfo = new ProcessStartInfo();  
string error = string.Empty;  

startInfo.FileName = PROCESS_COMMAND;  
startInfo.Arguments = string.Format(PROCESS_ARGUMENTS, fileFullPath);  
startInfo.UseShellExecute = false;  
startInfo.RedirectStandardError = true;  

proc.EnableRaisingEvents = false;  
proc.StartInfo = startInfo;  

proc.Start();  

using(StreamReader errorReader = proc.StandardError)  
{  
    string standardError = string.Empty;  
    while((standardError = errorReader.ReadLine()) != null)  
    {  
        error += standardError + " ";  
    }  
}  
proc.WaitForExit();

5 个解决方案

#1


3  

First thing I'd suggest is to have the service run under the context of a specific user. Then log into the server as that user and make sure that the printer is installed, set as the default, etc.

我建议的第一件事是让服务在特定用户的上下文中运行。然后以该用户身份登录服务器并确保已安装打印机,将其设置为默认值等。

Secondly, ditch the MS Paint solution to simplify things. You can load the image in .NET using System.Drawing.Image.FromFile(YourImageFilePath) and use PrintDocument to do the rest...

其次,抛弃MS Paint解决方案以简化事情。您可以使用System.Drawing.Image.FromFile(YourImageFilePath)在.NET中加载图像,并使用PrintDocument完成剩下的工作......

Create a PrintDocument object, define your settings (which printer to use, margins, etc.), add a handler for the document's PrintPage event which does something along the lines of e.Graphics.DrawImage(YourTiffImageObject, New Rectangle(0, 0, e.MarginBounds.Width, e.MarginBounds.Height)) to draw the TIFF image onto the page. Finally, you call your PrintDocument object's .Print method and away it goes.

创建一个PrintDocument对象,定义你的设置(使用哪个打印机,边距等),为文档的PrintPage事件添加一个处理程序,它执行e.Graphics.DrawImage(YourTiffImageObject,New Rectangle(0,0, e.MarginBounds.Width,e.MarginBounds.Height))将TIFF图像绘制到页面上。最后,您调用PrintDocument对象的.Print方法然后离开它。

This way, .NET is handling the printing -- not some random third-party app.

这样,.NET正在处理打印 - 而不是一些随机的第三方应用程序。

There are some minor code changes when you're dealing with more than one page at a time (primarily calling SelectActiveFrom to change the page on multi-page TIFFs and setting e.HasMorePages = True in the PrintPage event until you read the last page) but it's all fairly easily and well-documented.

当您一次处理多个页面时,会有一些小的代码更改(主要是调用SelectActiveFrom来更改多页TIFF页面并在PrintPage事件中设置e.HasMorePages = True,直到您阅读最后一页)但这一切都相当容易且记录完备。

UPDATE: Just for completeness, I guess I should add what others have already mentioned... Some applications may require desktop access to function properly. If you stick with MS Paint, you may need to enable 'Allow service to interact with desktop' in the service properties.

更新:为了完整性,我想我应该添加其他人已经提到的内容......某些应用程序可能需要桌面访问才能正常运行。如果您坚持使用MS Paint,则可能需要在服务属性中启用“允许服务与桌面交互”。

#2


0  

I'm not sure about the part about MSPaint... but if your app works as a console app but not as a service, chances are that the server doesn't have permission to do something that your user account does.

我不确定关于MSPaint的部分......但如果您的应用程序作为控制台应用程序而不是服务,则可能是服务器没有权限执行您的用户帐户所做的事情。

You might want try having the service log on as you to rule out permissions issues.

您可能希望尝试在服务登录时排除权限问题。

#3


0  

Check if the user used to install the service has the proper printing permissions AND/OR access to the files, i would also recomend using event logging

检查用于安装服务的用户是否具有正确的打印权限和/或访问文件,我还建议使用事件记录

#4


0  

Does MSPaint open when you run this from a console app? If so, its probably because your service is running headless; it doesn't have rights to display UI. So, MSPaint basically bails as it can't open its UI up without erroring.

从控制台应用程序运行时,MSPaint是否打开?如果是这样,可能是因为你的服务无头;它没有显示UI的权限。所以,MSPaint基本上是因为无法在没有错误的情况下打开它的UI而保释。

Why not just print it directly from .NET? You can do this from a service. There are some warnings about System.Printing not designed for use by a service, however. I'm not sure why, tho. I've done it without issues before...

为什么不直接从.NET打印?您可以通过服务完成此操作。但是,有一些关于System.Printing的警告并非设计用于服务。我不知道为什么,所以。我以前做过没有问题......

#5


0  

We've run into all sorts of issues with Services trying to launch apps. Often it's security/credentials being used, or it can also be something like enabling 'Allow service to interact with desktop' as the app (in this case mspaint) might need that.

我们遇到了服务试图启动应用程序的各种问题。通常使用的是安全/凭证,或者也可以是启用“允许服务与桌面交互”,因为应用程序(在本例中为mspaint)可能需要这样做。

That being said, I agree with Kevin, ditch MSPaint and either print natively within .NET or if it's just a matter of conversion, convert using .NET. The other is to look into something a little more sophisticate then MSPaint with libraries such as LibTIFF or even things like like Ghostscript to handle the formats that may not be supported natively inside .NET such as PDF.

话虽这么说,我同意凯文,沟通MSPaint并在.NET中本地打印,或者只是转换问题,使用.NET进行转换。另一个是研究一些比MSPaint更复杂的东西,比如LibTIFF这样的库,甚至像Ghostscript这样的东西来处理.NET内部可能不支持的格式,比如PDF。

#1


3  

First thing I'd suggest is to have the service run under the context of a specific user. Then log into the server as that user and make sure that the printer is installed, set as the default, etc.

我建议的第一件事是让服务在特定用户的上下文中运行。然后以该用户身份登录服务器并确保已安装打印机,将其设置为默认值等。

Secondly, ditch the MS Paint solution to simplify things. You can load the image in .NET using System.Drawing.Image.FromFile(YourImageFilePath) and use PrintDocument to do the rest...

其次,抛弃MS Paint解决方案以简化事情。您可以使用System.Drawing.Image.FromFile(YourImageFilePath)在.NET中加载图像,并使用PrintDocument完成剩下的工作......

Create a PrintDocument object, define your settings (which printer to use, margins, etc.), add a handler for the document's PrintPage event which does something along the lines of e.Graphics.DrawImage(YourTiffImageObject, New Rectangle(0, 0, e.MarginBounds.Width, e.MarginBounds.Height)) to draw the TIFF image onto the page. Finally, you call your PrintDocument object's .Print method and away it goes.

创建一个PrintDocument对象,定义你的设置(使用哪个打印机,边距等),为文档的PrintPage事件添加一个处理程序,它执行e.Graphics.DrawImage(YourTiffImageObject,New Rectangle(0,0, e.MarginBounds.Width,e.MarginBounds.Height))将TIFF图像绘制到页面上。最后,您调用PrintDocument对象的.Print方法然后离开它。

This way, .NET is handling the printing -- not some random third-party app.

这样,.NET正在处理打印 - 而不是一些随机的第三方应用程序。

There are some minor code changes when you're dealing with more than one page at a time (primarily calling SelectActiveFrom to change the page on multi-page TIFFs and setting e.HasMorePages = True in the PrintPage event until you read the last page) but it's all fairly easily and well-documented.

当您一次处理多个页面时,会有一些小的代码更改(主要是调用SelectActiveFrom来更改多页TIFF页面并在PrintPage事件中设置e.HasMorePages = True,直到您阅读最后一页)但这一切都相当容易且记录完备。

UPDATE: Just for completeness, I guess I should add what others have already mentioned... Some applications may require desktop access to function properly. If you stick with MS Paint, you may need to enable 'Allow service to interact with desktop' in the service properties.

更新:为了完整性,我想我应该添加其他人已经提到的内容......某些应用程序可能需要桌面访问才能正常运行。如果您坚持使用MS Paint,则可能需要在服务属性中启用“允许服务与桌面交互”。

#2


0  

I'm not sure about the part about MSPaint... but if your app works as a console app but not as a service, chances are that the server doesn't have permission to do something that your user account does.

我不确定关于MSPaint的部分......但如果您的应用程序作为控制台应用程序而不是服务,则可能是服务器没有权限执行您的用户帐户所做的事情。

You might want try having the service log on as you to rule out permissions issues.

您可能希望尝试在服务登录时排除权限问题。

#3


0  

Check if the user used to install the service has the proper printing permissions AND/OR access to the files, i would also recomend using event logging

检查用于安装服务的用户是否具有正确的打印权限和/或访问文件,我还建议使用事件记录

#4


0  

Does MSPaint open when you run this from a console app? If so, its probably because your service is running headless; it doesn't have rights to display UI. So, MSPaint basically bails as it can't open its UI up without erroring.

从控制台应用程序运行时,MSPaint是否打开?如果是这样,可能是因为你的服务无头;它没有显示UI的权限。所以,MSPaint基本上是因为无法在没有错误的情况下打开它的UI而保释。

Why not just print it directly from .NET? You can do this from a service. There are some warnings about System.Printing not designed for use by a service, however. I'm not sure why, tho. I've done it without issues before...

为什么不直接从.NET打印?您可以通过服务完成此操作。但是,有一些关于System.Printing的警告并非设计用于服务。我不知道为什么,所以。我以前做过没有问题......

#5


0  

We've run into all sorts of issues with Services trying to launch apps. Often it's security/credentials being used, or it can also be something like enabling 'Allow service to interact with desktop' as the app (in this case mspaint) might need that.

我们遇到了服务试图启动应用程序的各种问题。通常使用的是安全/凭证,或者也可以是启用“允许服务与桌面交互”,因为应用程序(在本例中为mspaint)可能需要这样做。

That being said, I agree with Kevin, ditch MSPaint and either print natively within .NET or if it's just a matter of conversion, convert using .NET. The other is to look into something a little more sophisticate then MSPaint with libraries such as LibTIFF or even things like like Ghostscript to handle the formats that may not be supported natively inside .NET such as PDF.

话虽这么说,我同意凯文,沟通MSPaint并在.NET中本地打印,或者只是转换问题,使用.NET进行转换。另一个是研究一些比MSPaint更复杂的东西,比如LibTIFF这样的库,甚至像Ghostscript这样的东西来处理.NET内部可能不支持的格式,比如PDF。