- PR -

VB.NETでShellExecuteExを使用する

投稿者投稿内容
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2003-11-08 11:36
こんにちわ。諸農です。

引用:

PDF出力時AcrobatReaderが終了せず最小化され残ってしまいます。
AcrobatReaderを終了する方法をお教え下さい。



確認です。
Delphiでの実現コードではAcrobatReaderは印刷後に終了して
いたんでしょうか。

つまり、別の開発ツール・言語でShellExecute/ShellExecuteExを
呼び出せば何の考慮もしなくても、AcrobatReaderが印刷終了後に
AcrobatReader自身も終了するのに、.NETプログラミングでProcess
クラスを使うと印刷終了後に起動アプリケーションが終了まで進ま
ないのはなぜか、また対応方法に何かないのか、ということなのか、

別の開発ツール・言語では、終了処理までを考慮してコーディングし
ていたが、同様の方法を.NETプログラミングで実現するにはどうすれば
良いのか、ということでしょうか。


ところで、試していないので結果がどうなるかわかりませんが、
プロセスを終了させるにはKillメソッドが使えそうです。
また、WaitForInputIdleメソッドでアイドル状態かどうかの判定が出来
るようです。

アンマネージドな考え方でしたら、AcrobatReaderにWM_CLOSEを送るなど
で対応も出来そうです。



_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
KeroKero
常連さん
会議室デビュー日: 2003/11/06
投稿数: 26
投稿日時: 2003-11-08 15:17
AcrobatReaderが終了せず最小化されるのは,
"C:\Program Files\Adobe\Acrobat 6.0\Reader\AcroRd32.exe" /p /h "%1"
のようなオプションで起動されるせいだと思います。(/pは印刷はするが,終了まではしない。)

http://partners.adobe.com/asn/japan/developer/DOCS/DeveloperFAQ-J.pdf
の中の,VBのソースおよびコマンドラインの使用方法(/tオプション)を参考にしてみてください。
空条Q太郎
会議室デビュー日: 2003/11/06
投稿数: 19
投稿日時: 2003-11-08 20:28
Jubeiさん、KeroKeroさん、ありがとうございます。

>Delphiでの実現コードではAcrobatReaderは印刷後に終了して
>いたんでしょうか。

はい。
finally句にて
プロセスの終了にTerminateProcess
プロセスハンドルのクローズにCloseHandle
で終了しました。

>同様の方法を.NETプログラミングで実現するにはどうすれば
>良いのか、ということでしょうか。

はい。
ProcessクラスのStartメソッド後にKillメソッド等試していましたが
Killメソッド実行時に
"このオブジェクトに関連付けられているプロセスはありません。"
とエラーになるんです。
Startメソッドは『プロセス リソースを起動し、 Process コンポーネントに関連付けます。』
とういことですよね。なぜ関連付けられていないのか分からないのです。

>また、WaitForInputIdleメソッドでアイドル状態かどうかの判定が出来
>るようです。
>アンマネージドな考え方でしたら、AcrobatReaderにWM_CLOSEを送るなど
>で対応も出来そうです。
>http://partners.adobe.com/asn/japan/developer/DOCS/DeveloperFAQ-J.pdf
>の中の,VBのソースおよびコマンドラインの使用方法(/tオプション)を参考にしてみてください。

試してみることにします。
いつも本当にありがとうございます。
空条Q太郎
会議室デビュー日: 2003/11/06
投稿数: 19
投稿日時: 2003-11-08 22:32
何度もすみません。

----------source----------
Dim path as String = "ファイルパス(.pdf)"
Dim startInfo As New ProcessStartInfo("AcroRd32.exe", "/t " + path)
Process.Start(startInfo)
--------------------------
でうまくいきません。(最小化でファイルが開かれるのみ)
その他のオプションは成功します。

AcrobatReaderのコマンドラインのオプション"/t"は
パラメータにpath,printername,drivername,portnameがありますが
printername,drivername,portnameは必須でしょうか。

私の使用可能なプリンタはプリンタ名にスペースがありエラーが出ます。
またその場合使用するプリンタが変わった場合に困ります。

どうか宜しくお願い致します。
KeroKero
常連さん
会議室デビュー日: 2003/11/06
投稿数: 26
投稿日時: 2003-11-08 23:32
>printername,drivername,portnameは必須でしょうか。

必須です。

>私の使用可能なプリンタはプリンタ名にスペースがありエラーが出ます。

