不从服务器端打印的 PDF 文档 ASP.NET 应用程序
PDF Documents Not Printing from Server-Side ASP.NET App
前言:
我们正在开发一套应用程序(移动和桌面),它利用由 ASP.NET 应用程序 运行 在 Windows Server 2008 R2 上维护的 restapi 服务器。我们在后端集成的功能之一是打印功能,它从我们的 SSRS 服务中提取 pdf,然后打印到网络打印机。
有很多关于静默打印和利用不同产品的线程,这些解决方案中的大多数都在我的本地机器上运行 (Windows 10);然而,当我们将代码移动到我们的服务器时,我们发现部分代码执行但文档从未到达打印机。
我们的代码:
private async Task<bool> Print(string filename, string printer)
{
var processFilename = Microsoft.Win32.Registry.LocalMachine
.OpenSubKey("Software")
.OpenSubKey("Microsoft")
.OpenSubKey("Windows")
.OpenSubKey("CurrentVersion")
.OpenSubKey("App Paths")
.OpenSubKey("AcroRd32.exe")
.GetValue(String.Empty).ToString();
var fileInfo = new FileInfo(processFilename);
var workingDirectory = fileInfo.Directory.FullName;
Process process = new Process();
process.EnableRaisingEvents = true;
process.StartInfo = new ProcessStartInfo()
{
CreateNoWindow = true,
FileName = processFilename,
UseShellExecute = true,
WindowStyle = ProcessWindowStyle.Hidden,
ErrorDialog = false,
Arguments = $"/t {filename} \"{printer}\"",
WorkingDirectory = workingDirectory
};
try
{
var processStarted = process.Start();
if (processStarted)
{
LogHelper.WriteLog($"Print Process Started. Process: {process.ProcessName}");
}
else
{
process.Close();
LogHelper.WriteLog($"Print Process Not Started.");
throw new Exception("Error in PrintHelper.Print(): Print Process did not start.");
}
Console.WriteLine("Began Printing! (Test)");
}
catch (Exception e)
{
LogHelper.WriteLog($"Error in PrintHelper.Print(): {e.Message}");
throw e;
}
finally
{
process.Close();
Console.WriteLine("Finished Printing! (Test)");
}
LogHelper.WriteLog("Ending PrintHelper.Print().");
return true;
}
我们已经尝试过:
- 将文件名设置为要打印的 .PDF 并使用动词“Print”和“PrintTo”
- 将 UseShellExecute 设置为 True 和 False
- 将网络凭据和 LoadUserProfile 传递为 True
- 将运行我们应用程序的 ASP.NET AppPool 设置为 LocalSystem
- 运行 通过命令行(以不同用户身份登录时)执行相同的打印命令并打印文档。
显着发现:
- 利用 Adobe Acrobat Reader DC,我们看到它在服务器上启动时用户名为空,而不是 SYSTEM 或任何其他名称,尽管没有文档被发送到打印机。当 运行 本地代码时,Adobe Acrobat Reader DC 以用户登录时的用户名启动,文档打印成功。
- PDF 文档存在,并且已在本地和服务器上验证。
- 没有抛出异常,Adobe Acrobat Reader DC 成功打开,只是没有文档发送到服务器上的打印机。
作为我们意图的附加理由:我们希望将打印逻辑集中在多个单独的应用程序上,而不是为每个应用程序实现打印。打印还利用了一个映射,它允许我们为 SSRS 中的各种报告定义它们应该动态地转到哪台打印机;因此我们想走这条路。我觉得我们真的很亲密,我只是不确定这里出了什么问题。
请告诉我您的想法,我将不胜感激。
通过大量阅读和反复试验,我们找到了适合我们情况的解决方案:从利用 Adobe Acrobat Reader 转向 Foxit Reader。主要区别似乎是 Adobe Acrobat Reader 需要加载用户配置文件才能工作,而 Foxit 不需要。
我发布这个是为了万一有需要的人看到它,他们可以看到对我们有用的东西。代码确实有效,是我们利用的附加应用程序没有。
前言:
我们正在开发一套应用程序(移动和桌面),它利用由 ASP.NET 应用程序 运行 在 Windows Server 2008 R2 上维护的 restapi 服务器。我们在后端集成的功能之一是打印功能,它从我们的 SSRS 服务中提取 pdf,然后打印到网络打印机。
有很多关于静默打印和利用不同产品的线程,这些解决方案中的大多数都在我的本地机器上运行 (Windows 10);然而,当我们将代码移动到我们的服务器时,我们发现部分代码执行但文档从未到达打印机。
我们的代码:
private async Task<bool> Print(string filename, string printer)
{
var processFilename = Microsoft.Win32.Registry.LocalMachine
.OpenSubKey("Software")
.OpenSubKey("Microsoft")
.OpenSubKey("Windows")
.OpenSubKey("CurrentVersion")
.OpenSubKey("App Paths")
.OpenSubKey("AcroRd32.exe")
.GetValue(String.Empty).ToString();
var fileInfo = new FileInfo(processFilename);
var workingDirectory = fileInfo.Directory.FullName;
Process process = new Process();
process.EnableRaisingEvents = true;
process.StartInfo = new ProcessStartInfo()
{
CreateNoWindow = true,
FileName = processFilename,
UseShellExecute = true,
WindowStyle = ProcessWindowStyle.Hidden,
ErrorDialog = false,
Arguments = $"/t {filename} \"{printer}\"",
WorkingDirectory = workingDirectory
};
try
{
var processStarted = process.Start();
if (processStarted)
{
LogHelper.WriteLog($"Print Process Started. Process: {process.ProcessName}");
}
else
{
process.Close();
LogHelper.WriteLog($"Print Process Not Started.");
throw new Exception("Error in PrintHelper.Print(): Print Process did not start.");
}
Console.WriteLine("Began Printing! (Test)");
}
catch (Exception e)
{
LogHelper.WriteLog($"Error in PrintHelper.Print(): {e.Message}");
throw e;
}
finally
{
process.Close();
Console.WriteLine("Finished Printing! (Test)");
}
LogHelper.WriteLog("Ending PrintHelper.Print().");
return true;
}
我们已经尝试过:
- 将文件名设置为要打印的 .PDF 并使用动词“Print”和“PrintTo”
- 将 UseShellExecute 设置为 True 和 False
- 将网络凭据和 LoadUserProfile 传递为 True
- 将运行我们应用程序的 ASP.NET AppPool 设置为 LocalSystem
- 运行 通过命令行(以不同用户身份登录时)执行相同的打印命令并打印文档。
显着发现:
- 利用 Adobe Acrobat Reader DC,我们看到它在服务器上启动时用户名为空,而不是 SYSTEM 或任何其他名称,尽管没有文档被发送到打印机。当 运行 本地代码时,Adobe Acrobat Reader DC 以用户登录时的用户名启动,文档打印成功。
- PDF 文档存在,并且已在本地和服务器上验证。
- 没有抛出异常,Adobe Acrobat Reader DC 成功打开,只是没有文档发送到服务器上的打印机。
作为我们意图的附加理由:我们希望将打印逻辑集中在多个单独的应用程序上,而不是为每个应用程序实现打印。打印还利用了一个映射,它允许我们为 SSRS 中的各种报告定义它们应该动态地转到哪台打印机;因此我们想走这条路。我觉得我们真的很亲密,我只是不确定这里出了什么问题。
请告诉我您的想法,我将不胜感激。
通过大量阅读和反复试验,我们找到了适合我们情况的解决方案:从利用 Adobe Acrobat Reader 转向 Foxit Reader。主要区别似乎是 Adobe Acrobat Reader 需要加载用户配置文件才能工作,而 Foxit 不需要。
我发布这个是为了万一有需要的人看到它,他们可以看到对我们有用的东西。代码确实有效,是我们利用的附加应用程序没有。