Python check if current window is file explorer (windows) - python

I am using this code to obtain current window
from typing import Optional
from ctypes import wintypes, windll, create_unicode_buffer
def getForegroundWindowTitle() -> Optional[str]:
hWnd = windll.user32.GetForegroundWindow()
length = windll.user32.GetWindowTextLengthW(hWnd)
buf = create_unicode_buffer(length + 1)
windll.user32.GetWindowTextW(hWnd, buf, length + 1)
return buf.value if buf.value else None
print(getForegroundWindowTitle())
output:
Videos
git
Downloads
Python check if current window is file explorer - Stack Overflow - Google Chrome
While google chrome tabs can be easily identified using this, problem is there's no way to know whether Videos, git, Downloads are windows folder (opened using file explorer).
So, is there a way to get the output in this format Videos - File Explorer ?
/ check whether the current window is a windows folder/file explorer window ?

From the same Question I modified the Code of Nuno Andre
https://stackoverflow.com/a/56572696/2532695
import ctypes
from ctypes import wintypes
import psutil
user32 = ctypes.windll.user32
h_wnd = user32.GetForegroundWindow()
pid = wintypes.DWORD()
user32.GetWindowThreadProcessId(h_wnd, ctypes.byref(pid))
print(psutil.Process(pid.value).name())
This one should do the trick, but you need psutil (pip install psutil).
You should see something like "Explorer.exe" if the active Window is an Explorer-Window.

Related

Check if Windows File Explorer is already opened in python

I have simple script that launches Windows File Explorer
import subprocess
subprocess.call(["start", "explorer.exe"],shell=True)
I'd like to check if Windows File Explorer is already opened so that I don't open another instance. How can I do it? Solutions without external libraries are preferred.
Found the solution
import win32gui
explorerWindows = []
def handler( hwnd, list ):
# only explorer windows have class 'CabinetWClass'
if 'CabinetWClass' in win32gui.GetClassName(hwnd):
list.append(hwnd)
win32gui.EnumWindows(handler, explorerWindows)
explorerOpened = len(explorerWindows) > 0
EDIT: easier method
import win32gui
explorerOpened = win32gui.FindWindow('CabinetWClass', None) != 0

How do I create a link to a file in a specific directory?

I have a python file, which is... supposed to be an app. I found out that if I put a shortcut of it in the
"C:\Users\xxxxxxxxx\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\System Tools"
section, that I would be able to put it in the application list, and the system would detect is as an app.
The python file will be a game kind of thing, and if others install it, it would be better if there was just another python file that creates the shortcut in the destination.
But.
I do not know how to do this with python.
I tried this:
import win32com.client
import getpass
from time import sleep
user = getpass.getuser()
import pythoncom
import os
# pythoncom.CoInitialize() # remove the '#' at the beginning of the line if
running in a thread.
desktop = r'C:/Users/' + user + '/AppData/Roaming/Microsoft/Windows/Start
Menu/Programs/System Tools' # path to where you want to put the .lnk
path = os.path.join(desktop, 'Skulk.lnk')
target = r'C:/Users/' + user + '/main.py'
shell = win32com.client.Dispatch("WScript.Shell")
shortcut = shell.CreateShortCut(path)
shortcut.Targetpath = target
shortcut.WindowStyle = 7 # 7 - Minimized, 3 - Maximized, 1 - Normal
shortcut.save()
print("Success!")
sleep(3)
If it is, could you please tell me how to do it?
Any help would be greatly appreciated.

python - Finding the user's "Downloads" folder

I already found this question that suggests to use os.path.expanduser(path) to get the user's home directory.
I would like to achieve the same with the "Downloads" folder. I know that this is possible in C#, yet I'm new to Python and don't know if this is possible here too, preferable platform-independent (Windows, Ubuntu).
I know that I just could do download_folder = os.path.expanduser("~")+"/Downloads/", yet (at least in Windows) it is possible to change the Default download folder.
from pathlib import Path
downloads_path = str(Path.home() / "Downloads")
This fairly simple solution (expanded from this reddit post) worked for me
import os
def get_download_path():
"""Returns the default downloads path for linux or windows"""
if os.name == 'nt':
import winreg
sub_key = r'SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders'
downloads_guid = '{374DE290-123F-4565-9164-39C4925E467B}'
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, sub_key) as key:
location = winreg.QueryValueEx(key, downloads_guid)[0]
return location
else:
return os.path.join(os.path.expanduser('~'), 'downloads')
The GUID can be obtained from Microsoft's KNOWNFOLDERID docs
This can be expanded to work more generically other directories
For python3+ mac or linux
from pathlib import Path
path_to_download_folder = str(os.path.join(Path.home(), "Downloads"))
Correctly locating Windows folders is somewhat of a chore in Python. According to answers covering Microsoft development technologies, such as this one, they should be obtained using the Vista Known Folder API. This API is not wrapped by the Python standard library (though there is an issue from 2008 requesting it), but one can use the ctypes module to access it anyway.
Adapting the above answer to use the folder id for downloads shown here and combining it with your existing Unix code should result in code that looks like this:
import os
if os.name == 'nt':
import ctypes
from ctypes import windll, wintypes
from uuid import UUID
# ctypes GUID copied from MSDN sample code
class GUID(ctypes.Structure):
_fields_ = [
("Data1", wintypes.DWORD),
("Data2", wintypes.WORD),
("Data3", wintypes.WORD),
("Data4", wintypes.BYTE * 8)
]
def __init__(self, uuidstr):
uuid = UUID(uuidstr)
ctypes.Structure.__init__(self)
self.Data1, self.Data2, self.Data3, \
self.Data4[0], self.Data4[1], rest = uuid.fields
for i in range(2, 8):
self.Data4[i] = rest>>(8-i-1)*8 & 0xff
SHGetKnownFolderPath = windll.shell32.SHGetKnownFolderPath
SHGetKnownFolderPath.argtypes = [
ctypes.POINTER(GUID), wintypes.DWORD,
wintypes.HANDLE, ctypes.POINTER(ctypes.c_wchar_p)
]
def _get_known_folder_path(uuidstr):
pathptr = ctypes.c_wchar_p()
guid = GUID(uuidstr)
if SHGetKnownFolderPath(ctypes.byref(guid), 0, 0, ctypes.byref(pathptr)):
raise ctypes.WinError()
return pathptr.value
FOLDERID_Download = '{374DE290-123F-4565-9164-39C4925E467B}'
def get_download_folder():
return _get_known_folder_path(FOLDERID_Download)
else:
def get_download_folder():
home = os.path.expanduser("~")
return os.path.join(home, "Downloads")
A more complete module for retrieving known folders from Python is available on github.
Some linux distributions localize the name of the Downloads folder. E.g. after changing my locale to zh_TW, the Downloads folder became /home/user/下載. The correct way on linux distributions (using xdg-utils from freedesktop.org) is to call xdg-user-dir:
import subprocess
# Copy windows part from other answers here
try:
folder = subprocess.run(["xdg-user-dir", "DOWNLOAD"],
capture_output=True, text=True).stdout.strip("\n")
except FileNotFoundError: # if the command is missing
import os.path
folder = os.path.expanduser("~/Downloads") # fallback
Note that the use of capture_output requires Python ≥3.7.
If you already use GLib or don't mind adding more dependencies, see also
these approaches using packages.
For python3 on windows try:
import os
folder = os.path.join(os.path.join(os.environ['USERPROFILE']), 'folder_name')
print(folder)

