Last active
June 30, 2023 22:37
-
-
Save x011/dce6215696cbc7ae62018d8c3024fd86 to your computer and use it in GitHub Desktop.
The script is very handy, Simply select a file or directory in Windows Explorer and copy its path to the clipboard directly from the context menu.To install it, run a command shell as admin and call the script without an argument. After that it is installed and can be used from the context menu.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
PathCatcher is a Windows utility that allows one to right-click on | |
a folder or a file in Explorer and save its path to the clipboard. | |
If this module is run by itself, it installs PathCatcher to the registry. | |
After it is installed, when one clicks on a file or folder, "PathCatcher" | |
appears in the right-click menu. | |
This module also contains some useful code for accessing the Windows | |
clipboard and registry. | |
OLD: Requires ctypes -- download from SourceForge. | |
Jack Trainor 2007 | |
Updated by The Famous Unknown in 20181128 | |
Several fixes on Jack's code, which was already 11 years old (Thanks jack!) | |
Supports both python2 and 3 | |
Doesn't require ctypes as before | |
To install run python pathcatcher.py once | |
""" | |
import sys | |
import win32con | |
import time | |
import os | |
import win32api | |
import win32clipboard | |
# IMPORTANT # | |
#Specify the python path manually - PYTHONPATH ENV can be unrealiable | |
pythonwExePath = "e:\\anaconda2\\pythonw.exe" # pythonw exe path | |
_input = None # | |
#handles input on py2 and py3 | |
if sys.version_info[0] == 2: | |
_input = raw_input | |
elif sys.version_info[0] == 3: | |
_input = input | |
""" Windows Clipboard utilities """ | |
def GetClipboardText(): | |
win32clipboard.OpenClipboard() | |
data = win32clipboard.GetClipboardData() | |
win32clipboard.CloseClipboard() | |
return data | |
def SetClipboardText(dir_or_file): | |
win32clipboard.OpenClipboard() | |
win32clipboard.EmptyClipboard() | |
win32clipboard.SetClipboardText(dir_or_file) | |
win32clipboard.CloseClipboard() | |
""" Windows Registry utilities """ | |
def OpenRegistryKey(hiveKey, key): | |
keyHandle = None | |
try: | |
curKey = "" | |
keyItems = key.split('\\') | |
for keyItem in keyItems: | |
if curKey: | |
curKey = curKey + "\\" + keyItem | |
else: | |
curKey = keyItem | |
keyHandle = win32api.RegCreateKey(hiveKey, curKey) | |
except Exception as e: | |
keyHandle = None | |
print ("OpenRegistryKey failed:", e) | |
return keyHandle | |
def ReadRegistryValue(hiveKey, key, name): | |
""" Simple api to read one value from Windows registry. | |
If 'name' is empty string, reads default value.""" | |
data = typeId = None | |
try: | |
hKey = win32api.RegOpenKeyEx(hiveKey, key, 0, win32con.KEY_ALL_ACCESS) | |
data, typeId = win32api.RegQueryValueEx(hKey, name) | |
win32api.RegCloseKey(hKey) | |
except Exception as e: | |
print ("ReadRegistryValue failed:", e) | |
return data, typeId | |
def WriteRegistryValue(hiveKey, key, name, typeId, data): | |
""" Simple api to write one value to Windows registry. | |
If 'name' is empty string, writes to default value.""" | |
try: | |
keyHandle = OpenRegistryKey(hiveKey, key) | |
win32api.RegSetValueEx(keyHandle, name, 0, typeId, data) | |
win32api.RegCloseKey(keyHandle) | |
except Exception as e: | |
print ("WriteRegistry failed:", e) | |
""" misc utilities """ | |
def WriteLastTime(): | |
secsString = str(time.time()) | |
WriteRegistryValue(win32con.HKEY_CLASSES_ROOT, r"*\shell\PathCatcher\time", "", win32con.REG_SZ, secsString) | |
def ReadLastTime(): | |
secs = 0.0 | |
secsString, dateTypId = ReadRegistryValue(win32con.HKEY_CLASSES_ROOT, r"*\shell\PathCatcher\time", "") | |
if secsString: | |
secs = float(secsString) | |
return secs | |
def AccumulatePaths(path): | |
""" Windows creates a Python process for each selected file on right-click. | |
Check to see if this invocation is part of current batch and accumulate to clipboard """ | |
lastTime = ReadLastTime() | |
now = time.time() | |
if (now - lastTime) < 1.0: | |
SetClipboardText(GetClipboardText() + "\n" + path) | |
else: | |
SetClipboardText(path) | |
WriteLastTime() | |
######################################################### | |
def InstallPathCatcher(): | |
""" Installs PathCatcher to the Windows registry """ | |
command = '%s %s "%s"' % (pythonwExePath, os.getcwd()+"/"+sys.argv[0], "%1") | |
WriteRegistryValue(win32con.HKEY_CLASSES_ROOT, r"*\shell\PathCatcher\Command", "", win32con.REG_SZ, command) | |
WriteRegistryValue(win32con.HKEY_CLASSES_ROOT, r"Folder\shell\PathCatcher\Command", "", win32con.REG_SZ, command) | |
WriteLastTime() | |
######################################################### | |
if __name__ == "__main__": | |
try: | |
# log requests | |
with open("d:/pathcatcher.log", "a") as f: | |
f.write( "{}".format( sys.argv[1]+"\n" ) ) | |
except: | |
pass | |
if len(sys.argv) > 1: | |
""" If invoked through a right-click, there will be a path argument """ | |
path = sys.argv[1] | |
AccumulatePaths(path) | |
else: | |
""" If module is run by itself, install PathCatcher to registry """ | |
InstallPathCatcher() | |
_input("PathCatcher installed.\nPress RETURN...") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment