11module fpx_process_windows
15 implicit none;
private
17 public :: get_process_name_windows, &
18 get_parent_pid_windows
20 integer(c_int32_t),
parameter :: TH32CS_SNAPPROCESS = int(z
'00000002', c_int32_t)
21 integer(c_intptr_t),
parameter :: INVALID_HANDLE = -1_c_intptr_t
22 integer,
parameter :: MAX_PATH = 260
24 type,
bind(C) :: PROCESSENTRY32W
25 integer(c_int32_t) :: dwSize
26 integer(c_int32_t) :: cntUsage
27 integer(c_int32_t) :: th32ProcessID
28 integer(c_intptr_t) :: th32DefaultHeapID
29 integer(c_int32_t) :: th32ModuleID
30 integer(c_int32_t) :: cntThreads
31 integer(c_int32_t) :: th32ParentProcessID
32 integer(c_int32_t) :: pcPriClassBase
33 integer(c_int32_t) :: dwFlags
34 integer(c_int16_t) :: szExeFile(MAX_PATH)
38 function getcurrentprocessid() bind(C, name='GetCurrentProcessId')
40 integer(c_int32_t) :: GetCurrentProcessId
43 function createtoolhelp32snapshot(flags, pid) bind(C, name='CreateToolhelp32Snapshot')
45 integer(c_int32_t),
value :: flags
46 integer(c_int32_t),
value :: pid
47 integer(c_intptr_t) :: CreateToolhelp32Snapshot
50 function process32firstw(hSnap, pe) bind(C, name='Process32FirstW')
52 integer(c_intptr_t),
value :: hSnap
53 type(PROCESSENTRY32W) :: pe
54 integer(c_int) :: Process32FirstW
57 function process32nextw(hSnap, pe) bind(C, name='Process32NextW')
59 integer(c_intptr_t),
value :: hSnap
60 type(PROCESSENTRY32W) :: pe
61 integer(c_int32_t) :: Process32NextW
64 function closehandle(h) bind(C, name='CloseHandle')
66 integer(c_intptr_t),
value :: h
67 integer(c_int32_t) :: CloseHandle
73 function utf16_to_string(w)
result(str)
74 integer(c_int16_t),
intent(in) :: w(:)
75 character(:),
allocatable :: str
85 allocate(
character(n) :: str)
88 str(i:i) = achar(int(w(i)))
92 pure function strip_exe(name)
result(out)
93 character(*),
intent(in) :: name
94 character(:),
allocatable :: out
96 if (len(name) > 4)
then
97 if (name(len(name)-3:) ==
'.exe')
then
98 out = name(:len(name)-4)
106 integer(c_int32_t) function current_pid()
result(pid)
107 pid = getcurrentprocessid()
110 integer(c_int32_t) function get_parent_pid_windows()
result(ppid)
112 type(PROCESSENTRY32W),
target :: pe
113 integer(c_intptr_t) :: snap
114 integer(c_int32_t) :: ios, pid
119 snap = createtoolhelp32snapshot(th32cs_snapprocess, 0)
121 if (snap == invalid_handle)
return
123 pe%dwSize = c_sizeof(pe)
125 if (process32firstw(snap, pe) /= 0)
then
128 if (pe%th32ProcessID == pid)
then
129 ppid = pe%th32ParentProcessID
133 if (process32nextw(snap, pe) == 0)
exit
138 ios = closehandle(snap)
141 function get_process_name_windows(pid)
result(name)
142 integer(c_int32_t),
intent(in) :: pid
143 character(:),
allocatable :: name
145 type(PROCESSENTRY32W),
target :: pe
146 integer(c_intptr_t) :: snap
147 integer(c_int32_t) :: ios
151 snap = createtoolhelp32snapshot(th32cs_snapprocess, 0_c_int32_t)
152 if (snap == invalid_handle)
return
154 pe%dwSize = c_sizeof(pe)
156 if (process32firstw(snap, pe) /= 0)
then
159 if (pe%th32ProcessID == pid)
then
160 name = utf16_to_string(pe%szExeFile)
164 if (process32nextw(snap, pe) == 0)
exit
169 ios = closehandle(snap)
171 name = strip_exe(name)