Python 在 windows 下的下调用 cmd 相关问题

2017-04-20 20:12:50 +08:00
 wangqianping
需要调用管理员权限的 cmd
4000 次点击
所在节点    问与答
16 条回复
Mistwave
2017-04-20 20:40:12 +08:00
wevsty
2017-04-20 21:14:44 +08:00
要执行命令的话直接 os.system()不就好了么?
wangqianping
2017-04-20 21:31:58 +08:00
@wevsty 这个不能调用管理员权限
wevsty
2017-04-20 23:00:39 +08:00
@wangqianping 权限是根据运行进程的权限决定的。
如果你的 Python 解释器是管理员权限,那么 os.system()就是管理员权限来执行。
如果你要在非管理员权限中创建管理员权限的进程,那估计就只能自己调 Windows API 了(比如 ShellExecuteEx ),而且免不了 UAC 提示。
wangqianping
2017-04-20 23:23:34 +08:00
@wevsty 您能简略说下怎么让 python 在管理员权限下运行么
wevsty
2017-04-20 23:35:48 +08:00
@wangqianping 找到 Python 的解释器,比如 python.exe , pythonw.exe ,右键属性-》兼容性选项卡-》以管理员身份运行
wangqianping
2017-04-20 23:49:09 +08:00
@wevsty 好的,多谢您了
geelaw
2017-04-21 00:16:49 +08:00
@wangqianping

难道不是在一个管理员权限的 prompt (例如管理员权限的 Command Prompt )下打开 python 即可么?为什么要改变 global 的性质来干一件 local 的事情?
wangqianping
2017-04-21 00:25:14 +08:00
@geelaw 我的 python 代码是要被其他函数调用的,然后 python 代码中要调用 adminstrator 权限的 cmd ,在这里运行一个 bat 文件,您有什么办法呢
wangqianping
2017-04-21 00:28:23 +08:00
@wevsty 想问您下,如果不该 python 权限可以吗,如果没次要改 python 权限,在别的机子上就可能会出问题呢,能不能 python 调用 cmd 的方式呢,然后可以自动输入密码,而不是要求手动输入密码的方式
geelaw
2017-04-21 01:05:01 +08:00
@wangqianping 如果你提前知道了密码,那么你可以写一个辅助程序帮你做这件事情,但是这很麻烦。

而且你怎么可能知道其他机器的管理员密码呢?

一个选项是你可以在启动 Python 脚本的时候看一下自己是不是管理员权限,如果不是,尝试以管理员权限重启自己。

另一个选项是以管理员身份启动你需要的程序,这需要使用 RunAs 这个动词,你可以透过 PowerShell 来做这件事情,通过 Python 运行如下命令:

PowerShell.exe -Command "& { Start-Process cmd.exe -Verb RunAs }"

如果你不具有管理员权限,将会弹出 UAC 要求确认或输入密码,如果你具有管理员权限,将使用管理员权限启动 cmd.exe 。

如果你想设置参数,你可以

PowerShell.exe -Command "& { Start-Process cmd.exe -ArgumentList @('/c', 'my-batch.bat') -Verb RunAs }"

注意:如果你先前不是管理员权限,那么通过 UAC 启动应用后,应用的工作目录会被重设为系统目录。
wevsty
2017-04-21 08:19:55 +08:00
@geelaw
@wangqianping
当然,如果已经具有管理员程序的进程创建的新进程,如果没有做过特殊限制的话,那么子进程将会继承父进程的管理员权限。

所以打开一个管理员权限的 CMD 然后再执行其他程序也是可以的。
个人不喜欢使用 PowerShell ,比起直接执行会有一些其他的问题,所以使用 PowerShell 的方法我个人并不推荐。

对于一个开启 UAC 的机器, UAC 启动时给出的提示环境与普通桌面并不处于一个 Session ,一般也会叫他安全桌面,这个环境下与其他 Session 是隔离的,所以没办法做到自动允许 UAC 提示或者自动输入密码。这一点是微软本身的设计,也是为了保障 UAC 不被非法绕过。
所以自动输入密码来使进程提升权限是不可行的,如果每次不定时启动一个程序都要求用户允许,体验太糟糕。所以根本的解决办法就是父进程启动时一次性使用管理员权限,然后子进程直接继承权限就好。如果需要开机自动启动并且具有管理员权限,可以使用任务计划来启动。
geelaw
2017-04-21 08:56:08 +08:00
@wevsty

PowerShell 只是一个间接用来 **以管理员权限** 启动 cmd 的工具,本来可以用 runas.exe 代替的,但是 runas.exe 自从 Windows 8 开始不会弹 UAC 了,而 PowerShell 可以很方便地用 RunAs verb 启动程序。这和在 ShellExecuteEx 里面传入 RunAs 作为 verb 效果一样。

我说的用密码直接启动是使用 Windows API 达成的,不是 UI 自动化。
wangqianping
2017-04-21 09:28:04 +08:00
@geelaw python 文件被调用时,提供管理员密码。可以把密码作为其中参数,但是中途不想要再输入密码。
wevsty
2017-04-21 10:33:04 +08:00
@geelaw
@wangqianping
PowerShell 这种用法当然也是可以的,但是用 system 函数执行这样的命令本来是会阻塞等待命令完成的,而这样操作则不会阻塞,从同步变成了异步,如果要获取命令行返回的结果也会有一些问题。总的来说,不推荐使用这样的方法。
最简单的就是任务计划来操作,任务计划提供了以管理员或者指定账户执行的功能,通过任务计划来启动主程序就什么事都没有了。
如果使用 CreateProcessAsUser 或者 CreateProcessWithLogonW 这样的 API 当然也可以做到通过密码登陆账户然后在创建管理员进程,但是那实在是太麻烦了。
geelaw
2017-04-21 12:53:33 +08:00
@wangqianping

那就得 Windows API 了,这样做是不好的,不如一开始用管理员权限启动整个程序。

@wevsty

那就没必要用任务计划启动主程序呀 - - 干脆直接管理员权限开 python 就好

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/356256

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX