HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2017
0422
プロセス一覧の取得方法9解決


リンク

2017/4/22(Sat) 17:42:47|NO.79202

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

 プロセスの一覧を取得したいと思い、下記サイトからモジュールを入手したのですが、コメントアウトしている部分をコメント解除すると、29行目でエラー23が表示されてしまいます。

http://hspnext.com/hspkura/hspkura02.htm

変更したソースが下記になります。

----------


#module ;***** 必要となるAPIや定数の定義 ***** #uselib "user32.dll" #cfunc GetDesktopWindow "GetDesktopWindow" #cfunc GetWindow "GetWindow" int,int #cfunc GetWindowText "GetWindowTextA" int,var,int #cfunc IsWindowVisible "IsWindowVisible" int #uselib "kernel32.dll" #cfunc lstrcmp "lstrcmp" sptr,sptr #define MAX_PATH260 #define GW_OWNER$00000004 #define GW_HWNDNEXT$00000002 #define GW_CHILD$00000005 #deffunc getproclist var prm1 WndDesk=GetDesktopWindow() if WndDesk!0 { WndCurWin=GetWindow(WndDesk,GW_CHILD) }else{ return -1 } ;***** 稼動中のプロセスを全て列挙 ***** buf="" : sdim szClassName,MAX_PATH : sdim chWinTxt,MAX_PATH count=0 ;▼▼▼▼フィルタリングしないで全て列挙する場合▼▼▼▼ while WndCurWin!0 await ret=GetWindowText(WndCurWin,varptr(chWinTxt),MAX_PATH) // ←この行でエラーが発生します。 i=WndCurWin : buf+=str(i)+","+chWinTxt+"\n" count++ WndCurWin=GetWindow(WndCurWin,GW_HWNDNEXT) wend while WndCurWin!0 await ret=GetWindowText(WndCurWin,chWinTxt,MAX_PATH) ;▼フィルタリング ; (1)不可視状態のもの ; (2)トップレベルウィンドウではないもの ; (3)キャプションを持っていないもの ; (4)シェル if chWinTxt!"" { vs=IsWindowVisible(WndCurWin) if vs!0 { owhwnd=GetWindow(WndCurWin,GW_OWNER) if owhwnd==0 { if chWinTxt!"Program Manager" { lpString="Progman" cp=lstrcmp(szClassName,lpString) if cp!0 { i=WndCurWin : buf+=str(i)+","+chWinTxt+"\n" count++ } } } } } WndCurWin=GetWindow(WndCurWin,GW_HWNDNEXT) wend prm1=buf sdim szClassName,0 : sdim chWinTxt,0 : sdim buf,0 return count #global target="" : temp=str(temp) : work=str(work) getproclist temp : num=stat dialog temp

----------

 解決法があれば、教えていただけると幸いです。
 よろしくお願いいたします。



この記事に返信する


inovia

リンク

2017/4/22(Sat) 21:29:59|NO.79215


ret=GetWindowText(WndCurWin,varptr(chWinTxt),MAX_PATH)
のvarptr()を外しましょう。
GetWindowTextの第二引数はvar宣言されているので、変数でないといけません。



リンク

2017/4/22(Sat) 22:28:11|NO.79216

 こんばんは、お返事ありがとうございます。

 とりあえず、エラーは解決したんですが、どうもうまく取得できないっぽいです。
 とりあえず、上記のモジュールの下に下記を加えて実行させてみたんですが、変数が空っぽのようです。

----------


target="" : temp=str(temp) : work=str(work) getproclist temp : num=stat notepos=0 : count=0 sdim mhwnd,8,num : sdim proctitle,260,num repeat num await ; getproclist命令での取得情報は、CSV形式なので個別に分解する repeat 2 getstr work,temp,notepos,',' : notepos+=strsize if cnt==0 : mhwnd(count)=work if cnt==1 : proctitle(count)=work loop ;***** 表示用に整形 ***** space="" : ls=strlen(mhwnd(count)) target+=mhwnd(count)+space+proctitle(count)+"\n" count++ loop dialog ""+count+"個のウィンドウハンドル・タイトルを取得しました。" ; ←これは正常に表示されます dialog target ; ←ここの変数が空っぽになってしまいます。

----------

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



inovia

リンク

2017/4/22(Sat) 22:45:04|NO.79217

>>79202のコードが

#define MAX_PATH260
とかなってるので、まあ正常に動かないだろうなぁと。
MAX_PATHと260の間にスペースもしくはTab文字が必要です。
というか、他の箇所もいろいろとコードが壊れていますね。

以下、修正

#module ;***** 必要となるAPIや定数の定義 ***** #uselib "user32.dll" #cfunc GetDesktopWindow "GetDesktopWindow" #cfunc GetWindow "GetWindow" int,int #cfunc GetWindowText "GetWindowTextA" int,var,int #cfunc IsWindowVisible "IsWindowVisible" int #uselib "kernel32.dll" #cfunc lstrcmp "lstrcmp" sptr,sptr #define MAX_PATH 260 #define GW_OWNER $00000004 #define GW_HWNDNEXT $00000002 #define GW_CHILD $00000005 #deffunc getproclist var prm1 WndDesk=GetDesktopWindow() if WndDesk!0 { WndCurWin=GetWindow(WndDesk,GW_CHILD) }else{ return -1 } ;***** 稼動中のプロセスを全て列挙 ***** buf="" : sdim szClassName,MAX_PATH : sdim chWinTxt,MAX_PATH count=0 ;▼▼▼▼フィルタリングしないで全て列挙する場合▼▼▼▼ while WndCurWin!0 await ret=GetWindowText(WndCurWin,chWinTxt,MAX_PATH) i=WndCurWin : buf+=str(i)+","+chWinTxt+"\n" count++ WndCurWin=GetWindow(WndCurWin,GW_HWNDNEXT) wend /* while WndCurWin!0 await ret=GetWindowText(WndCurWin,chWinTxt,MAX_PATH) ;▼フィルタリング ; (1)不可視状態のもの ; (2)トップレベルウィンドウではないもの ; (3)キャプションを持っていないもの ; (4)シェル if chWinTxt!"" { vs=IsWindowVisible(WndCurWin) if vs!0 { owhwnd=GetWindow(WndCurWin,GW_OWNER) if owhwnd==0 { if chWinTxt!"Program Manager" { lpString="Progman" cp=lstrcmp(szClassName,lpString) if cp!0 { i=WndCurWin : buf+=str(i)+","+chWinTxt+"\n" count++ } } } } } WndCurWin=GetWindow(WndCurWin,GW_HWNDNEXT) wend */ prm1=buf sdim szClassName,0 : sdim chWinTxt,0 : sdim buf,0 return count #global ;***** Sample ***** screen 0,640,480,0,ginfo_dispx-640>>1,ginfo_dispy-480>>1 font "MS ゴシック",14,0 : objmode 2 target="" : temp=str(temp) : work=str(work) pos 20,50:mesbox target,600,200,5 ;***** プロセスリスト取得 ***** getproclist temp : num=stat ;***** ハンドルとタイトル名を分解して配列に格納 ***** notepos=0 : count=0 sdim mhwnd,8,num : sdim proctitle,260,num repeat num await ; getproclist命令での取得情報は、CSV形式なので個別に分解する repeat 2 getstr work,temp,notepos,',' : notepos+=strsize if cnt==0 : mhwnd(count)=work if cnt==1 : proctitle(count)=work loop ;***** 表示用に整形 ***** space="" : ls=strlen(mhwnd(count)) : gosub *adjspc target+=mhwnd(count)+space+proctitle(count)+"\n" count++ loop color 0,0,0 pos 20,280 : mes ""+count+"個のウィンドウハンドル・タイトルを取得しました。" objprm 0,target stop ;***** スペース調整 ***** *adjspc sp=12-ls : repeat sp : space+=" " : loop return



リンク

2017/4/23(Sun) 07:53:05|NO.79226

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

 一応動くことは動きましたが、自分が想定していたのとちょっと違いました。
 これって、実行されているファイル名は取得できないんですかね。
 よろしければ教えていただけると幸いです。
 それでは。



inovia

リンク

2017/4/23(Sun) 12:21:58|NO.79231

作ってみたけど、いろいろ制約が出てます。
・HSPが標準ユーザーで動いている場合は、
管理者権限などの高い権限で動いている名前の取得に失敗する
⇒ [プロセスを開けません] と出る

・HSP 32bit版を使用している場合は、64bitプロセスの名前の取得に失敗する
(※現状64bit版のHSPはありますが、実装に必要な機能が不足しています)
⇒ [ハンドルの取得に失敗しました] と出る

