Last active
February 27, 2021 03:54
-
-
Save pc223/48e9a24ef595cec4465ed41bf880be5f to your computer and use it in GitHub Desktop.
Print out control panel task links on MS Windows
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
# -*- coding: utf-8 -*- | |
""" | |
Print out control panel task links: command, name, and keywords | |
This script is modified from this: https://github.com/blackdaemon/enso-launcher-continued/blob/master/enso/contrib/open/platform/win32/control_panel_win7.py | |
Need this to run: python27 + pip install pywin32 | |
Output language will depends on current system's language, not only English | |
Output: | |
0 | Accommodate learning abilities | control.exe /name Microsoft.EaseOfAccessCenter /page pageQuestionsCognitive | [[u'accomidate', u'accomodates', u'accomodating', u'adjust', u'for'], [u'can', u'not', u'cannot', u"can't", u'difficult', u'to', u'difficulty', u'does', u"doesn't", u'hard', u'not', u'will', u'willnot', u"won't"], [u'disabled', u'handicap', u'handicapped', u'disabilities', u'disability', u'empaired', u'impaired', u'imparied', u'trouble'], [u'cognitive', u'learning']] | |
1 | Accommodate low vision | control.exe /name Microsoft.EaseOfAccessCenter /page pageEasierToSee | [[u'accomidate', u'accomodates', u'accomodating', u'adjust', u'for'], [u'site', u'blindness', u'blurred', u'blurry', u'half', u'legally', u'low', u'vision', u'poor', u'seeing', u'seems', u'sight', u'weak', u'bad', u'eyesight', u'eye-sight'], [u'disabled', u'handicap', u'handicapped', u'disabilities', u'disability', u'empaired', u'impaired', u'imparied', u'trouble'], [u'best', u'better', u'easier', u'easy', u'enhance', u'improvement', u'make', u'more', u'most', u'optimal', u'optimise', u'optimize']] | |
2 | Change how your keyboard works | control.exe /name Microsoft.EaseOfAccessCenter /page pageKeyboardEasierToUse | [[u'switch', u'filterkeys', u'keys', u'stickykeys', u'togglekeys', u'sticky-keys', u'toggle-keys', u'repeat', u'delay', u'hold', u'down', u'rate'], [u'accessibility', u'acessibility', u'ease', u'of'], [u'best', u'better', u'easier', u'easy', u'enhance', u'improvement', u'make', u'more', u'most', u'optimal', u'optimise', u'optimize'], [u'board', u'bord', u'keyboards', u'keyborads', u'keybord']] | |
3 | Change how your mouse works | control.exe /name Microsoft.EaseOfAccessCenter /page pageEasierToClick | [[u'accessibility', u'acessibility', u'ease', u'of'], [u'butons', u'buttons'], [u'adjust', u'ajust', u'alter', u'change', u'edit', u'modify', u'replace', u'reset', u'set', u'switch'], [u'lock', u'clicking', u'doubleclick', u'double-click', u'single-click'], [u'best', u'better', u'easier', u'easy', u'enhance', u'improvement', u'make', u'more', u'most', u'optimal', u'optimise', u'optimize'], [u'move', u'moving', u'shadow', u'speed', u'tails'], [u'mice', u'mouses', u'pointer']] | |
4 | Use screen reader | control.exe /name Microsoft.EaseOfAccessCenter /page pageNoVisual | [[u'adjust', u'ajust', u'alter', u'change', u'edit', u'modify', u'replace', u'reset', u'set', u'switch'], [u'screan', u'readers', u'screenreader', u'windows', u'narrator']] | |
5 | Change the Narrator’s voice | %windir%\system32\narrator.exe | [[u'adjust', u'ajust', u'alter', u'change', u'edit', u'modify', u'replace', u'reset', u'set', u'switch'], [u'sound', u'voices'], [u'screan', u'readers', u'screenreader', u'windows', u'narrator']] | |
... | |
""" | |
import os | |
import re | |
from xml.etree import cElementTree as ElementTree | |
import win32api | |
import win32con | |
def _expand_path_variables(file_path): | |
re_env = re.compile(r'%\w+%') | |
def expander(mo): | |
return os.environ.get(mo.group()[1:-1], 'UNKNOWN') | |
return re_env.sub(expander, file_path) | |
def read_mui_string_from_dll(id): | |
assert id.startswith("@") and ",-" in id, \ | |
"id has invalid format. Expected format is '@dllfilename,-id'" | |
m = re.match("@([^,]+),-([0-9]+)(;.*)?", id) | |
if m: | |
dll_filename = _expand_path_variables(m.group(1)) | |
string_id = long(m.group(2)) | |
else: | |
raise Exception( | |
"Error parsing dll-filename and string-resource-id from '%s'" % id) | |
h = win32api.LoadLibraryEx( | |
dll_filename, | |
None, | |
win32con.LOAD_LIBRARY_AS_DATAFILE | win32con.DONT_RESOLVE_DLL_REFERENCES) | |
if h: | |
s = win32api.LoadString(h, string_id) | |
return s | |
return None | |
def read_task_links_xml(xml): | |
APPS_NS = "http://schemas.microsoft.com/windows/cpltasks/v1" | |
TASKS_NS = "http://schemas.microsoft.com/windows/tasks/v1" | |
TASKS_NS2 = "http://schemas.microsoft.com/windows/tasks/v2" | |
results = [] | |
tree = ElementTree.fromstring(xml) | |
for app in tree.findall("{%s}application" % APPS_NS): | |
for item in app.findall('{%s}task' % TASKS_NS): | |
keyword_tags = item.findall('{%s}keywords' % TASKS_NS) | |
keywords = [] | |
for m in [k.text for k in keyword_tags]: | |
keywords.append([kw.strip() for kw in | |
read_mui_string_from_dll(m).split(';') if | |
kw.strip()]) | |
name_shell32id = item.findtext("{%s}name" % TASKS_NS) | |
name = read_mui_string_from_dll(name_shell32id) | |
cmd = item.findtext("{%s}command" % TASKS_NS) | |
cp = item.find("{%s}controlpanel" % TASKS_NS2) | |
if cmd is not None: | |
pass | |
elif cp is not None: | |
cname = cp.get('name') | |
cpage = cp.get('page') | |
cmd = "control.exe /name %s" % cname | |
if cpage: | |
cmd += " /page %s" % cpage | |
else: | |
raise ValueError('cmd and cp both None') | |
results.append((name, cmd, keywords)) | |
return results | |
def read_default_windows7_tasklist_xml(): | |
handle = win32api.LoadLibraryEx( | |
"shell32.dll", | |
None, | |
win32con.LOAD_LIBRARY_AS_DATAFILE | win32con.DONT_RESOLVE_DLL_REFERENCES) | |
# TODO: Is the resource-id #21 for all versions of Windows 7? | |
xml = win32api.LoadResource(handle, "XML", 21) | |
return xml | |
if __name__ == '__main__': | |
xml = read_default_windows7_tasklist_xml() | |
r = read_task_links_xml(xml) | |
r = sorted(r, key=lambda x: x[1]) | |
for idx, i in enumerate(r): | |
# Encode to avoid encoding trouble | |
s = '%d | %s | %s | %s' % (idx, i[1], i[0], i[2]) | |
print(s.encode('ascii', 'replace')) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here's a patch to work with both Python2 and Python3, using a try except.
This was tested on Windows 10.