- PR -

VB.NETでプロセスが終了するまで待機する

投稿者投稿内容
未記入
会議室デビュー日: 2006/03/14
投稿数: 6
投稿日時: 2006-03-14 12:24
下記のようにEXCELファイルを起動させて終了するまで待機するようにしたのですが
既にEXCELが起動されている場合にエラーとなります。
エラー内容は「オブジェクト参照がオブジェクト インスタンスに設定されていません。」です。

原因は「既存のプロセスを再利用した場合、戻り値がNothingとなる」ことで
p.EnableRaisingEvents = True
のところでエラーとなり、イベントハンドラを追加することができませんでした。

既にEXCELが起動されている場合、これから開くEXCELファイルが終了するときに
イベントを発生させることは可能なのでしょうか?
どなたかご存知の方がいらしたら教えてください。
わかりにくくてすみません。

[VB.NET]
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click

'プロセス終了フラグがOFFのとき処理を抜ける
If end_flg = False Then Exit Sub

'ファイルを開いて終了まで待機する
Dim p As System.Diagnostics.Process = _
System.Diagnostics.Process.Start("test.xls")
'プロセスが終了したときに Exited イベントを発生させる
p.EnableRaisingEvents = True     
'イベントハンドラの追加
AddHandler p.Exited, AddressOf p_Exited
'プロセス終了フラグをOFFにする
end_flg = False
End Sub

Private Sub p_Exited(ByVal sender As Object, ByVal e As EventArgs)
'プロセスが終了したときに実行される
MsgBox("終了しました。")
'プロセス終了フラグをONにする
end_flg = True
End Sub


[ メッセージ編集済み 編集者: 未記入 編集日時 2006-03-14 12:37 ]
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-03-14 12:48
引用:

未記入さんの書き込み (2006-03-14 12:24) より:

既にEXCELが起動されている場合にエラーとなります。


なので、回避策は新しいプロセスとして常に起動する。

引用:

Dim p As System.Diagnostics.Process = System.Diagnostics.Process.Start("test.xls")


System.Diagnostics.Process.Start("Excel.exe までのパス", "test.xls")

引用:

'ファイルを開いて終了まで待機する


これは、WaitForExit がないので不適切なコメントですよね。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
YAS
ベテラン
会議室デビュー日: 2006/02/15
投稿数: 59
投稿日時: 2006-03-14 13:42
pがNothingのときに起動済みのExcelを探してpに入れてやるというのはどうでしょう。

動くだけでいいならば,以下のようなコードでいけます。
(動くだけなので,このまま使ってはだめです。)

コード:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

'プロセス終了フラグがOFFのとき処理を抜ける
If end_flg = False Then Exit Sub

'ファイルを開いて終了まで待機する
Dim p As System.Diagnostics.Process = _
System.Diagnostics.Process.Start("test.xls")
If p Is Nothing Then
Dim Processes As Process() = Process.GetProcesses
For Each Process As Process In Processes
If Process.MainWindowTitle = "Microsoft Excel - test.xls" Then
p = Process
Exit For
End If
Next
End If
'プロセスが終了したときに Exited イベントを発生させる
p.EnableRaisingEvents = True
'イベントハンドラの追加
AddHandler p.Exited, AddressOf p_Exited
'プロセス終了フラグをOFFにする
end_flg = False
End Sub



(プロセスを探している最中にExcelを閉じたらどうするなど,いろいろな事態に
 備えなければならないことを考えれば,新しく開いた方が楽かもしれません。)


[ メッセージ編集済み 編集者: YAS 編集日時 2006-03-14 13:45 ]
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-03-14 14:24
引用:

YASさんの書き込み (2006-03-14 13:42) より:

pがNothingのときに起動済みのExcelを探してpに入れてやるというのはどうでしょう。


GetObject の代わりみたいなものですね。

引用:

(プロセスを探している最中にExcelを閉じたらどうするなど,いろいろな事態に
 備えなければならないことを考えれば,新しく開いた方が楽かもしれません。)


確かに「プロセスを回す」のは、この世界ではかなり時間のかかる処理なので、入り込む余地は高いですね。
イベント ハンドラに Add する前に、HasExited プロパティ で見るとまだ良さそうですね。
いずれにしても例外処理は必須で、例外時はおせっかいに新規起動するの... かな。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
未記入
会議室デビュー日: 2006/03/14
投稿数: 6
投稿日時: 2006-03-14 14:38
さまざまな方法を教えていただきありがとうございます。
大変助かりました。

System.Diagnostics.Process.Start("Excel.exe までのパス", "test.xls")
を使わせていただこうと思います。

そこでまたわからないことがでてきたのですが、Excel.exeのインストールフォルダが
固定であればできるのですが、Excel.exeのインストールフォルダを探すことはできるの
でしょうか?レジストリ検索(?)のようなことをしなければならないのでしょうか?
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-03-14 14:40
方法 (1) のサンプル。

メリット : 他の作業中の Excel と干渉しない。

コード:

    ' プライベート メンバ
    Private myProcess As System.Diagnostics.Process

    ' myProcess.Exited イベント
    Private Sub myProcess_Exited(ByVal sender As Object, ByVal e As System.EventArgs)
        MessageBox.Show("終了した")

        Try
            Me.myProcess.Close()
        Finally
            Me.myProcess.Dispose()
            Me.myProcess = Nothing
        End Try
    End Sub

    ' 指定した WorkBook を開いて Excel を実行する
    Private Sub ExecuteExcelApplication(ByVal workBookPath As String)
        If Not Me.myProcess Is Nothing Then
            Return
        End If

        Me.myProcess = System.Diagnostics.Process.Start("EXCEL", workBookPath)
        Me.myProcess.EnableRaisingEvents = True
        AddHandler Me.myProcess.Exited, AddressOf myProcess_Exited
    End Sub

    ' 使用例
    Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        Me.ExecuteExcelApplication("C:\Book1.xls")
    End Sub


_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-03-14 15:31
引用:

未記入さんの書き込み (2006-03-14 14:38) より:

そこでまたわからないことがでてきたのですが、Excel.exeのインストールフォルダが
固定であればできるのですが、Excel.exeのインストールフォルダを探すことはできるの
でしょうか?


入れ違いでしたね... 関連付け起動できるくらいであれば、「Excel」だけでも大丈夫です。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2006-03-14 17:01
引用:

関連付け起動できるくらいであれば、「Excel」だけでも大丈夫です。



大丈夫じゃないです。

拡張子関連付けかインストール系の情報から、フルパスを求めなければならないです。

_________________
// 渋木宏明 (Hiroaki SHIBUKI)
// http://hidori.jp/
// Microsoft MVP for Visual C#
//
// @IT会議室 RSS 配信中: http://hidori.jp/rss/atmarkIT/

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