【参考】
32bit プロセスは 64bit プロセスを見つけられない
http://d.hatena.ne.jp/tt_clown/20110416/1302927489


#module ;***** 必要となるAPIや定数の定義 ***** #uselib "user32.dll" #cfunc GetDesktopWindow "GetDesktopWindow" #cfunc GetWindow "GetWindow" int,int #cfunc GetWindowText "GetWindowTextA" int,var,int #cfunc IsWindowVisible "IsWindowVisible" int #func GetWindowThreadProcessId "GetWindowThreadProcessId" int, int #uselib "kernel32.dll" #cfunc lstrcmp "lstrcmp" sptr,sptr #cfunc OpenProcess "OpenProcess" int, int, int #func CloseHandle "CloseHandle" int #func EnumProcessModulesEx "K32EnumProcessModulesEx" int, var, int, var, int #define MAX_PATH 260 #define GW_OWNER $00000004 #define GW_HWNDNEXT $00000002 #define GW_CHILD $00000005 #define PROCESS_VM_READ $00000010 #define PROCESS_QUERY_INFORMATION $00000400 #define LIST_MODULES_ALL 0x03 #uselib "psapi.dll" #func GetModuleFileNameEx "GetModuleFileNameExA" int, int, var, int #defcfunc getExeNameStringByHWnd int _hwnd procID = 0 GetWindowThreadProcessId _hwnd, varptr(procID) if procID == 0 : return "[ウィンドウハンドルが無効です]" hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, procID) if hProc == 0 : return "[プロセスを開けません]" hModule = 0 : cbNeeded = 0 EnumProcessModulesEx hProc, hModule, 4, cbNeeded, LIST_MODULES_ALL if stat == 0 : CloseHandle hProc : return "[ハンドルの取得に失敗しました]" sdim destStrExeName, 261 GetModuleFileNameEx hProc, hModule, destStrExeName, 260 if stat == 0 : CloseHandle hProc : return "[名前の取得に失敗しました]" CloseHandle hProc return getpath(destStrExeName, 8 + 16) #deffunc getproclist var prm1 WndDesk=GetDesktopWindow() if WndDesk!0 { WndCurWin=GetWindow(WndDesk,GW_CHILD) }else{ return -1 } ;***** 稼動中のプロセスを全て列挙 ***** buf="" : sdim szClassName,MAX_PATH : sdim chWinTxt,MAX_PATH count=0 ;▼▼▼▼フィルタリングしないで全て列挙する場合▼▼▼▼ while WndCurWin!0 await ret=GetWindowText(WndCurWin,chWinTxt,MAX_PATH) i=WndCurWin : buf+=str(i)+","+getExeNameStringByHWnd(i)+","+chWinTxt+"\n" count++ WndCurWin=GetWindow(WndCurWin,GW_HWNDNEXT) wend prm1=buf sdim szClassName,0 : sdim chWinTxt,0 : sdim buf,0 return count #global ;***** Sample ***** screen 0,640,480,0,ginfo_dispx-640>>1,ginfo_dispy-480>>1 font "MS ゴシック",14,0 : objmode 2 target="" : temp=str(temp) : work=str(work) pos 20,50:mesbox target,600,200,5 ;***** プロセスリスト取得 ***** getproclist temp : num=stat ;***** ハンドルとタイトル名を分解して配列に格納 ***** notepos=0 : count=0 sdim mhwnd,8,num : sdim procexe,260,num : sdim proctitle,260,num repeat num await ; getproclist命令での取得情報は、CSV形式なので個別に分解する repeat 3 getstr work,temp,notepos,',' : notepos+=strsize if cnt==0 : mhwnd(count)=work if cnt==1 : procexe(count)=work if cnt==2 : proctitle(count)=work loop ;***** 表示用に整形 ***** space="" : ls=strlen(mhwnd(count)) space2="" : ls2=strlen(procexe(count)) : gosub *adjspc target+=mhwnd(count)+space+procexe(count)+space2+proctitle(count)+"\n" count++ loop color 0,0,0 pos 20,280 : mes ""+count+"個のウィンドウハンドル・タイトルを取得しました。" objprm 0,target stop ;***** スペース調整 ***** *adjspc sp=12-ls : repeat sp : space+=" " : loop sp=32-ls2 : repeat sp : space2+=" " : loop return



inovia

リンク

2017/4/23(Sun) 12:41:36|NO.79232

