あるソフト(メモ帳や電卓など)を起動したときに、起動するアプリケーションを作りたいと思っています。
ですが、調べてみたり、できることはやったと思うのですが自分の力では実現できなかったために、皆様のお力を借りたいと思っております。
1.あるソフト(メモ帳や電卓など)を起動したときに、起動するアプリケーションの作り方
2.あるソフトが起動したときに、ある処理を行う
このどちらかのやり方がわかる方がいらっしゃいましたら、ご教授のほど宜しくお願いします
>1.あるソフト(メモ帳や電卓など)を起動したときに、起動する
これは多分無理だと思います。逆に自分で作ったアプリケーションから"あるソフト"を起動することは可能ですが。
>2.あるソフトが起動したときに、ある処理を行う
こちらはWindowsが起動したとき(またはそれ以後)に自分で作ったアプリケーションを常駐させておき、"あるソフト"が起動したかどうかをFindWindowAPIなどで調べて"ある処理"を行えばできると思います。
起動プロセス列挙を
タイマーで監視しつづけて
たとえば
C:\WINNT\system32\notepad.exe
が存在することを調べる
って方法や
Window列挙をタイマーで監視して
notepadのWindowが存在していることをチェックする
という方法もあるようなきがしますが。
いかがでしょう。
簡単に考えると、このような形はいかがでしょうか。
メモ帳を立ち上げると、一度だけ電卓も立ち上がる。
// uses節に ShellAPI を追加
変数
hNote : HWND; {ハンドル}
CalcFlg : Boolean; {一度だけ電卓を立ち上げるため}
const
// 電卓(私の環境の場合)
FN = 'C:\WINNT\system32\Calc.exe';
//-----------------------------------------------
// 起動時の処理
//-----------------------------------------------
procedure TForm1.FormCreate(Sender: TObject);
begin
{メモ帳ハンドルを取得}
hNote := FindWindow('Notepad',nil);
// すでに起動していたら
if hNote <> 0
then
begin
ShellExecute(Handle,'open',PChar(FN),nil,nil,SW_SHOW);
CalcFlg := true;
end
// 起動していなかったら
else
CalcFlg := False;
end;
// 起動時・途中終了時のチェック
procedure TForm1.Timer_CheckTimer(Sender: TObject);
begin
{メモ帳のハンドルを取得}
hNote := FindWindow('Notepad',nil);
if hNote <> 0
then
begin
if CalcFlg = False
then
begin
ShellExecute(Handle,'open',PChar(FN),nil,nil,SW_SHOW);
CalcFlg := True;
end;
end
else
CalcFlg := False;
end;
起動中かどうかで、タイマーのインターバルを変えたり、
このプログラムを非表示にしたり、二重起動不可にしても良いかも
しれません。
こういう感じでしょうか?
リリカちゃんが日記更新してる!
不覚にも上のリンクを辿ってしまった…
単なる広告です
私も幾らか調べてみましたが、よく分かりませんでした。
要は「ソフトを起動を知る」ですよね?
もちろん、タイマーで常にチェックするのも手ですし、タスクマネージャはタイマーでプロセスを監視しているようですが、デスクトップ(タスクバー)なんかはもっとスマートな方法で実現しているようです。
どうやってるんでしょうね…
タスクバーでは、IShellExecuteHookインターフェースでフックしているのでは?
IShellExecuteHookを実装できればできそうですね。
COMを登録して、
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellExecuteHooks
にCLSIDを追加しておけば動くと思います。
>>タスクバーでは、IShellExecuteHookインターフェースでフックしているのでは?
ご指摘ありがとうございます。
IShellExecuteHookを元に調べていったら
SetWindowsHookExでWH_SHELLをフックしてもアプリケーションの起動を知ることができることが分かり、試してみたところアプリの起動を識別できそうです。
//----------------------------------------------------------------
// アプリケーションの起動を察知
//----------------------------------------------------------------
library HookShell;
uses
SysUtils, Windows, Messages, Controls;
{$R *.RES}
var
hInst : Integer; //インスタンスハンドル
hHook : Integer; //フックプロシージャのハンドル
function JournalRecordProc(nCode:Integer;wParam:WPARAM;lParam:LPARAM):LRESULT;stdcall;
begin
result:=0;
if nCode < 0 then begin
result := CallNextHookEx(hHook,nCode,wParam,lParam)
end else begin
beep(1000,10); //確認
CallNextHookEx(hHook,nCode,wParam,lParam);
end;
end;
procedure SetHook;stdcall;
begin
//フック開始
hHook := SetWindowsHookEx(WH_SHELL,@JournalRecordProc,hInstance,0);
end;
procedure EndHook;stdcall;
begin
UnhookWindowsHookEx(hHook);
end;
exports
SetHook,
EndHook;
begin
hInst := hInstance;
end.
ああっ
質問は「あるソフトを起動したときに、起動するアプリケーション」
ですね。
上のDLLは「全てのソフトの起動を監視」するものです。
質問の回等となるものはにしの様のおっしゃるものです。
単に私の興味で調べてしまったものでスミマセンです。
皆様、多数のご意見をありがとうございました。
やはり一番無難なのはタイマーなどによる一定時間ごとの監視なのでしょうね。
一応、その方法ではちゃんと予定通りの動作を確認することが出来ました。
ただ、せっかく他の意見も出していただいたので、参考にして他の方法にもチャレンジしてみますね。少し格好の悪い方法なきもしますので^^;
また何かできましたら報告させていただきます。
皆様ありがとうございました、一応これにて解決ということで。
チェックミスです。申し訳ありません><
ツイート | ![]() |