- PR -

タスクバーのタスクボタンの情報を取得したい

投稿者投稿内容
uni
会議室デビュー日: 2005/09/30
投稿数: 11
投稿日時: 2005-10-07 10:12
はじめまして。uniと申します。
Windows2000+VB.NET2003でWindowsアプリケーションを作成しています。

タスクバーのボタンの情報を取得しようと思い、
http://techtips.belution.com/ja/vc/0001/
http://www.bcap.co.jp/hanafusa/vbbbs/wforum.cgi?mode=allread&pastlog=0001&no=2449&page=0&act=past#2466
を参考にして下記のようなコードを書いてみたのですが、
ReadProcessMemoryの戻値が0となり失敗します。

そこで、ReadProcessMemoryとWriteProcessMemoryの引数はポインタとなっているので、
pSysShared、pLocalSharedのアドレスを渡そうと思い、
GCHandle.Allocで取得した値を渡してみたのですが、
"メモリがReadになることはできませんでした。"のエラーが出ます。
ボタン数などは正しく取得できるのですが・・・
どうしたら情報を取得できるでしょうか?
よろしくお願いします。


コード:

Const TCM_FIRST As Integer = &H1300
Const TCM_GETITEMCOUNT As Integer = TCM_FIRST + 4
Const TCM_GETITEM As Integer = TCM_FIRST + 5
Const TCIF_TEXT As Integer = &H1

'ボタン(タブ)の数取得
Dim iTabCnt As Integer = SendMessage(hSysTab, TCM_GETITEMCOUNT, 0, 0)
If iTabCnt = 0 Then
Return
End If

Dim tItem As tagTCITEM
Dim bytGetText(255) As Byte '文字列情報を取得する領域
Dim pLocalShared As Integer 'ファイルがマップされた自プロセスのビューの開始アドレス
Dim pSysShared As Integer 'ファイルがマップされたほかのプロセスのビューの開始アドレス
Dim hProcess As Integer 'プロセスハンドル
Dim processID As Integer 'プロセスID
Dim threadID As Integer 'スレッドID
Dim dwNumberOfBytes As Integer '読み書きされたバイト数
Dim dwSize As Integer = System.Runtime.InteropServices.Marshal.SizeOf(tItem)

'自プロセスのメモリ領域確保
pLocalShared = VirtualAlloc(0, dwSize, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)

If pLocalShared > 0 Then
'プロセスID取得
threadID = GetWindowThreadProcessId(hSysTab, processID)

'プロセスハンドル取得
hProcess = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, 0, processID)

If hProcess > 0 Then

'他のプロセスのメモリ領域確保
pSysShared = VirtualAllocEx(hProcess, 0, dwSize + bytGetText.Length, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)

If pSysShared > 0 Then

With tItem
.mask = TCIF_TEXT
.pszText = pSysShared + dwSize
.cchTextMax = bytGetText.Length
End With

'データを書き込む
WriteProcessMemory(hProcess, pSysShared, pLocalShared, dwSize + bytGetText.Length, dwNumberOfBytes)
'タブの情報取得
SendMessage(hSysTab, TCM_GETITEM, 0, pSysShared)
'データを読み込む
ReadProcessMemory(hProcess, pSysShared, pLocalShared, dwSize + bytGetText.Length, dwNumberOfBytes)

'他のプロセスのメモリ領域解放
VirtualFreeEx(hProcess, pSysShared, 0, MEM_RELEASE)

End If
'プロセスハンドル閉じる
CloseHandle(hProcess)

End If
'自プロセスのメモリ領域解放
VirtualFree(pLocalShared, 0, MEM_RELEASE)

End If



[ メッセージ編集済み 編集者: uni 編集日時 2005-10-07 10:14 ]

[ メッセージ編集済み 編集者: uni 編集日時 2005-10-07 10:16 ]
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-10-07 10:30
DllImport の部分も提示して頂けませんか?

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
uni
会議室デビュー日: 2005/09/30
投稿数: 11
投稿日時: 2005-10-07 10:49
> じゃんぬねっと さん

お返事ありがとうございます。
以下のコードを、別のモジュールに書いています。
(長くなってすいません)

コード:

Public Const MEM_COMMIT As Integer = &H1000
Public Const MEM_RESERVE As Integer = &H2000
Public Const MEM_RELEASE As Integer = &H8000
Public Const PROCESS_VM_OPERATION As Integer = &H8
Public Const PROCESS_VM_READ As Integer = &H10
Public Const PROCESS_VM_WRITE As Integer = &H20
Public Const PAGE_READWRITE As Integer = &H4

'+ 呼び出し側プロセスの仮想アドレス空間内のページ領域を予約またはコミットする
Public Declare Function VirtualAlloc Lib "kernel32.dll" (ByVal lpAddress As Integer, ByVal dwSize As Integer, _
ByVal flAllocationType As Integer, ByVal flProtect As Integer) As Integer