これは"でくくることで解消されます。またpathもスペースが入ることを考えて同じようにした方がいいでしょう(多分)。
テストしていないのでなんですが,オプション部分はこのような感じになると思います。
"/t """ + path + """ """ + printername + """ """ + drivername + """ /"

>またその場合使用するプリンタが変わった場合に困ります。

PrinterSettings.InstalledPrintersとPrinterSettings.IsDefaultPrinterを使えば何とかなると思いますが,drivernameの取得も考えるとWindows APIを使わないといけないかもしれません。
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2003-11-08 23:59
こんにちわ。諸農です。
引用:

----------source----------
Dim path as String = "ファイルパス(.pdf)"
Dim startInfo As New ProcessStartInfo("AcroRd32.exe", "/t " + path)
Process.Start(startInfo)
--------------------------
でうまくいきません。(最小化でファイルが開かれるのみ)
その他のオプションは成功します。



SDKの例を参考に以下のコードを書いてみました。うまく印刷されますが。。。
(C#ですので、VB.NETの場合は読み替えてください)

コード:
private void PrintDoc(string APrintDocName)
{
    Process myProcess = new Process();
    try
    {
        myProcess.StartInfo.FileName = APrintDocName; 
        myProcess.StartInfo.Verb = "Print";
        myProcess.StartInfo.CreateNoWindow = true;
        myProcess.Start();
        myProcess.WaitForExit(5000);
    }
    catch (Win32Exception e)
    {
        MessageBox.Show(e.Message);
    }
    finally
    {
        myProcess.Kill();
    }
}

private void button1_Click(object sender, System.EventArgs e)
{
    openFileDialog1.Filter = "PDF|*.pdf";
    if (openFileDialog1.ShowDialog() == DialogResult.OK)
    {
        PrintDoc(openFileDialog1.FileName);
    }
}



環境は、Win2000PRO SP4、Canon PIXUSシリーズインクジェットプリンタ、
Acrobat Reader6.0、印刷対象のドキュメントは
http://www.borland.co.jp/csharpbuilder/csharp10/techoverview.pdf
で入手できるものです。

ではでは(^^)/

_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2003-11-09 01:12
こんにちわ。諸農です。
引用:

ProcessクラスのStartメソッド後にKillメソッド等試していましたが
Killメソッド実行時に
"このオブジェクトに関連付けられているプロセスはありません。"
とエラーになるんです。
Startメソッドは『プロセス リソースを起動し、 Process コンポーネントに関連付けます。』
とういことですよね。なぜ関連付けられていないのか分からないのです。



さっき読み返してみて、わかりました。
引数有りのStartメソッドはstaticなんですね。
Killが使えないのも納得です(-_-


_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
空条Q太郎
会議室デビュー日: 2003/11/06
投稿数: 19
投稿日時: 2003-11-09 01:48
Jubeiさん、ご回答ありがとうございます。

Jubeiさんに頂いたコードで正常に動作しました。バンザーイ。

----------source----------
Private Sub PrintDoc(ByVal APrintDocName As String)
  Dim myProcess As New Process()
  Try
    '''成功
    myProcess.StartInfo.FileName = APrintDocName
    myProcess.StartInfo.Verb = "Print"
    myProcess.StartInfo.CreateNoWindow = True
    myProcess.Start()
    myProcess.WaitForExit(5000)

    '''失敗(関連付けられているプロセスはありません)
    'Dim startInfo As New ProcessStartInfo("AcroRd32.exe")
    'With startInfo
    '  .FileName = APrintDocName
    '  .Verb = "print"
    '  .CreateNoWindow = True
    'End With
    'myProcess.Start(startInfo)
    'myProcess.WaitForExit(5000)
  Catch e As Exception
    MsgBox(e.Message)
  Finally
    myProcess.Kill()
  End Try
End Sub
-------------------------

KeroKeroさん、ご回答ありがとうございます。

>これは"でくくることで解消されます。
>またpathもスペースが入ることを考えて同じよう>にした方がいいでしょう(多分)。

エラーはでなくなりましたが、印刷ができないです。
あと一歩(?)なのに…

>>またその場合使用するプリンタが変わった場合に困ります。

>PrinterSettings.InstalledPrintersとPrinterSettings.IsDefaultPrinterを使えば何と>かなると思いますが,
>drivernameの取得も考えるとWindows APIを使わないといけないか>もしれません。

やはり、印刷後にプロセスを終了させるようにしたほうが良いのでしょうか。

スキルアップ/キャリアアップ(JOB@IT)