🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

Q&A

解決済

1回答

2114閲覧

Windows10で他プロセスのリストコントロールの内容を取得したい

m_ichikawa

総合スコア5

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

0グッド

0クリップ

投稿2019/12/02 23:27

編集2019/12/03 08:44

前提・実現したいこと

Windows10で他プロセスのリストコントロールの内容を取得したいです。

発生している問題・エラーメッセージ

C++にて他プロセスのリストコントロールのテキストを取得するためにSendMessage関数にLVM_GETITEMコマンドでWPARAMにテキストを取りたい行のインデックス、LPARAMにVirtualAllocEx関数で取得した仮想メモリを指定して使用しています。
結果は正常(true)で返ってくるのですが、テキスト(szText)の中身は全て'\0'です。

該当のソースコード

VC++

1#include "stdafx.h" 2#include <psapi.h> 3#include <tlhelp32.h> 4#include "rpa_operation.h" 5 6/////////////////////// 7//ファイル内での構造体 8/////////////////////// 9//プロセス検索構造体 10struct stProcessSearch 11{ 12 DWORD m_dwProcessIDs[1024]; 13 int m_nProcessCount; 14 stApplication_info* m_pApplication_info; 15}; 16 17//子ウィンドウ検索構造体 18struct stChildWindow 19{ 20 CString m_strTitleName; 21 CString m_strClassName; 22 int m_iControlID; 23 int m_nCount[2]; 24 CWnd* m_pWnd; 25}; 26 27/////////////////////// 28//プロトタイプ宣言 29/////////////////////// 30CWnd* ControlSerach(stApplication_info& application_info, LPCTSTR pszChildWindowTitle, LPCTSTR pszTitle, LPCTSTR pszClassName, int iControlID); //コントロールの検索 31BOOL GetProcessIdByName(DWORD dwProcessID, CString& exeName); //プロセスIDに対するexe名を取得する 32BOOL CALLBACK EnumWndProc(HWND hWnd, LPARAM lParam); //他のプログラムのウインドウハンドルを取得する 33BOOL CALLBACK EnumChildProc(HWND hWnd, LPARAM lParam); //子ウィンドウのウインドウハンドルを取得する 34int FindMenu(CMenu* pMenu, LPCTSTR pszTitle); //メニューの検索 35 36#define GWL_HWNDPARENT (-8) 37 38class CVirtualMemory 39{ 40private: 41 HANDLE m_hProcess; 42 CArray<LPVOID> m_arrayAlloc; 43public: 44 CVirtualMemory(CWnd* pWnd) 45 { 46 DWORD dwPID; 47 GetWindowThreadProcessId(pWnd->m_hWnd, &dwPID); 48 m_hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID); 49 } 50 LPVOID VirtualAlloc(SIZE_T dwSize) 51 { 52 LPVOID pAlloc = VirtualAllocEx(m_hProcess, NULL, dwSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); 53 if (pAlloc != NULL) { 54 m_arrayAlloc.Add(pAlloc); 55 } 56 return pAlloc; 57 } 58 59 BOOL Write(LPVOID lpBaseAddress, LPCVOID lpBuffer, SIZE_T nSize) 60 { 61 return WriteProcessMemory(m_hProcess, lpBaseAddress, lpBuffer, nSize, NULL); 62 } 63 64 BOOL Read(LPVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize) 65 { 66 return ReadProcessMemory(m_hProcess, lpBaseAddress, lpBuffer, nSize, NULL); 67 } 68 69 CVirtualMemory() 70 { 71 for(int i = 0; i < m_arrayAlloc.GetCount(); i++) 72 { 73 VirtualFreeEx(m_hProcess, m_arrayAlloc[i], 0, MEM_RELEASE); 74 } 75 CloseHandle(m_hProcess); 76 } 77}; 78 79//アプリケーション情報の取得 80BOOL GetApplicationInfo(stApplication_info& application_info) 81{ 82 stProcessSearch processSearch; 83 processSearch.m_pApplication_info = &application_info; 84 85 // PID一覧を取得 86 DWORD cbNeeded; 87 if (!EnumProcesses(processSearch.m_dwProcessIDs, sizeof(processSearch.m_dwProcessIDs), &cbNeeded)) { 88 return FALSE; 89 } 90 processSearch.m_nProcessCount = cbNeeded / sizeof(DWORD); 91 92 EnumWindows(EnumWndProc, (LPARAM)&processSearch); 93 94 if (application_info.m_dwProcessID != 0) { 95 return TRUE; 96 } 97 return FALSE; 98} 99 100//プロセスIDに対するexe名を取得する 101BOOL GetProcessIdByName(DWORD dwProcessID, CString& exeName) 102{ 103 auto entry = PROCESSENTRY32{ sizeof(PROCESSENTRY32) }; 104 105 auto hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 106 107 if (Process32First(hSnapshot, &entry)) { 108 do { 109 if (dwProcessID == entry.th32ProcessID) { 110 exeName = entry.szExeFile; 111 CloseHandle(hSnapshot); 112 return TRUE; 113 } 114 } while (Process32Next(hSnapshot, &entry)); 115 } 116 117 CloseHandle(hSnapshot); 118 return FALSE; 119} 120 121//他のプログラムのウインドウハンドルを取得する 122BOOL CALLBACK EnumWndProc(HWND hWnd, LPARAM lParam) 123{ 124 stProcessSearch* pProcessSearch = (stProcessSearch*)lParam; 125 stApplication_info* pApplication_info = pProcessSearch->m_pApplication_info; 126 CWnd* pWnd = CWnd::FromHandle(hWnd); 127 // ウィンドウとプロセスIDを比較 128 DWORD dwProcessID; 129 ::GetWindowThreadProcessId(hWnd, &dwProcessID); 130 for (int i = 0; i < pProcessSearch->m_nProcessCount; i++) { 131 if (dwProcessID == pProcessSearch->m_dwProcessIDs[i]) { 132 //ウインドウタイトル取得 133 CString strTitle; 134 pWnd->GetWindowText(strTitle); 135 if (!strTitle.IsEmpty() && GetWindowLong(hWnd, GWL_HWNDPARENT) == 0 && pWnd->IsWindowVisible()) { 136 // プロセス名を取得 137 CString strProcName; 138 GetProcessIdByName(dwProcessID, strProcName); 139 if (strProcName.Compare(pApplication_info->m_strApplicationName) == 0) 140 { 141 pApplication_info->m_dwProcessID = dwProcessID; 142 pApplication_info->m_strWindowName = strTitle; 143 pApplication_info->m_pWnd = pWnd; 144 } 145 } 146 break; 147 } 148 } 149 return TRUE; 150} 151 152//リストビュー選択メッセージ 153BOOL ListViewSelect(stApplication_info& application_info, LPCTSTR pszChildWindowTitle, int iControlID, LPCTSTR pszText, int nSelect, BOOL bLeftClick) 154{ 155 CWnd* pWnd = NULL; 156 if ((pWnd = ControlSerach(application_info, pszChildWindowTitle, NULL, L"SysListView32", iControlID)) == NULL) { 157 return FALSE; 158 } 159 CListCtrl ListCtrl; 160 ListCtrl.Attach(pWnd->m_hWnd); 161 162 if (wcslen(pszText) > 0) { 163 TCHAR szText[256] = { 0 }; 164 // テキストを取得する 165 CVirtualMemory vm(application_info.m_pWnd); 166 LVITEM *pLvItem_vm = (LVITEM*)vm.VirtualAlloc(sizeof(LVITEM)); 167 LPTSTR pText_vm = (LPTSTR)vm.VirtualAlloc(sizeof(szText)); 168 169 LVITEM LvItem = { 0 }; 170 LvItem.mask = LVIF_TEXT; 171 LvItem.iSubItem = 0; 172 LvItem.pszText = pText_vm; 173 LvItem.cchTextMax = sizeof(szText) / sizeof(TCHAR); 174 175 for (int i = 0; i < ListCtrl.GetItemCount(); i++) { 176 LvItem.iItem = i; 177 178 vm.Write(pLvItem_vm, &LvItem, sizeof(LVITEM)); 179 180 BOOL bRes = (BOOL)ListCtrl.SendMessage(LVM_GETITEM, nSelect, (LPARAM)pLvItem_vm); 181 182 if (bRes == TRUE) { 183 vm.Read(pText_vm, szText, sizeof(szText)); 184 if (wcscmp(szText, pszText) == 0) { 185 nSelect = i; 186 break; 187 } 188 } 189 } 190 } 191 if (nSelect < 0 || nSelect >= ListCtrl.GetItemCount()) { 192 ListCtrl.Detach(); 193 return FALSE; 194 } 195 196 // 矩形を取得する 197 RECT rect; 198 CVirtualMemory vm(application_info.m_pWnd); 199 LVITEMINDEX *plvItemIndex_vm = (LVITEMINDEX*)vm.VirtualAlloc(sizeof(LVITEMINDEX)); 200 LPTSTR pRect_vm = (LPTSTR)vm.VirtualAlloc(sizeof(rect)); 201 202 LVITEMINDEX lvItemIndex = { 0 }; 203 lvItemIndex.iGroup = 0; 204 lvItemIndex.iItem = nSelect; 205 206 vm.Write(plvItemIndex_vm, &lvItemIndex, sizeof(LVITEMINDEX)); 207 208 BOOL bRes = (BOOL)ListCtrl.SendMessage(LVM_GETITEMINDEXRECT, (WPARAM)plvItemIndex_vm, (LPARAM)pRect_vm); 209 210 if (bRes == TRUE) { 211 vm.Read(plvItemIndex_vm, &lvItemIndex, sizeof(LVITEMINDEX)); 212 vm.Read(pRect_vm, &rect, sizeof(RECT)); 213 214 application_info.m_pWnd->SetForegroundWindow(); 215 216 if (bLeftClick) { 217 ListCtrl.PostMessage(WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(rect.left, rect.top)); 218 } 219 else { 220 ListCtrl.PostMessage(WM_RBUTTONDOWN, MK_RBUTTON, MAKELPARAM(rect.left, rect.top)); 221 } 222 } 223 224 ListCtrl.Detach(); 225 return TRUE; 226} 227//コントロールの検索 228CWnd* ControlSerach(stApplication_info& application_info, LPCTSTR pszChildWindowTitle, LPCTSTR pszTitle, LPCTSTR pszClassName, int iControlID) 229{ 230 stChildWindow ChildWindow; 231 ChildWindow.m_pWnd = NULL; 232 ChildWindow.m_strClassName = pszClassName; 233 ChildWindow.m_strTitleName = pszTitle; 234 ChildWindow.m_iControlID = iControlID; 235 CWnd* pWnd = application_info.m_pWnd; 236 if (pszChildWindowTitle != NULL && wcslen(pszChildWindowTitle) != 0) { 237 CWnd* pFind = application_info.m_pWnd->FindWindow(NULL, pszChildWindowTitle); 238 if (pFind) { 239 pWnd = pFind; 240 } 241 } 242 EnumChildWindows(pWnd->m_hWnd, EnumChildProc, (LPARAM)&ChildWindow); 243 return ChildWindow.m_pWnd; 244} 245 246//子ウィンドウのウインドウハンドルを取得する 247BOOL CALLBACK EnumChildProc(HWND hWnd, LPARAM lParam) 248{ 249 stChildWindow* pChildWindow = (stChildWindow*)lParam; 250 CWnd* pWnd = CWnd::FromHandle(hWnd); 251 252 CString strTitle; 253 pWnd->GetWindowText(strTitle); 254 int iCtrlID = pWnd->GetDlgCtrlID(); 255 TCHAR szClassName[1024]; 256 GetClassName(hWnd, szClassName, sizeof(szClassName)); 257 258 if (!pChildWindow->m_strTitleName.IsEmpty()) { 259 if (pChildWindow->m_iControlID != 0) { 260 if (!pChildWindow->m_strClassName.IsEmpty()) { 261 if (pChildWindow->m_strTitleName.Compare(strTitle) == 0 && 262 pChildWindow->m_iControlID == iCtrlID && 263 pChildWindow->m_strClassName.Compare(szClassName) == 0) { 264 pChildWindow->m_pWnd = pWnd; 265 return FALSE; 266 } 267 } 268 else { 269 if (pChildWindow->m_strTitleName.Compare(strTitle) == 0 && 270 pChildWindow->m_iControlID == iCtrlID) { 271 pChildWindow->m_pWnd = pWnd; 272 return FALSE; 273 } 274 } 275 } 276 else if (!pChildWindow->m_strClassName.IsEmpty()) { 277 if (pChildWindow->m_strTitleName.Compare(strTitle) == 0 && 278 pChildWindow->m_strClassName.Compare(szClassName) == 0) { 279 pChildWindow->m_pWnd = pWnd; 280 return FALSE; 281 } 282 } 283 else { 284 if (pChildWindow->m_strTitleName.Compare(strTitle) == 0) { 285 pChildWindow->m_pWnd = pWnd; 286 return FALSE; 287 } 288 } 289 } 290 else { 291 if (pChildWindow->m_iControlID != 0) { 292 if (!pChildWindow->m_strClassName.IsEmpty()) { 293 if (pChildWindow->m_iControlID == iCtrlID && 294 pChildWindow->m_strClassName.Compare(szClassName) == 0) { 295 pChildWindow->m_pWnd = pWnd; 296 return FALSE; 297 } 298 } 299 else { 300 if (pChildWindow->m_iControlID == iCtrlID) { 301 pChildWindow->m_pWnd = pWnd; 302 return FALSE; 303 } 304 } 305 } 306 else if (!pChildWindow->m_strClassName.IsEmpty()) { 307 if (pChildWindow->m_strClassName.Compare(szClassName) == 0) { 308 pChildWindow->m_pWnd = pWnd; 309 return FALSE; 310 } 311 } 312 } 313 return TRUE; 314}