'+ 呼び出し側プロセスの仮想アドレス空間内のページ領域の解放、コミット解除
Public Declare Function VirtualFree Lib "kernel32.dll" (ByVal lpAddress As Integer, ByVal dwSize As Integer, _
ByVal dwFreeType As Integer) As Integer

'+ 仮想アドレス内のメモリ領域の予約とコミットの一方または両方
Public Declare Function VirtualAllocEx Lib "kernel32" (ByVal hProcess As Integer, ByVal lpAddress As Integer, _
ByVal dwSize As Integer, ByVal flAllocationType As Integer, ByVal flProtect As Integer) As Integer

'+ 指定されたプロセスの仮想アドレス空間内のメモリ領域を開放またはコミットを解除
Public Declare Function VirtualFreeEx Lib "kernel32" (ByVal hProcess As Integer, ByVal lpAddress As Integer, _
ByVal dwSize As Integer, ByVal dwFreeType As Integer) As Integer

'+ 指定されたウィンドウを作成したスレッドのIDとプロセスIDを取得
Public Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Integer, ByRef lpdwProcessId As Integer) As Integer

'+ 既存のプロセスオブジェクトのハンドルを開く
Public Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Integer, ByVal bInheritHandle As Integer, _
ByVal dwProcessId As Integer) As Integer

'+ 開いているオブジェクトハンドルを閉じる
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Integer) As Integer

'+ 指定されたプロセスのメモリ領域にデータを書き込む
Public Declare Function WriteProcessMemory Lib "kernel32.dll" (ByVal hProcess As Integer, ByVal lpBaseAddress As Integer, _
ByVal lpBuffer As Integer, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Integer

'+ 指定されたプロセスのメモリ領域からデータを読み取る
Public Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Integer, ByVal lpBaseAddress As Integer, _
ByVal lpBuffer As Object, ByVal nSize As Integer, ByVal lpNumberOfBytesRead As Integer) As Integer

'タブの情報
Public Structure tagTCITEM
Dim mask As Integer
Dim dwState As Integer
Dim dwStateMask As Integer
Dim pszText As Integer
Dim cchTextMax As Integer
Dim iImage As Integer
Dim lParam As Integer
End Structure

'+ メッセージを送信
Public Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" ( _
ByVal hWnd As Integer, ByVal MSG As Integer, ByVal wParam As Integer, ByVal lParam As Object) As Integer



追加:すいませんSendMessageが抜けていました。。。

[ メッセージ編集済み 編集者: uni 編集日時 2005-10-07 10:59 ]
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-10-07 11:15
ん? lpBuffer って Object で良かったでしたっけ?

コード:

'/ Imports System.Runtime.InteropSerivices なされているものする

<DllImport("KERNEL32.DLL", CharSet:=CharSet.Auto)> _
Private Shared Function ReadProcessMemory( _
ByVal hProcess As System.IntPtr, _
ByVal lpBaseAddress As System.IntPtr, _
ByRef lpBuffer As Byte(), _
ByVal nSize As System.UIntPtr, _
ByVal lpNumberOfBytesRead As System.IntPtr) As Boolean
End Function


こんな感じではなかったですか?

[ シグネチャを削除 ]

[ メッセージ編集済み 編集者: じゃんぬねっと 編集日時 2006-09-19 14:44 ]
uni
会議室デビュー日: 2005/09/30
投稿数: 11
投稿日時: 2005-10-07 11:42
じゃんぬねっとさん、ありがとうございます。

私が調べたところでは、Objectと書いていたのでそのまま使ったのですが、
「ReadProcessMemory IntPtr」で検索したらいろいろ出てきました・・・。
ということは他のWriteProcessMemoryなどの引数の型も変ですよね、たぶん。
しかもByRefでなくByValになってるし・・・。

調べなおしてもう一度やってみます。
また後で報告(または質問)に参ります。
ありがとうございました。
未記入
会議室デビュー日: 2005/09/27
投稿数: 4
投稿日時: 2005-10-07 12:15
> タスクバーのボタンの情報

といってもいろいろあると思うんだけど、具体的に何が取得したいのかな?
それによっては別解を提示できるやもしれません。
uni
会議室デビュー日: 2005/09/30
投稿数: 11
投稿日時: 2005-10-07 13:05
引用:

未記入さんの書き込み (2005-10-07 12:15) より:
> タスクバーのボタンの情報

といってもいろいろあると思うんだけど、具体的に何が取得したいのかな?
それによっては別解を提示できるやもしれません。



タスクバーのボタンの順番を並べ替えられるアプリケーションを作成したいのです。
並べ替えが出来るソフトを使っていますが、他に自分が欲しい機能を追加したアプリを
作りたいなーと思いまして。
そのために、まずは表示されているテキストやアイコンを取得したらいいんじゃないかと
思ったのですが。。。
何かいい方法ありますでしょうか??
uni
会議室デビュー日: 2005/09/30
投稿数: 11
投稿日時: 2005-10-07 15:41
いろいろ試行錯誤した結果、ReadProcessMemoryも成功し文字列らしきものを取得できたのですが、
中身が文字化けしていて結果が正しいかどうかわかりません。。。
がんばって変換すれば正しい結果が得られるのでしょうか?
下記にコードを示します。(長くなったので分割しました)

