主要な手順#
CreateToolhelp32Snapshot
を使用してプロセスを走査し、プロセス ID を取得します。
コード#
private fun getProcessID(processName: String): UInt{
memScoped {
val snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS.toUInt(),0U)
val processEntry = alloc<PROCESSENTRY32W>()
processEntry.dwSize = sizeOf<PROCESSENTRY32W>().convert()
if(Process32FirstW(snapshot,processEntry.ptr) != 0){
do {
val name = processEntry.szExeFile.toKString()
if(processName == name){
CloseHandle(snapshot)
return processEntry.th32ProcessID
}
}while (Process32NextW(snapshot,processEntry.ptr) != 0)
}
CloseHandle(snapshot)
return 0U
}
}
遭遇した問題#
1. CreateToolhelp32Snapshot
メソッドが存在しない#
原因:#
tlhelp32.h
ヘッダーファイルがデフォルトでインポートされていないため
解決策:#
nativeInterop/cinterop
ディレクトリを作成し、windows.def
を配置します:
package = platform.windows
headers = wtypes.h minwindef.h windows.h commctrl.h dwmapi.h shlobj.h shlwapi.h shobjidl.h \
urlmon.h usp10.h uxtheme.h vfw.h wininet.h winsock2.h ws2tcpip.h ws2def.h windows.h tlhelp32.h
compilerOpts = -DUNICODE -DWINVER=0x0601 -D_WIN32_WINNT=0x0601 -DWINAPI_FAMILY=3 -DOEMRESOURCE \
-Wno-incompatible-pointer-types -Wno-deprecated-declarations
linkerOpts = -lcomctl32 -lcrypt32 -lshlwapi -lshell32 -limm32 -lusp10 -lwininet -lgdi32 -luser32 -lkernel32 -lbcrypt -luuid -ldwmapi
noStringConversion = LoadCursorA LoadBitmapA LoadIconA LoadImageA LoadCursorW LoadBitmapW LoadIconW LoadImageW
depends = posix
ディレクトリ構造:
windows.def
のソース:#
windows.def このファイルのheaders
の後に windows.h tlhelp32.h
を追加します
-
build.gradle.kts
に以下を追加します:compilations.getByName("main"){ cinterops{ val windows by creating } }
:::
2. プロセスが取得できない#
以前は Process32First
とProcess32Next
メソッドを使用して CreateToolhelp32Snapshot
を処理していましたが、Process32First
の結果が 0 になり、通常は 0 になるべきではありません。その後、私は YouTrack でIssueを報告しました。
解決策は次のとおりです:
-
PROCESSENTRY32 -> PROCESSENTRY32W
-
Process32First -> Process32FirstW
-
Process32Next -> Process32NextW
この問題の解決に協力してくれたスタッフの皆様に感謝します。
参考記事#
Create an app using C Interop and libcurl
[Kotlin/Native] Unable to get process via CreateToolhelp32Snapshot