Comments (9)
通过前面几个版本的迭代,发现任务应该这样分解
分成两个脚本,脚本2中有两个任务
脚本1.要为右键菜单添加一个“添加到当前用户环境变量PATH中”的项目,将该菜单项的执行链接为python的脚本2所在路径
脚本2.获取选中的文本或获取选中文件夹所在路径
脚本2.单击该菜单时要执行另一段python设置环境变量PATH的脚本
原计划是将右键菜单项添加到资源管理器的右键菜单中,获取当前选中文本作为要添加到PATH中的值,比如
但是经过两天的搜索,依然没有清晰的解决方案,先时间止损,采用剪贴板的方案实现文本的获取
再次调整任务
脚本1.添加一个右键菜单项“将剪贴板内容添加到PATH值中”到所有文件、文件夹的右键菜单中
脚本2.实现将剪贴板内容添加到当前用户环境变量PATH值的末尾
用python操作剪贴板资料比较多,所以将剪贴板操作代码合并到version1.2.1中形成version1.3(脚本2)
version 1.3
# coding:utf-8
"""
将剪贴板内容设置为环境变量PATH的值
"""
import _winreg
import win32clipboard as w
import win32con
def clearClipboard():
w.OpenClipboard()
w.EmptyClipboard()
w.CloseClipboard()
def getTextFromClipboard():
w.OpenClipboard()
d = w.GetClipboardData(win32con.CF_TEXT)
w.CloseClipboard()
return d
try:
strtemp = getTextFromClipboard()
except TypeError:
print 'maybe no data in Clipboard'
exit()
clearClipboard()
newenv = strtemp + ';' #'c:\\python271;'#用变量代替取到的字符串
user_env = _winreg.CreateKey(_winreg.HKEY_CURRENT_USER,'Environment')
# user_env = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER,'Environment')
# print user_env
value,type = _winreg.QueryValueEx(user_env,'PATH')
# print value,type
tempenv = value + newenv
# print tempenv
try:
_winreg.SetValueEx(user_env,'PATH',0,type,tempenv)
except WindowsError:
print 'excetion'
finally:
_winreg.CloseKey(user_env)
from pythonstartup.
优化
1.PATH中已有的路径不再添加
2.原本打印信息的地方改为弹出windows消息框
version 2.0
# coding:utf-8
"""
将剪贴板中的内容添加到环境变量PATH的值中
"""
import sys
import _winreg
import win32clipboard as w
import win32con
import win32api
def clearClipboard():
w.OpenClipboard()
w.EmptyClipboard()
w.CloseClipboard()
def getTextFromClipboard():
w.OpenClipboard()
d = w.GetClipboardData(win32con.CF_TEXT)
w.CloseClipboard()
return d
try:
strtemp = getTextFromClipboard()
except TypeError:
win32api.MessageBox(0, "Maybe no data in Clipboard", "Tips",win32con.MB_OK)
sys.exit()
print strtemp
clearClipboard()
newenv = strtemp + ';'
user_env = _winreg.CreateKey(_winreg.HKEY_CURRENT_USER,'Environment')
value,type = _winreg.QueryValueEx(user_env,'PATH')
vlist = value.split(';')
print vlist
for v in vlist:
if strtemp == v:
win32api.MessageBox(0, "exist same path", "Tips",win32con.MB_OK)
sys.exit()
tempenv = value + newenv
try:
_winreg.SetValueEx(user_env,'PATH',0,type,tempenv)
win32api.MessageBox(0, "Successfully", "Tips",win32con.MB_OK)
except WindowsError:
win32api.MessageBox(0, "Set failed", "Tips",win32con.MB_OK)
finally:
_winreg.CloseKey(user_env)
# coding:utf-8
"""
添加菜单项到windows所有文件和文件夹的右键菜单中
"""
import _winreg
cKey = _winreg.CreateKeyEx(_winreg.HKEY_CLASSES_ROOT,"AllFilesystemObjects\shell\setpath\command")
mKey = _winreg.CreateKeyEx(_winreg.HKEY_CLASSES_ROOT,"AllFilesystemObjects\shell\setpath")
mstr = 'add clipboard content to the path'
cstr = "\"C:\\Program Files\\envset\\env.exe\" \"%1\"" # %1表示该文件不带参数
_winreg.SetValueEx(mKey,'',0,_winreg.REG_SZ, mstr) # menu name
_winreg.SetValueEx(cKey,'',0,_winreg.REG_SZ, cstr) #
_winreg.CloseKey(cKey)
_winreg.CloseKey(mKey)
最终,实现这个设置环境变量的功能需要安装一个文件,执行一个脚本
from pythonstartup.
总结
原本以为很简单的‘获取选中的文本’的功能却卡了很长时间,到现在心里面还有影子在。
通过一系列的搜索发现这个获取选中文本的功能有更专业的名词来表达,如“屏幕划词”、“鼠标划词”、“鼠标取词”等,在一些翻译软件中,这是很基础的一个功能。
用到的主要模块
_winreg:操作windows注册表
win32clipboard:操作windows剪贴板
win32api:调用windows api接口函数
cx_Freeze:打包python脚本成exe
了解了
windows注册表结构
windows环境变量在注册表中的位置
windows右键菜单在注册表中的位置
小技巧
python弹出提示消息框
python脚本打包成exe
from pythonstartup.
在报名三期之前有看过二期的一些资料
这两天在看同学陆续提交入学任务的时候也发现有同学碰到了windows操作系统下环境变量的坑,于是想着用Python做一个脚本轻松简便的将路径设置为用户的环境变量。
想法是这样的:用户在windows资源管理器地址栏中,选中路径文本后右键弹出菜单项“加入到当前用户的PATH环境变量”,单击该菜单即完成环境变量的设置
分解任务:
任务1.在windows的资源管理器中选中路径或选中一个目录
任务2.获取选中的路径文本或当前目录所在路径的字符串
任务3.右键为系统添加一个右键菜单项“加入到当前用户的PATH环境变量”,同时弹出菜单
任务4.执行设置环境变量脚本
以上4个任务中,第1个选中文本的任务可以由操作系统完成,后面3个任务需要编程
先来做第4个任务。
将第4个任务进行细分
4.1 取出当前环境变量PATH的值
4.2 根据分号分解字符串成列表
4.3 查询列表中的每个值,若已存在相同的值则提示“已有当前路径设置”,否则添加到列表末尾
4.4 将列表中的值重新组合为环境变量PATH的值
4.5 赋值给PATH
环境变量属于系统级的东西,于是想到python中的os模块应该有相应的方法可以用。
打开python官方文档搜索os模块,找到两个函数,一个是获取环境变量os.getenv(),一个是设置环境变量os.putenv(),果断用上先
少废话,上代码
version 1.0
# coding:utf-8
"""
使用getenv和putenv函数取出和设置环境变量
"""
import os
waitstr = 'c:\python271;'#假设一个待新增到环境变量中的路径
pathstr = ''
p = []
tempstr = os.getenv('path') #取得环境变量值
p = tempstr.split(';') #根据分号分解path环境变量的值
if waitstr in p:#若待新增的路径已经存在在path的值中则退出,否则添加到值列表中
print "exist"
exit()
else:
p.append(waitstr)
for s in p:#重新组合列表中的值为一个字符串
if s == '':
continue
pathstr += s + ';'
os.putenv('path',pathstr)#设置环境变量path设置值
print os.getenv('path')
最后一句打印出来的path的值始终没有新增的那条路径,也就是说putenv设置没有成功。
from pythonstartup.
打开windows查看环境变量,发现path的值没有发生变化,于是再去文档中查看putenv函数,发现有这么一句话
Such changes to the environment affect subprocesses started with os.system(), popen() or fork() and execv().
......
however, calls to putenv() don’t update os.environ, so it is actually preferable to assign to items of os.environ.
这个变化会影响到以os.system(), popen() or fork() and execv()开启的子进程
......
调用putenv()函数并不更新os.environ
不太明白啥意思,反正跟进程什么鬼有关系,感觉可能需要更新os.environ才会起作用
所以在准备尝试通过修改os.environ的值来设置为环境变量path设置值
少废话,上代码
version 1.1
# coding:utf-8
"""
使用os.environ取出和设置环境变量
"""
import os
# print os.environ
waitstr = 'c:\python271;'
os.environ['PATH'] = os.environ['PATH'] + waitstr
print os.getenv('path')
这下简单多了,但是最后发现跟1.0版本一样的现象,还是没法更改windows环境变量PATH的值。
此时有点困惑了,这到底咋回事,为什么不起作用的?
from pythonstartup.
只能再用google搜了
发现一段话,也许可能大概差不多解释了不起作用的原因
环境变量表是保存在每个进程的用户空间的最高地址的,一个进程无权修改别的进程的用户空间内容
没办法了,只能出大招了。
最终,考虑到在规划的任务中第3个任务需要修改注册表值以添加右键菜单,于是想到也许环境变量也可以通过修改注册表来实现,简单、暴力
在网上搜索python操作注册表的模块,还真有。
python有一个内置模块_winreg可以用来操作注册表。
工具有了,下面来了解操作方法,操作之前得先了解环境变量在注册表中的位置、键值等等信息
搜索一通,找到了位置
对于用户环境变量,写入注册表的 HKEY_CURRENT_USER/Environment
对于系统环境变量,写入注册表的 HKEY_LOCAL_MACHINE/SYSTEM/ControlSet001/Control/SessionManager/Environment
ControlSet分几种情况
ControlSet:表示运行时的配置
ControlSet001:表示系统真实的配置信息
ControlSet002:表示最近一次成功的配置信息
少废话,上代码
version 1.2
# coding:utf-8
"""
使用注册表操作模块取出和设置环境变量
"""
import _winreg
newenv = 'c:\\python271;'
user_env = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER,'Environment')
# print user_env
value,type = _winreg.QueryValueEx(user_env,'PATH')
# print value,type
tempenv = value + newenv
# print tempenv
try:
_winreg.SetValueEx(user_env,'PATH',0,type,tempenv)
except WindowsError:
print 'excetion'
finally:
_winreg.CloseKey(user_env)
执行后,SetValueEx一直抛异常,不知是什么原因
搜索一通,将OpenKey函数换成CreateKey函数后执行正常,PATH的值发生了变化
对比两个函数
_winreg.CreateKey(key, sub_key)
Creates or opens the specified key, returning a handle object.
key is an already open key, or one of the predefined HKEY_* constants.
sub_key is a string that names the key this method opens or creates.
If key is one of the predefined keys, sub_key may be None. In that case, the handle returned is the same key handle passed in to the function.
If the key already exists, this function opens the existing key.
The return value is the handle of the opened key. If the function fails, a WindowsError exception is raised.
_winreg.OpenKey(key, sub_key[, res[, sam]])
Opens the specified key, returning a handle object.
key is an already open key, or any one of the predefined HKEY_* constants.
sub_key is a string that identifies the sub_key to open.
res is a reserved integer, and must be zero. The default is zero.
sam is an integer that specifies an access mask that describes the desired security access for the key. Default is KEY_READ. See Access Rights for other allowed values.
The result is a new handle to the specified key.
If the function fails, WindowsError is raised.
网上说这个可能跟_winreg模块与系统之间的配合有关系
再优化一下version 1.2
version 1.2.1
# coding:utf-8
"""
使用注册表操作模块取出和设置环境变量
"""
import _winreg
envlist = []
newenv = 'c:\\python271;'
user_env = _winreg.CreateKey(_winreg.HKEY_CURRENT_USER,'Environment')
# print user_env
value,type = _winreg.QueryValueEx(user_env,'PATH')
# print value,type
envlist = value.split(';')
for env in envlist:
if env == newenv:
print 'exist'
exit()
tempenv = value + newenv + ';'
# print tempenv
try:
_winreg.SetValueEx(user_env,'PATH',0,type,tempenv)
except WindowsError:
print 'excetion'
finally:
_winreg.CloseKey(user_env)
至此,任务4(设置环境变量的脚本)算是有了影。
from pythonstartup.
重新屡一下需要编程实现的点
1.编程查找注册表特定位置添加键值
2.右键菜单执行脚本2生成的exe文件实现添加环境变量PATH的值
由于脚本2已基本完工,所以先将脚本2生成exe文件,以便能在windows上运行。
搜索发现cx-freeze模块可以干这个事,使用pip install cx-Freeze
安装包
生成exe需要在脚本2所在目录再新增一个setup.py脚本
访问cx-Freeze的官方文档,上面有setup.py的模板,复制下来
import sys
from cx_Freeze import setup, Executable
# Dependencies are automatically detected, but it might need fine tuning.
build_exe_options = {"packages": ["os"], "excludes": ["tkinter"]}
# GUI applications require a different base on Windows (the default is for a
# console application).
base = None
if sys.platform == "win32":
base = "Win32GUI"
setup( name = "guifoo",
version = "0.1",
description = "My GUI application!",
options = {"build_exe": build_exe_options},
executables = [Executable("guifoo.py", base=base)])
将setup函数的参数修改为自己的信息,必须要修改的地方是executables = [Executable("guifoo.py", base=base)])
中的guifoo.py,这里应该改成脚本2的名字,确保cx_Freeze在生成exe时能找到脚本2
脚本2和setup.py都已经准备好。
命令行中输入命令
python setup.py bdist_msi
在脚本所在的目录中会生成两个文件夹
dist目录中有一个生成的安装文件
双击安装,默认路径安装完成后,在C盘下能找到安装后的可执行exe程序
验证是否可以成功执行,复制一条待设置环境变量的路径到剪贴板
执行生成的exe,查看环境变量PATH值的变化
PATH值的末尾新增了刚刚复制的一条路径,说明exe执行成功。
from pythonstartup.
截至目前,整个任务还剩下编程实现添加右键菜单
及一些优化
未实现
现在就来实现添加右键菜单的功能。
考虑后,决定将右键菜单项添加到所有文件和文件夹的右键菜单中。
经过搜索,文件和文件夹的右键菜单位于注册表 HKEY_CLASSES_ROOT\AllFilesystemObjects\shell下
要想右键菜单执行指定的文件,需在shell下设置好菜单项后在其下新建command键,并将指定的文件路径赋值给command的值
依然使用_winreg模块来操作注册表
CreateKeyEx函数用于打开已存在的或新建一个键
SetValueEx函数用于为键设定一个值
少废话,上代码
# coding:utf-8
import _winreg
cKey = _winreg.CreateKeyEx(_winreg.HKEY_CLASSES_ROOT,"AllFilesystemObjects\shell\setpath\command")
mKey = _winreg.CreateKeyEx(_winreg.HKEY_CLASSES_ROOT,"AllFilesystemObjects\shell\setpath")
mstr = 'add clipboard content to the path'
cstr = "\"C:\\Program Files\\envset\\env.exe\" \"%1\"" # %1表示该文件不带参数
_winreg.SetValueEx(oKey,'',0,_winreg.REG_SZ, mstr) # menu name
_winreg.SetValueEx(cKey,'',0,_winreg.REG_SZ, cstr) #
_winreg.CloseKey(cKey)
_winreg.CloseKey(mKey)
执行代码后,打开注册表
注册表更新成功。再看右键菜单效果
右键菜单添加成功。
from pythonstartup.
请问是怎么实现选中文本的啊
from pythonstartup.
Related Issues (20)
- 流云完成 Py104 入学挑战啦
- 小琪完成 Py104 入学挑战啦
- 许可完成 Py104 入学挑战啦
- XWJ 完成 Py104 入学挑战啦;
- O水水完成py104入学挑战啦
- Menty5完成py104入学挑战啦
- ziyouma1010完成py104入学挑战 HOT 1
- ternknuth完成 Py104 入学挑战啦
- caicono完成 Py104 入学挑战啦
- 董琛完成 Py104 入学挑战啦
- 子午鸟完成 Py104 入学挑战啦
- NBR-hugh 完成PY104入学挑战啦
- 刘帆提交了 Py104 入学挑战啦 HOT 2
- 武虎完成 Py104 入学挑战啦
- 李长建完成 Py104 入学挑战啦
- 熊猫完成 Py104 入学挑战啦 achievement HOT 2
- 侯豆豆完成 Py104 入学挑战啦
- puzzling完成Py104入学挑战啦 HOT 1
- rick完成 Py104 入学挑战啦
- xuewenqi完成课程py104课程挑战了
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pythonstartup.