• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:Active Basic 他のアプリケーションを終了させる)

Active Basicで他のアプリケーションを終了させる方法

このQ&Aのポイント
  • Active Basic4.23.00を使用しています。他のアプリケーションを終了させる方法について質問です。
  • FindWindow関数についてお聞きしたいです。lpClassNameの指定やlpWindowNameにNULLを指定する場合のハンドル取得について教えてください。
  • コードに誤りがある場合は指摘お願いします。TerminateProcessでエラーが発生する場合の対処方法も教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.6

API宣言を Declare Function EnumProcesses Lib "psapi.dll" _ (lpidProcess As DWord,cb As DWord ,ByRef cbNeeded As DWord) As Integer といった具合に cbNeededを ByRefの参照渡しにしてください たぶんここが値渡しになっているので EnumProcess側でデータを書き込もうとしてエラーになっているのでしょう

if-so-at
質問者

お礼

何とかできました! 此処までのお付き合い、ありがとうございました

その他の回答 (5)

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.5

Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)   Dim nRet As Integer   Dim err As Long   Dim code As DWord   nRet = EnumProcesses(ProcessID,Len(ProcessID),ProcessSize)   If nRet=0 Then     Error("EnumProcesses")   End If   ProcessNum = ProcessSize / SizeOf( DWord ) End Sub といった具合でしょう GetProcessModulesは ActiveBasicから直接呼び出すのは無理なようです 関数の呼び出し規約が違っているようで C/C++でActiveBasic用のラッパーを作らないといけないようです EnumProcessesではアクセス違反などは確認できておりません どこまで実行できているのかを確認しましょう debugステートメントを挿入して F2キーでデバッグ実行 ブレークポイントで止まったら デバッガの ステップアウトなどで1行ごとに実行してみましょう

if-so-at
質問者

お礼

>>EnumProcessesではアクセス違反などは確認できておりません >>debugステートメントを挿入して F2キーでデバッグ実行 やってみましたが、 nRet = EnumProcesses(ProcessID,Len(ProcessID),ProcessSize) でアクセス違反が起こります。 コンピュータの再起動、プロジェクトの作成のやり直しなどをやってみましたが、アクセス違反が直りません。 これは、コンピュータが可笑しいのでしょうか

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.4

ごめんなさい EnumProcessesの第2引数は配列の大きさなので Lenで求めたバイト長でよかったですね EnumProcesses( ProcessID, Len( ProcessID ), ProcessSize ) といった具合でした

if-so-at
質問者

お礼

ご回答ありがとうございます。 試してみたのですが、アクセス違反が取れません。 訂正をお願いします。 Declare Function EnumProcesses Lib "psapi.dll"(lpidProcess As DWord,cb As DWord ,cbNeeded As DWord) As Integer Dim ProcessID[1024] As DWord 'プロセスの配列 Dim ProcessNum As DWord 'プロセスの個数 Dim ProcessSize As DWord 'プロセスのサイズ '----------------------------------------------------------------------------- ' ここから下は、イベントプロシージャを記述するための領域になります。 Sub MainWnd_Destroy() Vul_DestroyObjects() PostQuitMessage(0) End Sub Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT) Dim nRet As Integer Dim err As Long Dim code As DWord EnumProcesses(ProcessID,Len(ProcessID),ProcessSize) If nRet=0 Then Error("EnumProcesses") End If End Sub Sub Error(ErrorWord As BytePtr) Dim length As Long Dim w As BytePtr length=lstrlen(ErrorWord) length=length+lstrlen("でエラーが発生しました") w=malloc(length+1) w=lstrcat(ErrorWord,"でエラーが発生しました") MessageBox(hMainWnd,w,"Error",MB_OK or MB_ICONHAND) ExitProcess(0) End Sub スレッド(&H284)でアクセス違反がありました(EPI=&H76BA3B23)。

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.3

