I'm having 2 issues when trying to print a pdf silently in C# using adobe acrobat. I'm printing the pdfs using Process.Start().
我在尝试用adobeacrobat在c#中静默打印pdf时遇到了两个问题。我正在使用Process.Start()打印pdf。
The first issue is that I cannot launch Adobe Acrobat without specifying the full path to the executable. I assume it doesn't add it to your path when you install it. Is there an easy way to launch the newest version of acrobat on a machine without specifying full path names? I'm worried that the client is going to do an update and break my code that launches this. I'm also concerned with them installing this on machines with different versions of windows (install paths are different in 64 bit environment vs. 32 bit).
第一个问题是,我不能在不指定可执行文件的完整路径的情况下启动adobeacrobat。我假设它不会在安装时将它添加到您的路径中。是否有一种简单的方法可以在机器上启动最新版本的acrobat,而无需指定完整的路径名?我担心客户端会更新并破坏我的代码。我还关心他们在不同版本的windows上安装这个程序(在64位环境中安装路径不同于32位)。
My second problem is the fact that whenever I launch acrobat and print it still leaves the acrobat window open. I thought that the command line parameters I was using would suppress all of this but apparently not.
我的第二个问题是,每当我启动acrobat和print时,acrobat窗口仍会打开。我认为我使用的命令行参数会抑制所有这些,但显然不是。
I'm trying to launch adobe acrobat from the command line with the following syntax:
我尝试从命令行启动adobeacrobat,使用以下语法:
C:\Program Files (x86)\Adobe\Reader 10.0\Reader>AcroRd32.exe /t "Label.pdf" "HP4000" "HP LaserJet 4100 Series PCL6" "out.pdf"
> AcroRd32 C:\Program Files (x86)\Adobe\Reader 10.0 \读者。exe / t”的标签。pdf" "HP4000" "HP LaserJet 4100系列PCL6" "out.pdf"
It prints out fine but it still leaves the acrobat window up. Is there any other solution besides going out and killing the process programmatically?
它打印的很好,但它仍然让acrobat窗口向上。除了走出去和以编程方式杀死进程之外,还有其他的解决方案吗?
8 个解决方案
#1
24
I ended up bailing on Adobe Acrobat here and going with FoxIt Reader (Free pdf reader) to do my pdf printing. This is the code I'm using to print via FoxIt in C#:
我在这里结束了对adobeacrobat的求助,并与FoxIt Reader(免费pdf阅读器)进行了pdf打印。这是我在c#中使用FoxIt打印的代码:
Process pdfProcess = new Process();
pdfProcess.StartInfo.FileName = @"C:\Program Files (x86)\Foxit Software\Foxit Reader\Foxit Reader.exe";
pdfProcess.StartInfo.Arguments = string.Format(@"-p {0}", fileNameToSave);
pdfProcess.Start();
The above code prints to the default printer but there are command line parameters you can use to specify file and printer. You can use the following syntax:
上面的代码打印到默认打印机,但是您可以使用命令行参数来指定文件和打印机。您可以使用以下语法:
Foxit Reader.exe -t "pdf filename" "printer name"
福昕阅读器。exe -t "pdf档名" "打印机名称"
Update:
Apparently earlier versions of acrobat do not have the problem outlined above either. If you use a much older version (4.x or something similar) it does not exhibit this problem.
显然,早期版本的acrobat也没有上述问题。如果您使用的是更老的版本(4)。x或类似的东西)它不显示这个问题。
Some printers do support native pdf printing as well so it's possible to send the raw pdf data to the printer and it might print it. See https://support.microsoft.com/en-us/kb/322091 for sending raw data to the printer.
有些打印机也支持原生pdf打印,因此可以将原始pdf数据发送给打印机,并打印出来。请参阅https://support.microsoft.com/en-us/kb/322091向打印机发送原始数据。
Update 2
In later versions of our software we ended up using a paid product:
在后来的版本中,我们使用了付费产品:
http://www.pdfprinting.net/
#2
9
Nick's answer looked good to me, so I translated it to c#. It works!
尼克的回答对我来说很好,所以我把它翻译成c#。它的工作原理!
using System.Diagnostics;
namespace Whatever
{
static class pdfPrint
{
public static void pdfTest(string pdfFileName)
{
string processFilename = Microsoft.Win32.Registry.LocalMachine
.OpenSubKey("Software")
.OpenSubKey("Microsoft")
.OpenSubKey("Windows")
.OpenSubKey("CurrentVersion")
.OpenSubKey("App Paths")
.OpenSubKey("AcroRd32.exe")
.GetValue(String.Empty).ToString();
ProcessStartInfo info = new ProcessStartInfo();
info.Verb = "print";
info.FileName = processFilename;
info.Arguments = String.Format("/p /h {0}", pdfFileName);
info.CreateNoWindow = true;
info.WindowStyle = ProcessWindowStyle.Hidden;
//(It won't be hidden anyway... thanks Adobe!)
info.UseShellExecute = false;
Process p = Process.Start(info);
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
int counter = 0;
while (!p.HasExited)
{
System.Threading.Thread.Sleep(1000);
counter += 1;
if (counter == 5) break;
}
if (!p.HasExited)
{
p.CloseMainWindow();
p.Kill();
}
}
}
}
}
#3
8
The following is tested in both Acrobat Reader 8.1.3 and Acrobat Pro 11.0.06, and the following functionality is confirmed:
在acrobatreader8.1.3和Acrobat Pro 11.0.06中测试了以下功能,并确认以下功能:
- Locates the default Acrobat executable on the system
- 定位系统上的默认Acrobat可执行文件。
- Sends the file to the local printer
- 将文件发送到本地打印机。
- Closes Acrobat, regardless of version
- 关闭Acrobat,不管版本。
string applicationPath;
var printApplicationRegistryPaths = new[]
{
@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\Acrobat.exe",
@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\AcroRD32.exe"
};
foreach (var printApplicationRegistryPath in printApplicationRegistryPaths)
{
using (var regKeyAppRoot = Registry.LocalMachine.OpenSubKey(printApplicationRegistryPath))
{
if (regKeyAppRoot == null)
{
continue;
}
applicationPath = (string)regKeyAppRoot.GetValue(null);
if (!string.IsNullOrEmpty(applicationPath))
{
return applicationPath;
}
}
}
// Print to Acrobat
const string flagNoSplashScreen = "/s";
const string flagOpenMinimized = "/h";
var flagPrintFileToPrinter = string.Format("/t \"{0}\" \"{1}\"", printFileName, printerName);
var args = string.Format("{0} {1} {2}", flagNoSplashScreen, flagOpenMinimized, flagPrintFileToPrinter);
var startInfo = new ProcessStartInfo
{
FileName = printApplicationPath,
Arguments = args,
CreateNoWindow = true,
ErrorDialog = false,
UseShellExecute = false,
WindowStyle = ProcessWindowStyle.Hidden
};
var process = Process.Start(startInfo);
// Close Acrobat regardless of version
if (process != null)
{
process.WaitForInputIdle();
process.CloseMainWindow();
}
#4
4
got another solution .. its combination of other snippets from *. When I call CloseMainWindow, and then call Kill .. adobe closes down
有另一种解决方案。它的其他片段来自*。当我调用CloseMainWindow,然后调用Kill。adobe关闭
Dim info As New ProcessStartInfo()
info.Verb = "print"
info.FileName = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software").OpenSubKey("Microsoft").OpenSubKey("Windows").OpenSubKey("CurrentVersion").OpenSubKey("App Paths").OpenSubKey("AcroRd32.exe").GetValue(String.Empty).ToString()
info.Arguments = String.Format("/p /h {0}", "c:\log\test.pdf")
info.CreateNoWindow = True
info.WindowStyle = ProcessWindowStyle.Hidden
info.UseShellExecute = False
Dim p As Process = Process.Start(info)
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
Dim counter As Integer = 0
Do Until p.HasExited
System.Threading.Thread.Sleep(1000)
counter += 1
If counter = 5 Then
Exit Do
End If
Loop
If p.HasExited = False Then
p.CloseMainWindow()
p.Kill()
End If
#5
4
I've tried both Adobe Reader and Foxit without luck. The current versions of both are very fond of popping up windows and leaving processes running. Ended up using Sumatra PDF which is very unobtrusive. Here's the code I use. Not a trace of any windows and process exits nicely when it's done printing.
我已经试用了adobereader和Foxit,没有运气。目前的版本都非常喜欢弹出窗口并让进程运行。最后使用了苏门答腊的PDF,这是非常不引人注目的。这是我使用的代码。当它完成打印时,没有任何窗口和进程的踪迹。
public static void SumatraPrint(string pdfFile, string printer)
{
var exePath = Registry.LocalMachine.OpenSubKey(
@"SOFTWARE\Microsoft\Windows\CurrentVersion" +
@"\App Paths\SumatraPDF.exe").GetValue("").ToString();
var args = $"-print-to \"{printer}\" {pdfFile}";
var process = Process.Start(exePath, args);
process.WaitForExit();
}
#6
3
Problem 1
You may be able to work your way around the registry. In HKEY_CLASSES_ROOT\.pdf\PersistentHandler\(Default)
you should find a CLSID that points to a value found in one of two places. Either the CLSID folder of the same key, or (for 64 bit systems) one step down in Wow6432Node\CLSID
then in that CLSID's key.
你可以在注册中心工作。在HKEY_CLASSES_ROOT\.pdf\PersistentHandler\(默认)中,您应该找到一个CLSID,它指向两个位置中的一个值。同样键的CLSID文件夹,或者(对于64位系统),在Wow6432Node . CLSID中一个步骤,然后在CLSID的密钥中。
Within that key you can look for LocalServer32
and find the default string value pointing to the current exe path.
在该键中,您可以查找LocalServer32并找到指向当前exe路径的默认字符串值。
I'm not 100% on any of this, but seems plausible (though you're going to have to verify on multiple environments to confirm that in-fact locates the process you're looking for).
我并不是100%支持这一点,但似乎是合理的(尽管您需要在多个环境中进行验证,以确认实际上找到了您正在寻找的过程)。
(Here are the docs on registry keys involved regarding PersistentHandlers)
(以下是有关“PersistentHandlers”的注册表密钥的文档)
Problem 2
Probably using the CreateNoWindow of the Process StartInfo.
可能使用的是Process StartInfo的CreateNoWindow。
Process p = new Process();
p.StartInfo.FileName = @"C:\Program Files (x86)\Adobe\Reader 10.0\Reader\AcroRd32.exe";
p.StartInfo.Arguments = "/t \"Label.pdf\" \"HP4000\" \"HP LaserJet 4100 Series PCL6\" \"out.pdf\"";
p.CreateNoWindow = true;
p.Start();
p.WaitForExit();
(only a guess however, but I'm sure a little testing will prove it to work/not work)
(只是猜测,但我确信有一点测试会证明它是有效的/无效的)
#7
3
If you use Acrobat reader 4.0 you can do things like this: "C:\Program Files\Adobe\Acrobat 4.0\Reader\Acrord32.exe" /t /s "U:\PDF_MS\SM003067K08.pdf" Planning_H2 BUT if the PDF file has been created in a newer version of Acrobat an invisible window opens
如果您使用acrobatreader4.0,您可以这样做:“C:\程序文件\ adobeacrobat 4.0\ reader \Acrord32”。exe”/ t / s“U:\ PDF_MS \ SM003067K08。pdf“Planning_H2但是如果pdf文件已经被创建在一个新的版本的Acrobat,一个看不见的窗口打开。
#8
0
You have already tried something different than Acrobat Reader, so my advice is forget about GUI apps and use 3rd party command line tool like RawFilePrinter.exe
您已经尝试了一些与Acrobat阅读器不同的东西,因此我的建议是忘记GUI应用程序,并使用像RawFilePrinter.exe这样的第三方命令行工具。
private static void ExecuteRawFilePrinter() {
Process process = new Process();
process.StartInfo.FileName = "c:\\Program Files (x86)\\RawFilePrinter\\RawFilePrinter.exe";
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.Arguments = string.Format("-p \"c:\\Users\\Me\\Desktop\\mypdffile.pdf\" \"Canon Printer\"");
process.Start();
process.WaitForExit();
if (process.ExitCode == 0) {
//ok
} else {
//error
}
}
Latest version to download: http://effisoft.pl/rawfileprinter
下载的最新版本:http://effisoft.pl/rawfileprinter。
#1
24
I ended up bailing on Adobe Acrobat here and going with FoxIt Reader (Free pdf reader) to do my pdf printing. This is the code I'm using to print via FoxIt in C#:
我在这里结束了对adobeacrobat的求助,并与FoxIt Reader(免费pdf阅读器)进行了pdf打印。这是我在c#中使用FoxIt打印的代码:
Process pdfProcess = new Process();
pdfProcess.StartInfo.FileName = @"C:\Program Files (x86)\Foxit Software\Foxit Reader\Foxit Reader.exe";
pdfProcess.StartInfo.Arguments = string.Format(@"-p {0}", fileNameToSave);
pdfProcess.Start();
The above code prints to the default printer but there are command line parameters you can use to specify file and printer. You can use the following syntax:
上面的代码打印到默认打印机,但是您可以使用命令行参数来指定文件和打印机。您可以使用以下语法:
Foxit Reader.exe -t "pdf filename" "printer name"
福昕阅读器。exe -t "pdf档名" "打印机名称"
Update:
Apparently earlier versions of acrobat do not have the problem outlined above either. If you use a much older version (4.x or something similar) it does not exhibit this problem.
显然,早期版本的acrobat也没有上述问题。如果您使用的是更老的版本(4)。x或类似的东西)它不显示这个问题。
Some printers do support native pdf printing as well so it's possible to send the raw pdf data to the printer and it might print it. See https://support.microsoft.com/en-us/kb/322091 for sending raw data to the printer.
有些打印机也支持原生pdf打印,因此可以将原始pdf数据发送给打印机,并打印出来。请参阅https://support.microsoft.com/en-us/kb/322091向打印机发送原始数据。
Update 2
In later versions of our software we ended up using a paid product:
在后来的版本中,我们使用了付费产品:
http://www.pdfprinting.net/
#2
9
Nick's answer looked good to me, so I translated it to c#. It works!
尼克的回答对我来说很好,所以我把它翻译成c#。它的工作原理!
using System.Diagnostics;
namespace Whatever
{
static class pdfPrint
{
public static void pdfTest(string pdfFileName)
{
string processFilename = Microsoft.Win32.Registry.LocalMachine
.OpenSubKey("Software")
.OpenSubKey("Microsoft")
.OpenSubKey("Windows")
.OpenSubKey("CurrentVersion")
.OpenSubKey("App Paths")
.OpenSubKey("AcroRd32.exe")
.GetValue(String.Empty).ToString();
ProcessStartInfo info = new ProcessStartInfo();
info.Verb = "print";
info.FileName = processFilename;
info.Arguments = String.Format("/p /h {0}", pdfFileName);
info.CreateNoWindow = true;
info.WindowStyle = ProcessWindowStyle.Hidden;
//(It won't be hidden anyway... thanks Adobe!)
info.UseShellExecute = false;
Process p = Process.Start(info);
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
int counter = 0;
while (!p.HasExited)
{
System.Threading.Thread.Sleep(1000);
counter += 1;
if (counter == 5) break;
}
if (!p.HasExited)
{
p.CloseMainWindow();
p.Kill();
}
}
}
}
}
#3
8
The following is tested in both Acrobat Reader 8.1.3 and Acrobat Pro 11.0.06, and the following functionality is confirmed:
在acrobatreader8.1.3和Acrobat Pro 11.0.06中测试了以下功能,并确认以下功能:
- Locates the default Acrobat executable on the system
- 定位系统上的默认Acrobat可执行文件。
- Sends the file to the local printer
- 将文件发送到本地打印机。
- Closes Acrobat, regardless of version
- 关闭Acrobat,不管版本。
string applicationPath;
var printApplicationRegistryPaths = new[]
{
@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\Acrobat.exe",
@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\AcroRD32.exe"
};
foreach (var printApplicationRegistryPath in printApplicationRegistryPaths)
{
using (var regKeyAppRoot = Registry.LocalMachine.OpenSubKey(printApplicationRegistryPath))
{
if (regKeyAppRoot == null)
{
continue;
}
applicationPath = (string)regKeyAppRoot.GetValue(null);
if (!string.IsNullOrEmpty(applicationPath))
{
return applicationPath;
}
}
}
// Print to Acrobat
const string flagNoSplashScreen = "/s";
const string flagOpenMinimized = "/h";
var flagPrintFileToPrinter = string.Format("/t \"{0}\" \"{1}\"", printFileName, printerName);
var args = string.Format("{0} {1} {2}", flagNoSplashScreen, flagOpenMinimized, flagPrintFileToPrinter);
var startInfo = new ProcessStartInfo
{
FileName = printApplicationPath,
Arguments = args,
CreateNoWindow = true,
ErrorDialog = false,
UseShellExecute = false,
WindowStyle = ProcessWindowStyle.Hidden
};
var process = Process.Start(startInfo);
// Close Acrobat regardless of version
if (process != null)
{
process.WaitForInputIdle();
process.CloseMainWindow();
}
#4
4
got another solution .. its combination of other snippets from *. When I call CloseMainWindow, and then call Kill .. adobe closes down
有另一种解决方案。它的其他片段来自*。当我调用CloseMainWindow,然后调用Kill。adobe关闭
Dim info As New ProcessStartInfo()
info.Verb = "print"
info.FileName = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software").OpenSubKey("Microsoft").OpenSubKey("Windows").OpenSubKey("CurrentVersion").OpenSubKey("App Paths").OpenSubKey("AcroRd32.exe").GetValue(String.Empty).ToString()
info.Arguments = String.Format("/p /h {0}", "c:\log\test.pdf")
info.CreateNoWindow = True
info.WindowStyle = ProcessWindowStyle.Hidden
info.UseShellExecute = False
Dim p As Process = Process.Start(info)
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
Dim counter As Integer = 0
Do Until p.HasExited
System.Threading.Thread.Sleep(1000)
counter += 1
If counter = 5 Then
Exit Do
End If
Loop
If p.HasExited = False Then
p.CloseMainWindow()
p.Kill()
End If
#5
4
I've tried both Adobe Reader and Foxit without luck. The current versions of both are very fond of popping up windows and leaving processes running. Ended up using Sumatra PDF which is very unobtrusive. Here's the code I use. Not a trace of any windows and process exits nicely when it's done printing.
我已经试用了adobereader和Foxit,没有运气。目前的版本都非常喜欢弹出窗口并让进程运行。最后使用了苏门答腊的PDF,这是非常不引人注目的。这是我使用的代码。当它完成打印时,没有任何窗口和进程的踪迹。
public static void SumatraPrint(string pdfFile, string printer)
{
var exePath = Registry.LocalMachine.OpenSubKey(
@"SOFTWARE\Microsoft\Windows\CurrentVersion" +
@"\App Paths\SumatraPDF.exe").GetValue("").ToString();
var args = $"-print-to \"{printer}\" {pdfFile}";
var process = Process.Start(exePath, args);
process.WaitForExit();
}
#6
3
Problem 1
You may be able to work your way around the registry. In HKEY_CLASSES_ROOT\.pdf\PersistentHandler\(Default)
you should find a CLSID that points to a value found in one of two places. Either the CLSID folder of the same key, or (for 64 bit systems) one step down in Wow6432Node\CLSID
then in that CLSID's key.
你可以在注册中心工作。在HKEY_CLASSES_ROOT\.pdf\PersistentHandler\(默认)中,您应该找到一个CLSID,它指向两个位置中的一个值。同样键的CLSID文件夹,或者(对于64位系统),在Wow6432Node . CLSID中一个步骤,然后在CLSID的密钥中。
Within that key you can look for LocalServer32
and find the default string value pointing to the current exe path.
在该键中,您可以查找LocalServer32并找到指向当前exe路径的默认字符串值。
I'm not 100% on any of this, but seems plausible (though you're going to have to verify on multiple environments to confirm that in-fact locates the process you're looking for).
我并不是100%支持这一点,但似乎是合理的(尽管您需要在多个环境中进行验证,以确认实际上找到了您正在寻找的过程)。
(Here are the docs on registry keys involved regarding PersistentHandlers)
(以下是有关“PersistentHandlers”的注册表密钥的文档)
Problem 2
Probably using the CreateNoWindow of the Process StartInfo.
可能使用的是Process StartInfo的CreateNoWindow。
Process p = new Process();
p.StartInfo.FileName = @"C:\Program Files (x86)\Adobe\Reader 10.0\Reader\AcroRd32.exe";
p.StartInfo.Arguments = "/t \"Label.pdf\" \"HP4000\" \"HP LaserJet 4100 Series PCL6\" \"out.pdf\"";
p.CreateNoWindow = true;
p.Start();
p.WaitForExit();
(only a guess however, but I'm sure a little testing will prove it to work/not work)
(只是猜测,但我确信有一点测试会证明它是有效的/无效的)
#7
3
If you use Acrobat reader 4.0 you can do things like this: "C:\Program Files\Adobe\Acrobat 4.0\Reader\Acrord32.exe" /t /s "U:\PDF_MS\SM003067K08.pdf" Planning_H2 BUT if the PDF file has been created in a newer version of Acrobat an invisible window opens
如果您使用acrobatreader4.0,您可以这样做:“C:\程序文件\ adobeacrobat 4.0\ reader \Acrord32”。exe”/ t / s“U:\ PDF_MS \ SM003067K08。pdf“Planning_H2但是如果pdf文件已经被创建在一个新的版本的Acrobat,一个看不见的窗口打开。
#8
0
You have already tried something different than Acrobat Reader, so my advice is forget about GUI apps and use 3rd party command line tool like RawFilePrinter.exe
您已经尝试了一些与Acrobat阅读器不同的东西,因此我的建议是忘记GUI应用程序,并使用像RawFilePrinter.exe这样的第三方命令行工具。
private static void ExecuteRawFilePrinter() {
Process process = new Process();
process.StartInfo.FileName = "c:\\Program Files (x86)\\RawFilePrinter\\RawFilePrinter.exe";
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.Arguments = string.Format("-p \"c:\\Users\\Me\\Desktop\\mypdffile.pdf\" \"Canon Printer\"");
process.Start();
process.WaitForExit();
if (process.ExitCode == 0) {
//ok
} else {
//error
}
}
Latest version to download: http://effisoft.pl/rawfileprinter
下载的最新版本:http://effisoft.pl/rawfileprinter。