複数起動時の処理について

投稿者: 投稿日:2019/09/30(Mon) 23:07:30 No.2504

 こんにちは、お世話になります。

 現在メディアプレーヤーのようなものを作ろうとしています。
 この際、コマンドラインオプションで何かファイルが渡された時に、すでにプログラムが起動されていたらそちらに渡されたファイル名を引き継ぎたいと考えています。
 一般的なソフトでは、ウィンドウメッセージでやりとりするのですが、プロデルではウィンドウメッセージが扱えないため、困っています。
 プラグインを自作して、ウィンドウメッセージが発生した際にイベントを発生させようとしましたが、イベントを発生させる方法がわからず、つまずいてしまいました。
 また、一時ファイルを経由するという方法も考えましたが、できればほかの方法がないかと考えています。
 何かアドバイスをいただけないでしょうか。

 以上、よろしくお願いいたします。

 追記:あまりきれいではないですが、ウィンドウメッセージの受け取り部分をC#で書いたものを貼り付けておきます。
 ちなみに、このプラグインを読み込むと、プロデルが動作停止してしまいます。

----- サンプルソース -----
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Produire;

namespace rdr_msg{
public class メッセージレシーバ : IProduireClass{
private delegate int D_MyWndProc(IntPtr hwnd, int msg, int wParam, int lParam);
private static int GWL_WNDPROC = -4;

[DllImport("user32.dll", EntryPoint = "GetWindowLongA")]
extern static int GetWindowLong(IntPtr hwnd, int nIndex);
[DllImport("user32.dll", EntryPoint = "SetWindowLongA")]
extern static int SetWindowLong(IntPtr hwnd, int nIndex, int dwNewLong);
[DllImport("user32.dll", EntryPoint = "SetWindowLongA")]
extern static int SetWindowLong(IntPtr hwnd, int nIndex, D_MyWndProc dwNewLong);
[DllImport("user32.dll", EntryPoint = "CallWindowProcA")]
extern static int CallWindowProc(int lpPrevWndFunc, IntPtr hwnd, int msg, int wParam, int lParam);

private static int lngWnP;

[自分で]
public void メッセージ処理開始([として]IntPtr ハンドル){
lngWnP = GetWindowLong(ハンドル, GWL_WNDPROC);
SetWindowLong(ハンドル, GWL_WNDPROC, MyWndProc);
}

[自分で]
public void メッセージ処理終了([として]IntPtr ハンドル){
SetWindowLong(ハンドル, GWL_WNDPROC, lngWnP);
}

private static int MyWndProc(IntPtr hwnd, int msg, int wParam, int lParam){
return CallWindowProc(lngWnP, hwnd, msg, wParam, lParam);
}
}

public class MessageEventArgs : EventArgs {
private int _msg;
private int _lParam;
private int _wParam;

public MessageEventArgs(int msg, int lParam, int wParam){
this._msg = msg;
this._lParam = lParam;
this._wParam = wParam;
}

public int msg{
get { return this._msg; }
}

public int lParam{
get { return this._lParam; }
}

public int wParam{
get { return this._wParam; }
}
}
}
----------

Re: 複数起動時の処理について

投稿者:通り道 投稿日:2019/10/03(Thu) 01:07:25 No.2506

回答ではないのですが、一応。

dotnetの場合、多重起動防止と引数の受け渡しには、一般的には
mutexとIPC通信を用います。
メッセージによる方法は、主に、Win32のNativeアプリの手法です。
(WinFormsも、中の仕組みは似たようなもんですが・・・)

mutexとIPCの両機能が、プロデルの命令になるかどうかは未確認です。

また、多重起動にかかわる処理は、できれば、プロデルのソースで
書かれたプログラムが実行されるよりも、もうちょっと手前でチェックと
引数の受け渡しをしてほしいところではあるので、プロデル本体に
対応を要望として挙げておくのも手かと思います。
(通常は、GUIの部品を確保し始めるよりも前で行う)

なお、本題のイベントの作り方は、
public event ProduireEventHandler ユーザセッション終了する;
のような、感じでプロデルから使うイベントを定義しておいて、
コンストラクタで、
this.SessionEnding += (sender, e) => { if (this.ユーザセッション終了する != null) { this.ユーザセッション終了する(sender, new ユーザセッション終了イベント情報(e)); } };
のような感じで、実際のイベントに紐づけています。
もととなるイベントからではない場合、コンストラクタ等での事前設定は不要で、イベントを発行したい時に、適切なsenderとイベント情報を引数に指定して、関数のように呼び出せば、大丈夫です(nullチェックは必要)
(上記は、WPFのApplicationを継承したクラスに使った例です)

Re^2: 複数起動時の処理について

投稿者: 投稿日:2019/10/06(Sun) 17:59:58 No.2508

 こんにちは、お世話になります。

 ありがとうございます。
 やはり現状では難しいですよね。
 一応複数起動を検出して、エラーメッセージを表示するくらいのことであれば、今でもできるんですが、起動中のプログラムに文字列等を送信するというのは難しいようです。
 やはりプロデルに機能として追加していただけるとうれしいんですけどね。

 以上、今後ともよろしくお願いいたします。

▲ページの先頭へ

- WebForum -