SizeOfではなく LenとSizeOfを使って配列の個数を求めます Len(ProcessID)で 配列ProcessIDのバイト長を取得します SizeOf(DWord)で 配列要素1つのバイト長を求めます これの商を求めれば個数が求まります Len(ProcessID)/SizeOf(DWord) といった具合です EnumProcesses(ProcessID, Len(ProcessID)/SizeOf(DWord), ProcessSize) といった具合です 第3引数に『&』は不要です お示しのページの例は Cなので 変数のアドレスを渡すのに&演算子を使います ActiveBasicでは アドレス渡しは関数宣言時の 引数に ByRefを記述すればいいのです また 返り値は HWND型ではなく Integer(本来はBOOL)なのでhWndで受けるのではなく Dim nRet As Integer nRet = EnumProcesses(ProcessID, Len(ProcessID)/SizeOf(DWord), ProcessSize) などとするか 直接 if EnumProcesses(ProcessID, Len(ProcessID)/SizeOf(DWord), ProcessSize) then などと判断に使ったりします

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.2

BOOLは Integerで代用可能ですよ declare EnumProcessModules Lib "psapi" _ (hProcess as HANDLE, lphModule() as HANDLE ,cb as DWord ByRef lpcbNeeded as DWord) as Integer といった具合です

if-so-at
質問者

お礼

ご回答ありがとうございます。 とりあえず、IDを取得しようと Declare Function EnumProcesses Lib "psapi.dll"(lpidProcess As DWord,cb As DWord ,cbNeeded As DWord) As Integer を定義しましたが、上手くIDが返ってきません。 いろいろ、探し、 http://nienie.com/~masapico/api_EnumProcesses.html を参考にプログラムを書いてみましたが、『無効』だといわれます。 'グローバル Dim ProcessID[1024] As DWord 'プロセスの配列 Dim ProcessNum As DWord 'プロセスの個数 Dim ProcessSize As DWord 'プロセスのサイズ 'ウインドウクリエイト hWnd=EnumProcesses(ProcessID,SizeOf(ProcessID),&ProcessSize) ↑SizeOfに『ProcessID』を入れると無効といわれ、(これが正しい使い方だと思ったので)『DWord』と入れるとアクセス違反が起こり、SizeOfを消すと、アクセス違反が起きます。 どのように扱えばいいのでしょうか。

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

ProcessハンドルとWindowハンドルを混同して使っているのが問題なのでしょう ProcessハンドルはEnumProcessesなどでプロセスIDを取得して このIDを使ってOpenProcessで取得します 使い終わったら CloseHandleでプロセスハンドルは閉じましょう プロセスハンドルには関連付けされたモジュールを取得するためには EnumProcessModulesをつかってモジュールハンドルを取得して このハンドルからGetModuleBaseNameをつかってEXEやDLLの名前を取得します これらのAPI関数はActiveBasicで準備されていないようですので Declareステートメントで新規に宣言しないといけないでしょう テストでEnumProcessesを作ってみたのですがEnumProcessModulesでどうしてもモジュールハンドルが取得できませんでした EnumProcessesで起動しているプロセスIDは取得でき その数もタスクマネージャの値に合致していました FindWindowで取得できるのはWindowハンドルです このアプリを閉じたいのでしたら WM_CLOSEメッセージを SendMessageで送るほうがいいでしょう FindWindowのlpClassNameはアプリケーション側でWindowsに対して 自分のウィンドウはこの名前で登録します といった手続きがあります これは、アプリごとに任意に行いますので メモ帳のようなアプリが "WebBrowser"というクラス名に登録してもいいことになっています Exeのベース名(sample.exeなら『sample』)で登録される場合が多いですが...

if-so-at
質問者

お礼

ご回答ありがとうございます。 EnumProcessesやEnumProcessModulesを定義しようと探してみましたが、 BOOL EnumProcessModules(HANDLE hProcess,HMODULE * lphModule,DWORD cb LPDWORD lpcbNeeded) のように、DLLではなく『BOOL』と言うものを使っていますよね。 ABではBOOL型を受け付けてくれません。 どのように定義すればいいのでしょうか。 ご教授いただければ嬉しいです

関連するQ&A