PHPを介したサーバーサイド印刷ジョブの開始
質問
これはたぶん簡単なものではありませんが、状況は次のとおりです。
次のようなC#コマンドラインアプリケーションを作成しました。
- ITextSharpを使用してPDFを作成
- ディスクに書き込みます
- 生成されたPDFを静かに印刷するために、
System.Diagnostics.Process
を介してAcrord32.exe
(これはAcrobat Reader)を使用します
ソリューションをビルドし、 pdfGen.exe
をダブルクリックすると、期待どおりに動作します。 PDFが作成および印刷されます。
今、私のアプリは、IIS 7を実行しているWindows Vistaを備えた内部サーバーに展開する必要があります。このサーバーには、いくつかのPHP webappが実行されています。そして、 shell_exec()
を使用してPHP経由で呼び出され、結果のPDFがサーバーに接続されたプリンターで印刷されます。
したがって、私のPHPページは基本的に次のようになります。
shell_exec('/path/to/pdfGen.exe');
しかし、ここで問題が発生します。何が起こるかはタスクマネージャーなどによる:
-
pdfGen.exe
が開始 - PDFが作成されました
-
Acrord32.exe
が開始 -
pdfGen.exe
は永久にハングし(PHPスクリプトも同様)、何も出力されません
それは許可関連の問題であると確信しています。既に IIS_IUSRS
にデフォルトのプリンターと、 Acrord32.exe
があるディレクトリへのアクセスを許可しました。それでも、印刷はできません。ただし、pdfGen.exeを手動で起動すると機能します。
私が見逃しているものは何ですか?
編集:
PDFを印刷するためにAcrobat Readerを使用する必要はありません。作成したPDFサーバーサイドを静かに印刷する別の方法があれば、私はまったく気にしません。
解決 5
コメントありがとうございます。残念ながら、この「php start printjob」はそれは、よくわからない...政治的理由のために、今日キャンセルされたより大きなプロジェクトの一部でした。プロジェクトはほとんど死んでいると思います。
とにかく、私は最後の数日間に何度か試してみましたが、IISで動作させることができませんでした。私が既に実装およびテストしたソリューション:IISを削除し、ローカルのApacheと adminアクセス権で実行されるPHPを使用してXAMPPまたはWAMPPパッケージをインストールします。
これでうまくいきました。 .exe
を開始するためにPHPで pclose(popen( '... command ...'、 'r'));
を使用したため、 PDFが完成するまで待たないでください。すべてうまくいきました。
Acrobat Readerを使用して印刷ジョブを開始するC#コードを次に示します
public void Print(string pathname, string acrobatDirectory)
{
var proc = new Process
{
StartInfo =
{
Arguments = String.Format("/t \"{0}\"", pathname),
FileName = acrobatDirectory,
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = false,
RedirectStandardError = false,
}
};
proc.Start();
}
最初の引数は印刷するPDFへのパスで、2番目のパラメーターは AcroRd32.exe
への絶対パスです。
残された唯一の問題は、 AcroRd32.exe
が起動、印刷され、再び閉じられないことでした。そのため、すべてのprintjobは AcroRd32.exe
の新しいインスタンスを開始しました(Acrobat Reader 9.0を使用しています)。したがって、10回印刷すると、10個のacrobat Readerインスタンスが作成されました。
私がしたことは、印刷ジョブを開始し、X秒待って、プリンターが終了することを期待して、すべての AcroRd32.exe
インスタンスを強制終了することでした:
public void Print(string pathname, string acrobatDirectory)
{
Debug.WriteLine("Printing...");
Printer.Print(pathname, acrobatDirectory);
Thread.Sleep(30000);
try
{
Debug.WriteLine("Trying to kill runnung AcroRd32.exe's ");
FindAndKillProcess("AcroRd32");
}
catch (Exception)
{
Debug.WriteLine("AcroRd32.exe could not be killed...");
}
}
private bool FindAndKillProcess(string name)
{
foreach (Process clsProcess in Process.GetProcesses())
{
if (clsProcess.ProcessName.StartsWith(name))
{
clsProcess.Kill();
return true;
}
}
return false;
}
これは非常にうまくいきました。
上記(すべての AcroRd32.exe
を強制終了し、管理者権限でPHPを実行)が実行可能であったことに注意してください。非常に限られた使用領域。
クライアントPOSにデプロイされたタッチスクリーンアプリケーションで使用する必要があります。セールスマンは製品を設定するためにPHPアプリを使用し、PHPはバックグラウンドでPDFを作成および印刷する私の.exeを呼び出します。印刷されたドキュメントは、クライアントに渡されます。 したがって、この場合、セキュリティなどは実際には懸念事項ではありませんでした。
IISで使用するためのソリューションがあれば、それを回答として受け入れます。
他のヒント
何が起こっているかを確認するには、実行してみてください Sysinternalsのプロセスモニターを使用して、イベントをadobe acrobatプロセスにフィルターします。 。 acrobatのシステムコールが表示され、何が間違っているかを多かれ少なかれ知ることができます。
あなたのソリューションの小さな改善を知っています:SumatraPDFには、印刷後にSumatraを自動的に閉じるために使用できる素晴らしいコマンドラインインターフェイスがあります。
PHP" system"を使用しましたまたは" exec"バッチファイルを実行してSumatraPDFを開く関数:
sumatrapdf.exe -print-to-default -exit-on-print <path_to_PDF_file>
(印刷するプリンター名を指定することもできます)
これは興味深いプログラムです。
IIS_IUSRS
印刷する権限がないようです。 IIS_IUSRS
をPrint Operators Groupに追加するか、ユーザーに印刷権限を付与してください。
Shell_exec()はほとんどシェルコマンド(ls / dir、cpなど)を対象としています。 shell_exec()の代わりにexec()を使用しようとしましたか?