【发布时间】:2012-06-26 13:18:03
【问题描述】:
我知道它是许多论坛和博客中的一个已知主题。我读了很多文章。他们中的许多人都安静地提供信息。但对我来说,完成这项任务似乎需要新的方法。
我正在寻找在服务器端打印 html 的解决方案。但是在使用了许多选项后,我意识到我们
- 无法提供打印机名称或
- 其打印 html 原始内容,如 txt 文件
后来知道ghostscript (https://stackoverflow.com/a/2600189/1238159) 可以在服务器端静默打印PDF。
还尝试使用水晶报告(但如何动态地将 HTML 内容传递给它,即使它不支持许多标签)、itextsharp、ssrs、pdfsharp 等,但它们都不支持许多 HTMl 标签和 W3C 标准。所以我在某一时刻结束了生成PDF。只有 wkhtmltopdf 非常适合将 html 转换为 pdf。根据我的经验,它支持每个 html 标签,这与其他任何标签都不一样。但是打印 PDf 是我多年以来的问题。
但现在即使使用 GhostScript(我使用的是 9.05 版)也面临问题。使用 localhost 我可以完美地使用它。我可以在服务器端以静默方式打印来自 UI 的任何打印机名称。但使用 IP 地址或机器名称无法正常工作。我什至实施了模拟。即使进程在调用 GhostScript 时挂起。
现在我想弄清楚的是
- 是否可以在服务器端打印 html 或 pdf(实际内容)?
- 任何开源工具都可以实现这一目标
- 我想动态传递的打印机名称
任何线索或解决方法都可能帮助全球数小时的人们。 :)
非常感谢。
问候, 帕万N
在使用了刘的建议之后。我能够在命令提示符下执行此操作(意味着 cmd.exe 在我的帐户下运行)。但我的应用程序将在网络服务下运行。 现在我遇到了一个问题ACCESS Denied
是的。最后我能够开始这个过程。并且能够使用我的域凭据在任务管理器下查看我的 gswin32c.exe 进程。代码如下:
public bool PrintVSPDF(string ghostScriptPath, int numberOfCopies, string printerName, string pdfFileName)
{
Logger.AddToLog("printerName", printerName);
string impersonationUsername = "";
string impersonationDomain = "";
string impersonationPWD = "";
if (ConfigurationManager.AppSettings["UName"] != null)
{
impersonationUsername = Encryption.Decrypt(ConfigurationManager.AppSettings["UName"].ToString(), Encryption.DEFAULT_KEY, Encryption.DEFAULT_SEED);
impersonationDomain = impersonationUsername.Split('\\').Count() > 1 ? impersonationUsername.Split('\\')[0] : "";
impersonationUsername = impersonationUsername.Split('\\').Count() > 1 ? impersonationUsername.Split('\\')[1] : impersonationUsername.Split('\\')[0];
}
if (ConfigurationManager.AppSettings["PD"] != null)
{
impersonationPWD = Encryption.Decrypt(ConfigurationManager.AppSettings["PD"].ToString(), Encryption.DEFAULT_KEY, Encryption.DEFAULT_SEED);
}
using (Impersonation imp = new Impersonation(impersonationUsername, impersonationDomain, impersonationPWD))
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.Arguments = "-dPrinted -dNoCancel -dNOPAUSE -dBATCH -dNumCopies=" + Convert.ToString(numberOfCopies) + " -sDEVICE=mswinpr2 -sOutputFile=%printer%\"" + printerName + "\" \"" + pdfFileName + "\" ";
startInfo.FileName = ghostScriptPath;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
//startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardOutput = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.UserName = impersonationUsername;
startInfo.Domain = impersonationDomain;
SecureString ss = new SecureString();
for (int i = 0; i < impersonationPWD.Length; i++)
{
ss.AppendChar(impersonationPWD[i]);
}
startInfo.Password = ss;
Process process = null;
try
{
process = Process.Start(startInfo);
//Logger.AddToLog("Error VS", process.StandardError.ReadToEnd());
//Logger.AddToLog("Output VS", process.StandardOutput.ReadToEnd());
//Logger.AddToLog(process.StartInfo.Arguments.ToString(), "VS Print Arguments");
//Console.WriteLine(process.StandardError.ReadToEnd() + process.StandardOutput.ReadToEnd());
//Logger.AddToLog(process.StartInfo.FileName.ToString(), "VS Print file name");
process.WaitForExit(30000);
if (process.HasExited == false)
process.Kill();
int exitcode = process.ExitCode;
process.Close();
return exitcode == 0;
}
catch (Exception ex)
{
Logger.AddToLog(ex);
return false;
}
}
}
但该过程在 localhost:5030 中运行良好,即在我的 Visual Studio 中运行时。但带有 IP 地址或机器名称。它只是挂起并引发此错误
adobe reader、foxit等也发生了同样的事情。
( Process must exit before requested information can be determined. : at System.Diagnostics.Process.EnsureState(State state)
at System.Diagnostics.Process.get_ExitCode() )
【问题讨论】:
-
我对“打印服务器端”的意思感到困惑。打印机连接在哪里?您是在谈论从远程 Web 服务器向用户的本地打印机发起打印吗?
-
“打印服务器端”表示我正在尝试在服务器端(即 IIS)打印由 XML+XSL 生成的 HTML 字符串。是的,打印机已连接到 IIS 服务器。它是一个 Intranet 应用程序。
标签: c# wcf printing server-side ghostscript