Getting a win32ui.error: CreateFile when trying to save a screenshot with python and winapi

The following is my code:
import sys
import win32gui
import win32ui
import win32con
from time import sleep
from datetime import datetime
def get_windows_bytitle(title_text):
def _window_callback(hwnd, all_windows):
all_windows.append((hwnd, win32gui.GetWindowText(hwnd)))
windows = []
win32gui.EnumWindows(_window_callback, windows)
return [hwnd for hwnd, title in windows if title_text in title]
def screenshot(hwnd, filename):
l,t,r,b = win32gui.GetClientRect(hwnd)
h = b - t
w = r - l
hDC = win32gui.GetDC(hwnd)
myDC = win32ui.CreateDCFromHandle(hDC)
newDC = myDC.CreateCompatibleDC()
myBitMap = win32ui.CreateBitmap()
myBitMap.CreateCompatibleBitmap(myDC, w, h)
newDC.SelectObject(myBitMap)
win32gui.SetForegroundWindow(hwnd)
sleep(.2) #lame way to allow screen to draw before taking shot
newDC.BitBlt((0,0),(w, h) , myDC, (0,0), win32con.SRCCOPY)
myBitMap.Paint(newDC)
myBitMap.SaveBitmapFile(newDC, "c:\\bla.bmp")
def main():
try:
hwnd = get_windows_bytitle("Chrome")[0]
except IndexError:
print("Chrome window not found")
sys.exit(1)
screenshot(hwnd, str(datetime.now().microsecond) + ".bmp")
if __name__ == "__main__":
main()
It works great on one PC, but running now on my laptop raises the following error for some reason:
win32ui.error: CreateFile
Can't find any info regarding that exception online... For the record (if it makes a difference) I installed the winapi on this laptop using the following package from pypi:
pip install pypiwin32
because installing the regular pywin32 didn't work.
Also, now that I think of it, this machine is Windows 8.1 as opposed to Windows 7 on the machine that runs it fine.
Any ideas?
There must be some permission issue on C:\ and hence it must be failing. Create temp folder (or whatever name you like) and modify your code as shown below
myBitMap.SaveBitmapFile(newDC, "c:\\temp\\bla.bmp")
Note: ensure that temp folder exist.

Launch default image viewer from pygtk program

I'm writing a PyGTK GUI application in Ubuntu to browse some images, and I'd like to open an image in the default image viewer application when it is double-clicked (like when it is opened in Nautilus).
How can I do it?
I don't know specifically using PyGTK but: xdg-open opens the default app for a file so running something like this should work:
import os
os.system('xdg-open ./img.jpg')
EDIT: I'd suggest using the subprocess module as in the comments. I'm not sure exactly how to use it yet so I just used os.system in the example to show xdg-open.
In GNU/Linux use xdg-open, in Mac use open, in Windows use start. Also, use subprocess, if not you risk to block your application when you call the external app.
This is my implementation, hope it helps: http://goo.gl/xebnV
import sys
import subprocess
import webbrowser
def default_open(something_to_open):
"""
Open given file with default user program.
"""
# Check if URL
if something_to_open.startswith('http') or something_to_open.endswith('.html'):
webbrowser.open(something_to_open)
return 0
ret_code = 0
if sys.platform.startswith('linux'):
ret_code = subprocess.call(['xdg-open', something_to_open])
elif sys.platform.startswith('darwin'):
ret_code = subprocess.call(['open', something_to_open])
elif sys.platform.startswith('win'):
ret_code = subprocess.call(['start', something_to_open], shell=True)
return ret_code
GTK (>= 2.14) has gtk_show_uri:
gtk.show_uri(screen, uri, timestamp)
Example usage:
gtk.show_uri(None, "file:///etc/passwd", gtk.gdk.CURRENT_TIME)
Related
How to open a file with the standard application?

Categories