Closed zSynctic closed 7 months ago
Hmm. I'm not able to reproduce this issue with a window that exists. Note that when using AutoHotkey v2, the window must exist, or an error will be thrown. This is different from the AutoHotkey v1 behavior where it will instead return None
.
The error message was: Target window not found.. Specifically: ahk_pid 1956
It seems like the PID you're using is not a window that exists. Can you confirm the window exists with this PID?
for win in ahk.list_windows():
print(win.title, win.pid) # does your PID show up here?
But you can see, generally, that this does work (assuming you have notepad.exe
) by running this code:
import subprocess, time
from ahk import AHK, Window
ahk = AHK(version='v2')
notepad = subprocess.Popen('notepad.exe')
time.sleep(1)
win = Window.from_pid(ahk, notepad.pid)
print(win.title) # 'Untitled - Notepad'
The window actually exists, my code opens a list of all the programs running with their pids and when u click on one of them it takes the pid and uses it in from_pid but it always doesn't work for some reason
Can you share minimal example code that can reproduce the issue?
def select_process(self):
# Get the selected process from the Listbox
self.selected_index = self.process_listbox.curselection()
if self.selected_index:
self.selected_pid = self.get_running_processes()[self.selected_index][1]
print(f"Selected PID: {self.selected_pid}")
self.win = ahk.Window.from_pid(self.ahk, pid=self.selected_pid)
if self.win is not None:
self.getmousepos = threading.Thread(target=self.mousepos)
self.getmousepos.start()
else:
print("No window found for the selected PID")
else:
print("No process selected")
def mousepos(self):
self.win.click(100, 138)
Sorry, but I'm not able to run this code and it's still unclear how you're getting the process IDs of windows.
I don't think this is a problem with the library, but about how you are obtaining your PIDs or other assumptions being made around that. But without a minimal piece of code I can actually run and instructions to reproduce the issue, I can't help any further.
Ok I will send the full code:
from ahk import AHK
import ahk
import customtkinter
from customtkinter import END
import threading
import psutil
from CTkListbox import *
class App(customtkinter.CTk):
def __init__(self):
super().__init__()
self.ahk = AHK()
self.process_listbox = CTkListbox(self, height=30, width=200)
self.process_listbox.grid(row=0, column=0, padx=10, pady=10)
self.update_process_list()
self.select_button = customtkinter.CTkButton(
self, text="Select", command=self.select_process
)
self.select_button.grid(row=1, column=0, pady=10)
def get_running_processes(self):
# Get a list of currently running processes
running_processes = []
for process in psutil.process_iter(["pid", "name"]):
pid_name = f"{process.info['pid']} {process.info['name']}"
running_processes.append((pid_name, process.info["pid"]))
return running_processes
def update_process_list(self):
# Update the list of running processes in the Listbox
running_processes = self.get_running_processes()
self.process_listbox.delete(0, END)
for pid_name, _ in running_processes:
self.process_listbox.insert(END, pid_name)
def select_process(self):
# Get the selected process from the Listbox
self.selected_index = self.process_listbox.curselection()
if self.selected_index:
self.selected_pid = self.get_running_processes()[self.selected_index][1]
print(f"Selected PID: {self.selected_pid}")
self.win = ahk.Window.from_pid(self.ahk, pid=self.selected_pid)
if self.win is not None:
self.getmousepos = threading.Thread(target=self.mousepos)
self.getmousepos.start()
else:
print("No window found for the selected PID")
else:
print("No process selected")
def mousepos(self):
self.win.click(100, 138)
def start(self):
self.mainloop()
if __name__ == "__main__":
app = App()
app.update()
app.start()
So, something to keep in mind is that not every PID, as returned by psutil.process_iter
will be associated with a window that can be retrieved. Many processes have no windows or their window may be hidden. Also keep in mind you're calling get_running_processes
twice, which means the list you're presenting to the user won't necessarily be the same list you're using when you pull the pid out in select_process
.
I would consider replacing psutil
with the AutoHotkey functionality of enumerating windows using ahk.list_windows
and retrieving the id and process name from the window objects.
Maybe something like this can replace your get_running_processes
method:
def get_available_windows(self):
available_windows = []
for win in self.ahk.list_windows():
selection_name = f'{win.id} {win.process_name} ({win.pid})'
available_windows.append((selection_name, win))
return available_windows
Then you can directly pull out the Window
object instead, too, and skip the step of creating the Window object from the pid.
I would also think about structuring this so you are not calling this function twice so that the list in which the user is making the selection and the list you're using to obtain the object based on their selection is guaranteed to be the same.
I'm trying to click while the windows is minimized so Idk why its not working here is my code after replacing it with get_running_processes
:
from ahk import AHK
import ahk
import customtkinter
from customtkinter import END
import threading
import psutil
from CTkListbox import *
class App(customtkinter.CTk):
def __init__(self):
super().__init__()
self.ahk = AHK()
self.process_listbox = CTkListbox(self, height=30, width=200)
self.process_listbox.grid(row=0, column=0, padx=10, pady=10)
self.update_process_list()
self.select_button = customtkinter.CTkButton(
self, text="Select", command=self.select_process
)
self.select_button.grid(row=1, column=0, pady=10)
def get_available_windows(self):
available_windows = []
for win in self.ahk.list_windows():
selection_name = f"{win.id} {win.process_name} ({win.pid})"
available_windows.append((selection_name, win))
return available_windows
def update_process_list(self):
# Update the list of running processes in the Listbox
running_processes = self.get_available_windows()
self.process_listbox.delete(0, END)
for pid_name, _ in running_processes:
self.process_listbox.insert(END, pid_name)
def select_process(self):
# Get the selected process from the Listbox
self.selected_index = self.process_listbox.curselection()
if self.selected_index:
self.selected_pid = self.get_available_windows()[self.selected_index][1]
print(f"Selected PID: {self.selected_pid}")
self.win = ahk.Window.from_pid(self.ahk, pid=self.selected_pid)
if self.win is not None:
self.getmousepos = threading.Thread(target=self.mousepos)
self.getmousepos.start()
else:
print("No window found for the selected PID")
else:
print("No process selected")
def mousepos(self):
self.win.click(100, 138)
def start(self):
self.mainloop()
if __name__ == "__main__":
app = App()
app.update()
app.start()
Here's what I believe to be the fixed version of your code:
from ahk import AHK
import ahk
import customtkinter
from customtkinter import END
import threading
from CTkListbox import *
class App(customtkinter.CTk):
def __init__(self):
super().__init__()
self.ahk = AHK()
self.process_listbox = CTkListbox(self, height=30, width=200)
self.process_listbox.grid(row=0, column=0, padx=10, pady=10)
self._available_windows = []
self.update_process_list()
self.select_button = customtkinter.CTkButton(
self, text="Select", command=self.select_process
)
self.select_button.grid(row=1, column=0, pady=10)
def get_available_windows(self):
available_windows = []
for win in self.ahk.list_windows():
selection_name = f"{win.id} {win.process_name} ({win.pid})"
available_windows.append((selection_name, win))
return available_windows
def update_process_list(self):
# Update the list of running processes in the Listbox
available_windows = self.get_available_windows()
self.process_listbox.delete(0, END)
for selection_name, _ in available_windows:
self.process_listbox.insert(END, selection_name)
self._available_windows = available_windows
return available_windows
def select_process(self):
# Get the selected process from the Listbox
self.selected_index = self.process_listbox.curselection()
if self.selected_index:
self.win = self._available_windows[self.selected_index][1]
if self.win.exists():
print('Selected window process is', self.win.get_process_name())
self.getmousepos = threading.Thread(target=self.mousepos)
self.getmousepos.start()
else:
print(f"selected window {self.win.id} no longer exists")
else:
print("No process selected")
def mousepos(self):
print('mousepos running')
self.win.click(100, 138)
def start(self):
self.mainloop()
if __name__ == "__main__":
app = App()
app.update()
app.start()
Keep in mind, some programs may not accept input while minimized. But I can confirm this works with notepad.exe
on my system.
Thanks this worked
describe your issue
What I did was that I put a running window's pid and try to use it in from_pid but somehow it always doesn't work even though I already verified that the pid is running and I tried switching it but still
ahk.version
1.5.2
AutoHotkey version
v2
Code to reproduce the issue
Traceback/Error message
Exception in Tkinter callback Traceback (most recent call last): File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.2288.0_x64__qbz5n2kfra8p0\Lib\tkinterinit.py", line 1967, in call return self.func(args) ^^^^^^^^^^^^^^^^ File "C:\Users...\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\customtkinter\windows\widgets\ctk_button.py", line 554, in _clicked self._command() File "D:\Python Programming\Projects\AutoClicker\ZClicker\test.py", line 47, in select_process self.win = ahk.Window.from_pid(self.ahk, pid=self.selected_pid) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users...\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\ahk_sync\window.py", line 627, in from_pid return engine.win_get(title=f'ahk_pid {pid}') ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users...\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\ahk_sync\engine.py", line 1709, in win_get resp = self._transport.function_call('AHKWinGetID', args, blocking=blocking, engine=self) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users...\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\ahk_sync\transport.py", line 611, in function_call return self.send(request, engine=engine) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users...\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\ahk_sync\transport.py", line 832, in send return response.unpack() # type: ignore ^^^^^^^^^^^^^^^^^ File "C:\Users...\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\ahk\message.py", line 221, in unpack raise self._exception_type(s) ahk.message.AHKExecutionException: Error occurred in WinGetID (line 530). The error message was: Target window not found.. Specifically: ahk_pid 1956 Stack: C:\Users...\AppData\Local\Temp\python-ahk-cf5lqn_k.ahk (530) : [WinGetID] output := WinGetID(title, text, extitle, extext) C:\Users...\AppData\Local\Temp\python-ahk-cf5lqn_k.ahk (530) : [AHKWinGetID] output := WinGetID(title, text, extitle, extext) C:\Users...\AppData\Local\Temp\python-ahk-cf5lqn_k.ahk (2735) : [] pyresp := %func_name%(argsArray)