コード:
  Public Const MEM_COMMIT As Integer = &H1000
  Public Const MEM_RESERVE As Integer = &H2000
  Public Const MEM_RELEASE As Integer = &H8000
  Public Const PROCESS_VM_OPERATION As Integer = &H8
  Public Const PROCESS_VM_READ As Integer = &H10
  Public Const PROCESS_VM_WRITE As Integer = &H20
  Public Const PAGE_READWRITE As Integer = &H4

  Public Const TCM_FIRST As Integer = &H1300
  Public Const TCM_GETITEMCOUNT As Integer = TCM_FIRST + 4
  Public Const TCM_GETITEM As Integer = TCM_FIRST + 5
  Public Const TCIF_TEXT As Integer = &H1

  <DllImport("user32.dll")> _
  Public Shared Function FindWindow( _
  ByVal lpClassName As String, _
  ByVal lpWindowName As String) As IntPtr

  End Function

  <DllImport("user32.dll")> _
  Public Shared Function FindWindowEx( _
  ByVal hWndParent As IntPtr, _
  ByVal hWndChildAfter As IntPtr, _
  ByVal lpszClass As String, _
  ByVal lpszWindow As String) As IntPtr

  End Function

  <DllImport("user32.dll")> _
  Public Shared Function SendMessage( _
  ByVal hWnd As IntPtr, _
  ByVal msg As Integer, _
  ByVal wParam As Integer, _
  ByVal lParam As IntPtr) As Boolean

  End Function

  <DllImport("user32.dll")> _
  Public Shared Function SendMessage( _
  ByVal hWnd As IntPtr, _
  ByVal msg As Integer, _
  ByVal wParam As Integer, _
  ByVal lParam As Integer) As Integer

  End Function

  <DllImport("user32.dll")> _
  Public Shared Function GetWindowThreadProcessId( _
  ByVal hWnd As IntPtr, _
  ByRef lpwdProcessId As Integer) As Integer

  End Function

  <DllImport("kernel32.dll")> _
  Public Shared Function OpenProcess( _
  ByVal dwDesiredAddccess As Integer, _
  ByVal bInheritHandle As Boolean, _
  ByVal dwProcessId As Integer) As IntPtr

  End Function

  <DllImport("kernel32.dll")> _
  Public Shared Function VirtualAlloc( _
  ByVal lpAddress As IntPtr, _
  ByVal dwSize As Integer, _
  ByVal fAllocationType As Integer, _
  ByVal flProtect As Integer) As IntPtr

  End Function

  <DllImport("kernel32.dll")> _
  Public Shared Function VirtualFree( _
  ByVal lpAddress As IntPtr, _
  ByVal dwSize As Integer, _
  ByVal dwFreeType As Integer) As Boolean

  End Function

  <DllImport("kernel32.dll")> _
  Public Shared Function VirtualAllocEx( _
  ByVal hProcess As IntPtr, _
  ByVal lpAddress As IntPtr, _
  ByVal dwSize As Integer, _
  ByVal flAllocationType As Integer, _
  ByVal flProtect As Integer) As IntPtr

  End Function

  <DllImport("kernel32.dll")> _
  Public Shared Function VirtualFreeEx( _
  ByVal hProcess As IntPtr, _
  ByVal lpAddress As IntPtr, _
  ByVal dwSize As Integer, _
  ByVal dwFreeType As Integer) As Boolean

  End Function

  <DllImport("kernel32.dll")> _
  Public Shared Function WriteProcessMemory( _
  ByVal hProcess As IntPtr, _
  ByVal lpBaseAddress As IntPtr, _
  ByRef tItem As tagTCITEM, _
  ByVal dwSize As Integer, _
  ByRef lpNumberOfBytesRead As Integer) As Boolean

  End Function

  <DllImport("kernel32.dll")> _
  Public Shared Function ReadProcessMemory( _
  ByVal hProcess As IntPtr, _
  ByVal lpBaseAddress As IntPtr, _
  ByVal lpBuffer As IntPtr, _
  ByVal dwSize As Integer, _
  ByRef lpNumberOfBytesRead As Integer) As Boolean

  End Function

  <DllImport("kernel32.dll")> _
  Public Shared Function CloseHandle( _
  ByVal hObject As IntPtr) As Boolean

  End Function

  Public Structure tagTCITEM
    Public mask As Integer
    Public dwState As Integer
    Public dwStateMask As Integer
    Public pszText As IntPtr
    Public cchTextMax As Integer
    Public iImage As Integer
    Public lParam As IntPtr
  End Structure

スキルアップ/キャリアアップ(JOB@IT)