教えて!ExcelVBA!

ExcelVBAの基礎知識・書き方について紹介します。

【ExcelVBA API操作】起動したアプリケーションのプロセスハンドルを取得(OpenProcess)及び解放(CloseHandle)する方法を教えて!

API宣言

ExcelVBAでは、WindowsAPIを使用して外部の機能を呼び出すことができます。プロセスハンドルを取得・解放するために、以下の2つのAPI関数を宣言します。

API関数 内容
OpenProcess 外部プロセスのハンドルを取得する
CloseHandle 取得したプロセスハンドルを解放する
OpenProcess関数

OpenProcess関数を使用する前にAPI宣言を行う必要があります。API宣言を行うことで、ExcelVBAがWindowsAPI関数を認識することができるようになります。API宣言は次のように行います。

Private Declare Function OpenProcess Lib "kernel32" ( _
    ByVal dwDesiredAccess As Long, _
    ByVal bInheritHandle As Long, _
    ByVal dwProcessId As Long) As Long

Private Const PROCESS_QUERY_INFORMATION = &H400
Private Const PROCESS_VM_READ = &H10

解説

パラメータ 内容
Lib 使用する動的リンクライブラリ(DLL)の名前を指定します。ここでは "kernel32.dll"となります。

引数については以下の通りです。

引数 内容
dwDesiredAccess 取得したいプロセスへのアクセス権を指定します。具体的なアクセス権を以下で紹介します。
bInheritHandle ハンドルを子プロセスに継承するかどうかを指定します。0以外の場合(True)は継承され、0の場合(False)は継承されません。
dwProcessId 対象のプロセスのプロセスID(識別子)を指定します。

アクセス権は以下の通りです。

定数 内容
PROCESS_ALL_ACCESS プロセスに対するすべてのアクセス権を指定します。
PROCESS_CREATE_PROCESS プロセスを作成できる権限を指定します。
PROCESS_QUERY_INFORMATION プロセス情報を問い合わせる権限を指定します。
PROCESS_TERMINATE プロセスを終了できる権限を指定します。
CloseHandle関数

CloseHandle関数を使用する前にAPI宣言を行う必要があります。API宣言を行うことで、ExcelVBAがWindowsAPI関数を認識することができるようになります。API宣言は次のように行います。

Private Declare Function CloseHandle Lib "kernel32" ( _
    ByVal hObject As Long) As Long

解説

パラメータ 内容
Lib 使用する動的リンクライブラリ(DLL)の名前を指定します。ここでは "kernel32.dll"となります。

引数については以下の通りです。

引数 内容
hObject 閉じる対象のハンドルを指定します。

使い方

OpenProcess関数とCloseHandle関数を使って、外部プロセスのプロセスハンドルを取得・解放します。最初に、両関数のAPI宣言を行います。

OpenProcess関数:
Private Declare Function OpenProcess Lib "kernel32" ( _
    ByVal dwDesiredAccess As Long, _
    ByVal bInheritHandle As Long, _
    ByVal dwProcessId As Long) As Long
Private Const PROCESS_QUERY_INFORMATION = &H400
Private Const PROCESS_VM_READ = &H10

CloseHandle関数:
Private Declare Function CloseHandle Lib "kernel32" ( _
    ByVal hObject As Long) As Long

プログラミング例

以下に、プログラミング例を紹介します。

Sub GetProcessHandleAndWindowTitle()
    Dim hWndNotepad As Long
    Dim hProcess As Long
    Dim pid As Long
    Dim buffer As String * 256
    ' メモ帳アプリケーションを起動
    Shell "notepad.exe", vbNormalFocus
    ' メモ帳のウィンドウハンドルを取得
    hWndNotepad = FindWindow("Notepad", vbNullString)
    ' メモ帳のプロセスIDを取得
    GetWindowThreadProcessId hWndNotepad, pid
    ' プロセスハンドルを取得
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, False, pid)
    ' タイトルバーのキャプションを取得して表示
    GetWindowText hProcess, buffer, 256
    MsgBox "メモ帳のタイトル: " & buffer
    ' プロセスハンドルを解放
    CloseHandle hProcess
End Sub

上記の例では、メモ帳アプリケーションを起動し、そのプロセスハンドルを取得し、タイトルバーのキャプションを取得しています。

まとめ

WindowsAPIのOpenProcess関数とCloseHandle関数を使うことで、外部プロセスとの連携が可能になります。特に、他のアプリケーションとデータをやり取りする場合に重要な技術です。この方法を活用することで、より高度なVBAプログラムを作成することができる様になります。是非活用してください。