VC++

1#pragma once 2 3//アプリケーション情報の構造体 4struct stApplication_info 5{ 6 CString m_strApplicationName; //exe 7 DWORD m_dwProcessID; 8 CString m_strWindowName; 9 CWnd* m_pWnd; 10}; 11 12//アプリケーション情報の取得 13BOOL GetApplicationInfo(stApplication_info& application_info); 14//リストビュー選択メッセージ 15BOOL ListViewSelect(stApplication_info& application_info, LPCTSTR pszChildWindowTitle, int iControlID, LPCTSTR pszTitle, int nSelect, BOOL bLeftClick);

試したこと

Windows7では取得できたのですが、Windows10では取得できません。

補足情報(FW/ツールのバージョンなど)

VS2017で作成しました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2019/12/03 00:28

相手が UWP なのでは?
m_ichikawa

2019/12/03 00:41

いいえ、普通のフォームアプリケーションです。
m_ichikawa

2019/12/03 00:43

64bit、32bitアプリケーションが影響しますか?
dodox86

2019/12/03 00:59

他プロセスのメモリを取得するようなものなので、Windows 7ではOKであったが、Win.8、8.1、10、Win10の各種アップデートで使えなくなるケースはよくありますね。
m_ichikawa

2019/12/03 07:03

そうなんです。 でもその機能は必要なので是非教えていただきたいです。 よろしくお願いいたします。
guest

回答1

0

ベストアンサー

Windows 7 で動作しているのであれば、手法は間違っていないと思います。ビット数の異なるプロセスを対象にする場合、該当プロセスのビット数に合わせた構造体定義を使用する必要があります。

32 ビットコンパイルしているなら 64 ビットの定義をプログラム内に独自に定義してください。また、構造体の種類によってはヘッダファイル内に 32 ビットと 64 ビットで異なる定義を持っているものもありますので、ヘッダファイルを確認してみると良いと思います。

以下は VBA ですが似たような話が過去にありました。
https://teratail.com/questions/120773#reply-184106

投稿2019/12/07 08:45

atata0319

総合スコア881

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m_ichikawa

2019/12/10 12:34

テキストを格納するポインタが32bitと64bitでは異なっていたため、受け取ることができませんでした。 32bitアプリケーションを操作するのでしたら32bit用の構造体、64bitアプリケーションを操作するのでしたら64bit用の構造体として使い分けが必要でした。
m_ichikawa

2019/12/10 12:34

ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問