CreateToolhelp32Snapshot系であれば、取得できる模様。
http://blog.goo.ne.jp/hiro239415/e/8146d7c0f10246f455b25a2b6e3728f1



リンク

2017/4/23(Sun) 16:07:14|NO.79238

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

 とりあえず、

http://blog.goo.ne.jp/hiro239415/e/8146d7c0f10246f455b25a2b6e3728f1

を参考に、モジュールを作ろうとしたんですが…。
 どうもうまくいきません。
 なかなか慣れてないので、いろいろ突っ込みはあると思いますが、どうしたらよいか教えていただければ幸いです。
 下記がソースになります。

----------


#module getProcess //関数の登録 #uselib "kernel32.dll" #func CreateToolhelp32Snapshot "CreateToolhelp32Snapshot" int,int #func Module32First "Module32First" int , sptr #func Module32Next "Module32Next" int , sptr #func Process32First "Process32First" int , sptr #func Process32Next "Process32Next" int , sptr #func CloseHandle "CloseHandle" int #uselib "user32.dll" #func GetWindowLongA "GetWindowLongA" int,int #func SetWindowLongA "SetWindowLongA" int,int,int #func SetWindowPos "SetWindowPos" int,int,int,int,int,int,int #func MoveWindow "MoveWindow" int,int,int,int,int,int ////////////////////////////////////////////////////////////// //変数 dim er dim lb1 dim lb2 sdim lbdata , 1024 sdim data , 260 sdim mbdata , 1024 dim hpsnap dim hmsnap dim p_entry, 74 dim p_id , 64 dim m_entry, 137 // スナップショット作成 //#func CreateToolhelp32Snapshot "CreateToolhelp32Snapshot" int,int // 戻り値にスナップショットのハンドル // // 第一引数 // 「TH32CS_INHERIT:(0x80000000)」スナップショットのハンドルを継承 // 「TH32CS_SNAPALL:(0x0f)」以下4つをあわせたもの // 「TH32CS_SNAPHEAPLIST:(0x01)」指定したプロセスのヒープリストを含む // 「TH32CS_SNAPMODULE:(0x08)」指定したプロセスのモジュールリストを含む // 「TH32CS_SNAPPROCESS(0x02)」プロセスリストを含む // 「TH32CS_SNAPTHREAD(0x04)」スレッドリストを含む // 第二引数 // プロセス識別子を指定(TH32CS_SNAPMODULEを指定した時のみ) // 0を指定すると現在のプロセスになる //プロセスの取得 #deffunc get_process var prm1 CreateToolhelp32Snapshot 0x0f, 0 hpsnap = stat if hpsnap==-1 : dialog "CreateToolhelp32Snapshot error" : stop dim p_id , 64 lbdata="" : notesel lbdata p_entry(0) = 296 Process32First hpsnap , varptr(p_entry) er = stat repeat -1 if er == 0 : break getstr data , p_entry , 36 , '\0' noteadd data , -1 p_id(cnt) = p_entry(2) Process32Next hpsnap , varptr(p_entry) er = stat loop prm1 = lbdata CloseHandle hpsnap return #global get_process list dialog list

----------

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



inovia

リンク

2017/4/23(Sun) 16:50:46|NO.79239

#module 〜 #global 内で、
#deffunc 〜 return などの外側に変数の初期化を行っても無視されます。

以下はダメな例。

#module _TEST_MOD_ sdim s, 64 : s = "ABC" // ← この位置だと無視される #deffunc test mes s // ↑が無視されているので、デフォルトの0が表示される return #global test

正しく表示される例。

#module _TEST_MOD_ #deffunc local init sdim s, 64 : s = "ABC" // これなら良い return #deffunc test mes s // ABCが表示される return #global init@_TEST_MOD_ test

他にもいろいろやり方あるケドね。

