Печать PDF без проблем с помощью Adobe Acrobat
У меня возникают две проблемы при попытке распечатать pdf файл в С# с использованием adobe acrobat. Я печатаю pdf файлы с помощью Process.Start().
Первая проблема заключается в том, что я не могу запустить Adobe Acrobat без указания полного пути к исполняемому файлу. Я предполагаю, что он не добавляет его на ваш путь при его установке. Есть ли простой способ запустить новейшую версию acrobat на машине без указания полных имен путей? Я беспокоюсь, что клиент собирается сделать обновление и сломать мой код, который запускает это. Я также обеспокоен тем, что они устанавливают это на машинах с разными версиями окон (пути установки различаются в 64-битной среде против 32 бит).
Моя вторая проблема заключается в том, что всякий раз, когда я запускаю acrobat и печатаю, все равно остается открытым окно acrobat. Я думал, что параметры командной строки, которые я использовал, будут подавлять все это, но, по-видимому, нет.
Я пытаюсь запустить adobe acrobat из командной строки с помощью следующего синтаксиса:
C:\Program Files (x86)\Adobe\Reader 10.0\Reader > AcroRd32.exe/t "Label.pdf" "HP4000" "HP LaserJet 4100 Series PCL6" "out.pdf"
Он печатает отлично, но он все равно выходит из окна acrobat. Есть ли какое-либо другое решение, помимо выхода и программного уничтожения процесса?
Ответы
Ответ 1
Я закончил работу с Adobe Acrobat здесь и перешел к FoxIt Reader (бесплатный PDF-ридер), чтобы выполнить мою печать в формате PDF. Это код, который я использую для печати через 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();
Вышеприведенный код печатает на принтере по умолчанию, но есть параметры командной строки, которые вы можете использовать для указания файла и принтера. Вы можете использовать следующий синтаксис:
Foxit Reader.exe -t "pdf имя файла" "имя принтера"
Обновление:
По-видимому, более ранние версии acrobat также не имеют проблемы, описанной выше. Если вы используете гораздо более старую версию (4.x или что-то подобное), она не обнаруживает эту проблему.
Некоторые принтеры также поддерживают собственную печать в формате pdf, поэтому можно отправить необработанные pdf-данные на принтер и распечатать их. См. https://support.microsoft.com/en-us/kb/322091 для отправки необработанных данных на принтер.
Обновление 2
В более поздних версиях нашего программного обеспечения мы закончили использование платного продукта:
http://www.pdfprinting.net/
Ответ 2
В Acrobat Reader 8.1.3 и Acrobat Pro 11.0.06 проверяется следующее:
- Определяет исполняемый файл Acrobat по умолчанию в системе
- Отправляет файл на локальный принтер
- Закрывает 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();
}
Ответ 3
Ник ответ мне понравился, поэтому я перевел его на С#. Он работает!
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();
}
}
}
}
Ответ 4
получил другое решение.. его комбинация других фрагментов из stackOverflow. Когда я вызываю 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
Проблема 1
Возможно, вы сможете работать с реестром. В HKEY_CLASSES_ROOT\.pdf\PersistentHandler\(Default)
вы должны найти CLSID, который указывает на значение, найденное в одном из двух мест. Либо в папке CLSID того же ключа, либо (для 64-битных систем) один шаг вниз в Wow6432Node\CLSID
, затем в этом CLSID-ключ.
Внутри этого ключа вы можете искать LocalServer32
и найти строковое значение по умолчанию, указывающее на текущий путь EXE.
Я не на 100% на все это, но кажется правдоподобным (хотя вам придется проверять в нескольких средах, чтобы подтвердить, что на самом деле находит процесс, который вы ищете).
(Ниже приведены документы разделы реестра относительно PersistentHandlers)
Проблема 2
Возможно, используя CreateNoWindow процесса StartInfo.
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();
(только предположение, но я уверен, что небольшое тестирование докажет, что оно работает/не работает)
Ответ 6
Если вы используете Acrobat reader 4.0, вы можете делать такие вещи:
"C:\Program Files\Adobe\Acrobat 4.0\Reader\Acrord32.exe" /t/s "U:\PDF_MS\SM003067K08.pdf" Planning_H2
НО, если файл PDF был создан в более новой версии Acrobat, откроется невидимое окно
Ответ 7
Я пробовал как Adobe Reader, так и Foxit без везения. Текущие версии обоих очень любят выскакивать окна и оставлять процессы запущенными. Закончился с помощью Sumatra 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();
}
Ответ 8
Вы уже пробовали что-то другое, чем Acrobat Reader, поэтому мои советы забывают о приложениях с графическим интерфейсом и используют сторонний инструмент командной строки, такой как 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
}
}
Последняя версия для загрузки: http://effisoft.pl/rawfileprinter