- ダッチ
- 大ベテラン
- 会議室デビュー日: 2005/10/31
- 投稿数: 113
|
投稿日時: 2005-12-04 14:15
ダッチです。
ウィンドウを複数表示する常駐型アプリケーションを作成しようと思考中です。
タスクアイコンの「コンテキストメニュー」-「新規作成」から
ウィンドウを新規作成します。
常駐型アプリケーションなので多重起動される場合が考えられます。
その時に新たなウィンドウを新規作成したいのです。
しかし、どのようにすれば既に起動されているアプリケーションに対して
新規作成処理をしてくださいと教えることが出来るのかが不明です。
ご教示お願いいたします。
下記に多重起動部分のコードを記載いたします。
コード: |
|
<STAThread()> _
Public Shared Sub Main()
' Mutex の新しいインスタンスを生成
Dim userMutex As System.Threading.Mutex = New System.Threading.Mutex(False, Application.ProductName)
' Mutex のシグナルを受信できるかどうか判断
If userMutex.WaitOne(0, False) = True Then
' アプリケーション実行
Application.Run(New MainWindow)
' 解放
userMutex.ReleaseMutex()
Else
' 既にアプリケーションが起動中
' ここに新規作成処理を教える処理を記載したい
End If
' 破棄
userMutex.Close()
End Sub
|
|
- じゃんぬねっと
- ぬし
- 会議室デビュー日: 2004/12/22
- 投稿数: 7811
- お住まい・勤務地: 愛知県名古屋市
|
投稿日時: 2005-12-04 14:27
引用: |
|
ダッチさんの書き込み (2005-12-04 14:15) より:
しかし、どのようにすれば既に起動されているアプリケーションに対して
新規作成処理をしてくださいと教えることが出来るのかが不明です。
|
「新規作成処理」を実装しているであろう、
引用: |
|
ウィンドウを複数表示する常駐型アプリケーションを作成しようと思考中です。
タスクアイコンの「コンテキストメニュー」-「新規作成」から
ウィンドウを新規作成します。
|
この部分のメソッドを呼び出すだけなのではないでしょうか?
引用: |
|
下記に多重起動部分のコードを記載いたします。
コード: |
|
<STAThread()> _
Public Shared Sub Main()
' Mutex の新しいインスタンスを生成
Dim userMutex As System.Threading.Mutex = New System.Threading.Mutex(False, Application.ProductName)
' Mutex のシグナルを受信できるかどうか判断
If userMutex.WaitOne(0, False) = True Then
' アプリケーション実行
Application.Run(New MainWindow)
' 解放
userMutex.ReleaseMutex()
Else
' 既にアプリケーションが起動中
' ここに新規作成処理を教える処理を記載したい
End If
' 破棄
userMutex.Close()
End Sub
|
|
これって、Mutex を保持するオブジェクトが、GC の対象になる可能性がありませんか?
プライベート メンバな変数にするか、GC の対象から外してあげてください。
二重起動を確実に禁止する
また、Try 〜 Finally で Close を保証してあげてください。
_________________ C# と VB.NET の入門サイト
じゃんぬねっと日誌
|
- ダッチ
- 大ベテラン
- 会議室デビュー日: 2005/10/31
- 投稿数: 113
|
投稿日時: 2005-12-04 14:54
回答ありがとうございます。
引用: |
|
じゃんぬねっとさんの書き込み(2005-12-04 14:27) より:
これって、Mutex を保持するオブジェクトが、GC の対象になる可能性がありませんか?
プライベート メンバな変数にするか、GC の対象から外してあげてください。
二重起動を確実に禁止する
また、Try 〜 Finally で Close を保証してあげてください。
|
Mutexの扱いを修正いたしました。
コード: |
|
<STAThread()> _
Public Shared Sub Main()
Dim userMutex As System.Threading.Mutex
Try
' Mutex の新しいインスタンスを生成
userMutex = New System.Threading.Mutex(False, Application.ProductName)
' Mutex のシグナルを受信できるかどうか判断
If userMutex.WaitOne(0, False) = True Then
' Mutex をガベージコレクションから外す
GC.KeepAlive(userMutex)
' アプリケーション実行
Application.Run(New MainWindow)
' 解放
userMutex.ReleaseMutex()
Else
' 既にアプリケーションが起動中
Dim mainWindow As MainWindow = New MainWindow
' 新規作成処理
mainWindow.AddWindow()
End If
Finally
' 破棄
If Not userMutex Is Nothing Then
userMutex.Close()
End If
End Try
End Sub
|
引用: |
|
この部分のメソッドを呼び出すだけなのではないでしょうか?
|
' 新規作成処理
mainWindow.AddWindow()
を実行しても一瞬でウィンドウが閉じてしまいます。
おそらくApplication.Run(New MainWindow)
で生成した MainWindow のインスタンスに対して
処理を行っていないからではないかと思います。
そのためメッセージループされていないのではないでしょうか。
|
- Hongliang
- ぬし
- 会議室デビュー日: 2004/12/25
- 投稿数: 576
|
投稿日時: 2005-12-04 15:24
GC.KeepAliveは、
引用: |
|
このメソッドは、 obj オブジェクトを参照し、ルーチンの開始時からこのメソッドが呼び出される時点までの間、そのオブジェクトをガベージ コレクションの対象から外します。このメソッドのコードは、 obj を使用可能にする必要がある命令の範囲の最初ではなく最後に作成します。
|
の通り、事前ではなく事後に呼び出すメソッドです。非常に奇妙な印象を受けますが。
さて、Mutexで多重起動を制限したとしても、実際に実行ファイルをダブルクリックしたときに起動するのは元々存在しているプロセスとは(当然のことながら)別のプロセスです。
既存プロセスに処理をお願いしなければなりません。
手段はいくつか考えられます。代表的なものは、- .NETのプロセス間通信である.NET Remoting
- DDE
- Windowsメッセージ
- 名前つきイベント(Mutexでもできるっけ)
下のものほど、新規プロセスから既存プロセスに送信できる情報が限られるようになります。また例に挙げたものでは.NET Remoting以外はWin32APIに頼る必要性が出てきます。
プロセス間通信で調べれば情報は様々に出てくるでしょう。
一番実装が簡単なのは、適当なメッセージをSendMessage関数(Win32APIです)を使って送信することでしょうか。
既存プロセスは対応する手段で起動を感知し、それに対応した処理を行います。
<チラシの裏>
そういえばDDEMLのクラス化放置しっぱなしだな……。
</チラシの裏>
|
- ダッチ
- 大ベテラン
- 会議室デビュー日: 2005/10/31
- 投稿数: 113
|
投稿日時: 2005-12-04 15:44
回答ありがとうございます。
引用: |
|
Hongliangさんの書き込み(2005-12-04 15:24) より:
GC.KeepAliveは、
このメソッドは、 obj オブジェクトを参照し、ルーチンの開始時からこのメソッドが呼び出される時点までの間、そのオブジェクトをガベージ コレクションの対象から外します。このメソッドのコードは、 obj を使用可能にする必要がある命令の範囲の最初ではなく最後に作成します。
の通り、事前ではなく事後に呼び出すメソッドです。非常に奇妙な印象を受けますが。
|
確かに奇妙な印象を受けますがご指摘ありがとうございます。
修正いたします。
引用: |
|
- .NETのプロセス間通信である.NET Remoting
- DDE
- Windowsメッセージ
- 名前つきイベント(Mutexでもできるっけ)
|
貴重な情報ありがとうございます。
なるべく Win32API は使用したくありませんので、
ますは.NET Remoting から調べたいと思います。
|
- なちゃ
- ぬし
- 会議室デビュー日: 2003/06/11
- 投稿数: 872
|
投稿日時: 2005-12-04 16:05
ちょっと疑問なんですが…
今回出てるような処理の流れで、GC.KeepAlive()って必要ですか?
|
- Hongliang
- ぬし
- 会議室デビュー日: 2004/12/25
- 投稿数: 576
|
投稿日時: 2005-12-04 16:16
引用: |
|
ちょっと疑問なんですが…
今回出てるような処理の流れで、GC.KeepAlive()って必要ですか?
|
Mutexがローカル変数である場合は必要です。
http://dobon.net/vb/dotnet/process/checkprevinstance.html
うまい理屈付けは私にはできてないんですけど。
|
- なちゃ
- ぬし
- 会議室デビュー日: 2003/06/11
- 投稿数: 872
|
投稿日時: 2005-12-04 16:23
mutexのcloseが後ろにあっても駄目なんですかね?
※念のため、私は「後ろにCloseがあるから不要なのでは?」と思ったわけです。
|