#module getProcess //関数の登録 #uselib "kernel32.dll" #func CreateToolhelp32Snapshot "CreateToolhelp32Snapshot" int,int #func Module32First "Module32First" int , sptr #func Module32Next "Module32Next" int , sptr #func Process32First "Process32First" int , sptr #func Process32Next "Process32Next" int , sptr #func CloseHandle "CloseHandle" int #uselib "user32.dll" #func GetWindowLongA "GetWindowLongA" int,int #func SetWindowLongA "SetWindowLongA" int,int,int #func SetWindowPos "SetWindowPos" int,int,int,int,int,int,int #func MoveWindow "MoveWindow" int,int,int,int,int,int ////////////////////////////////////////////////////////////// //変数 #deffunc local var_init dim er dim lb1 dim lb2 sdim lbdata , 1024 sdim data , 260 sdim mbdata , 1024 dim hpsnap dim hmsnap dim p_entry, 74 dim p_id , 64 dim m_entry, 137 return // スナップショット作成 //#func CreateToolhelp32Snapshot "CreateToolhelp32Snapshot" int,int // 戻り値にスナップショットのハンドル // // 第一引数 // 「TH32CS_INHERIT:(0x80000000)」スナップショットのハンドルを継承 // 「TH32CS_SNAPALL:(0x0f)」以下4つをあわせたもの // 「TH32CS_SNAPHEAPLIST:(0x01)」指定したプロセスのヒープリストを含む // 「TH32CS_SNAPMODULE:(0x08)」指定したプロセスのモジュールリストを含む // 「TH32CS_SNAPPROCESS(0x02)」プロセスリストを含む // 「TH32CS_SNAPTHREAD(0x04)」スレッドリストを含む // 第二引数 // プロセス識別子を指定(TH32CS_SNAPMODULEを指定した時のみ) // 0を指定すると現在のプロセスになる //プロセスの取得 #deffunc get_process var prm1 ; こことか。ここなら@getProcessはなくて良い ; var_init CreateToolhelp32Snapshot 0x0f, 0 hpsnap = stat if hpsnap==-1 : dialog "CreateToolhelp32Snapshot error" : stop dim p_id , 64 lbdata="" : notesel lbdata p_entry(0) = 296 Process32First hpsnap , varptr(p_entry) er = stat repeat -1 if er == 0 : break getstr data , p_entry , 36 , '\0' noteadd data , -1 p_id(cnt) = p_entry(2) Process32Next hpsnap , varptr(p_entry) er = stat loop prm1 = lbdata CloseHandle hpsnap return #global ; こことか var_init@getProcess get_process list dialog list



リンク

2017/4/23(Sun) 18:29:47|NO.79249

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

 無事取得に成功しました。
 ありがとうございました。

 一応、完成形のモジュールを張っておきます。
 ちなみに、モジュールも取得できるようにしてみました。

----------


#module getProcess //関数の登録 #uselib "kernel32.dll" #func CreateToolhelp32Snapshot "CreateToolhelp32Snapshot" int,int #func Module32First "Module32First" int , sptr #func Module32Next "Module32Next" int , sptr #func Process32First "Process32First" int , sptr #func Process32Next "Process32Next" int , sptr #func CloseHandle "CloseHandle" int //プロセスの取得 #deffunc get_process var prm1 dim er dim lb1 dim lb2 sdim lbdata , 1024 sdim data , 260 sdim mbdata , 1024 dim hpsnap dim hmsnap dim p_entry, 74 dim p_id , 64 dim m_entry, 137 CreateToolhelp32Snapshot 0x0f, 0 hpsnap = stat if hpsnap==-1 : dialog "CreateToolhelp32Snapshot error" : stop dim p_id , 64 lbdata="" : notesel lbdata p_entry(0) = 296 Process32First hpsnap , varptr(p_entry) er = stat repeat -1 if er == 0 : break getstr data , p_entry , 36 , '\0' noteadd data , -1 p_id(cnt) = p_entry(2) Process32Next hpsnap , varptr(p_entry) er = stat loop prm1 = lbdata CloseHandle hpsnap return //モジュールの取得 #deffunc get_module var prm1 dim er dim lb1 dim lb2 sdim lbdata , 1024 sdim data , 260 sdim mbdata , 1024 dim hpsnap dim hmsnap dim p_entry, 74 dim p_id , 64 dim m_entry, 137 get_process lbdata CreateToolhelp32Snapshot 0x0f , p_id(lb1) hmsnap = stat if hmsnap==-1{ return -1 } notesel lbdata : noteget data , lb1 // title TITLENAME+" : "+data mbdata = "" : notesel mbdata m_entry(0) = 548 Module32First hmsnap , varptr(m_entry) : er = stat repeat -1 if er == 0 : break getstr data , m_entry , 288 , '\0' noteadd data , -1 Module32Next hmsnap , varptr(m_entry) : er = stat loop prm1 = mbdata CloseHandle hmsnap return #global

----------

 ありがとうございました。
 それでは。



ONION software Copyright 1997-2023(c) All rights reserved.