我将如何获得一个特权提升对话框,以在我的Python应用程序中弹出?我需要Windows上的UAC对话框和Mac上的密码认证对话框。在Mac OS X,Windows上获取Python中的root对话框?
基本上,我需要部分应用程序的root权限,我需要通过GUI获得这些权限。我正在使用wxPython。有任何想法吗?
我将如何获得一个特权提升对话框,以在我的Python应用程序中弹出?我需要Windows上的UAC对话框和Mac上的密码认证对话框。在Mac OS X,Windows上获取Python中的root对话框?
基本上,我需要部分应用程序的root权限,我需要通过GUI获得这些权限。我正在使用wxPython。有任何想法吗?
在Windows上,如果不启动新进程就无法获得UAC对话框,甚至无法使用CreateProcess启动该进程。
可以通过运行具有相应清单文件的另一个应用程序来实现UAC对话框 - 有关如何使用py2exe执行此操作的示例,请参阅Running compiled python (py2exe) as administrator in Vista。
您也可以通过编程使用runas动词用的Win32 API的ShellExecute http://msdn.microsoft.com/en-us/library/bb762153(v=vs.85).aspx - 您可以通过使用ctypes的http://python.net/crew/theller/ctypes/这是蟒蛇2.5+ IIRC标准库的一部分调用它。
对不起,不知道Mac。如果您在Windows上提供更多关于您想要完成的细节,我可能会提供更具体的帮助。
我在Mac OS X上遇到了同样的问题。我有一个工作解决方案,但它不是最优的。我会在这里解释我的解决方案,并继续寻找更好的解决方案。
在节目的一开始我检查我的根或不执行
def _elevate():
"""Elevate user permissions if needed"""
if platform.system() == 'Darwin':
try:
os.setuid(0)
except OSError:
_mac_elevate()
os.setuid如果我没有根(0)将失败,将触发_mac_elevate()从osascript的帮助下,以管理员身份重新启动我的程序。 osascript可以用来执行applescript和其他东西。我用这样的:
def _mac_elevate():
"""Relaunch asking for root privileges."""
print "Relaunching with root permissions"
applescript = ('do shell script "./my_program" '
'with administrator privileges')
exit_code = subprocess.call(['osascript', '-e', applescript])
sys.exit(exit_code)
这样做的问题是,如果我用subprocess.call如上我保持当前的进程运行,并会出现运行给二常驻图标我的应用程序的两个实例。如果我使用subprocess.Popen,而让非特权进程立即死亡,我不能使用退出代码,也不能使用stdout/stderr流并传播到启动原始进程的终端。
我知道这个帖子有点旧了,但是我写了以下内容作为我的问题的解决方案(在Linux和OS X上以root身份运行python脚本)。
我写了下面的bash脚本以管理员权限执行的bash/Python脚本(在Linux和OS X系统):
#!/bin/bash
if [ -z "$1" ]; then
echo "Specify executable"
exit 1
fi
EXE=$1
available(){
which $1 >/dev/null 2>&1
}
platform=`uname`
if [ "$platform" == "Darwin" ]; then
MESSAGE="Please run $1 as root with sudo or install osascript (should be installed by default)"
else
MESSAGE="Please run $1 as root with sudo or install gksu/kdesudo!"
fi
if [ `whoami` != "root" ]; then
if [ "$platform" == "Darwin" ]; then
# Apple
if available osascript
then
SUDO=`which osascript`
fi
else # assume Linux
# choose either gksudo or kdesudo
# if both are avilable check whoch desktop is running
if available gksudo
then
SUDO=`which gksudo`
fi
if available kdesudo
then
SUDO=`which kdesudo`
fi
if (available gksudo && available kdesudo)
then
if [ $XDG_CURRENT_DESKTOP = "KDE" ]; then
SUDO=`which kdesudo`;
else
SUDO=`which gksudo`
fi
fi
# prefer polkit if available
if available pkexec
then
SUDO=`which pkexec`
fi
fi
if [ -z $SUDO ]; then
if available zenity; then
zenity --info --text "$MESSAGE"
exit 0
elif available notify-send; then
notify-send "$MESSAGE"
exit 0
elif available xmessage notify-send; then
xmessage -buttons Ok:0 "$MESSAGE"
exit 0
else
echo "$MESSAGE"
fi
fi
fi
if [ "$platform" == "Darwin" ]
then
$SUDO -e "do shell script \"$*\" with administrator privileges"
else
$SUDO [email protected]
fi
基本上,我建立了我的系统的方式就是,我不断bin目录内的子文件夹(例如/ usr/local/bin中的/ usr/local/bin/pyscripts),并创建与可执行文件的符号链接。这对我有三个好处:(1)如果我有不同的版本,我可以通过更改符号链接轻松切换执行哪个版本,并保持bin目录清洁(例如/ usr/local/bin/gcc -version/4.9 /,/usr/local/bin/gcc-versions/4.8/,/ usr/local/bin/gcc - > gcc-versions/4.8/gcc)
(2)脚本及其扩展(有助于IDE中的语法突出显示),但可执行文件不包含它们,因为我喜欢它(例如svn-tools - > pyscripts/svn-tools。PY)
(3)的原因我下面会显示:
我的名字脚本“运行为根 - 包装”,并将其放置在一个很普通的路径(例如,/ usr/local/bin目录)所以python不需要任何特殊的东西来定位它。然后,我有以下run_command.py模块:
import os
import sys
from distutils.spawn import find_executable
#===========================================================================#
def wrap_to_run_as_root(exe_install_path, true_command, expand_path = True):
run_as_root_path = find_executable("run-as-root-wrapper")
if(not run_as_root_path):
return False
else:
if(os.path.exists(exe_install_path)):
os.unlink(exe_install_path)
if(expand_path):
true_command = os.path.realpath(true_command)
true_command = os.path.abspath(true_command)
true_command = os.path.normpath(true_command)
f = open(exe_install_path, 'w')
f.write("#!/bin/bash\n\n")
f.write(run_as_root_path + " " + true_command + " [email protected]\n\n")
f.close()
os.chmod(exe_install_path, 0755)
return True
在我实际的Python脚本,我有以下功能:
def install_cmd(args):
exe_install_path = os.path.join(args.prefix,
os.path.join("bin", args.name))
if(not run_command.wrap_to_run_as_root(exe_install_path, sys.argv[0])):
os.symlink(os.path.realpath(sys.argv[0]), exe_install_path)
所以,如果我有一个名为TrackingBlocker.py(实际脚本脚本我当我调用“sudo /usr/local/bin/pyscripts/TrackingBlocker.py --prefix/usr/local --name ModifyTrackingBlocker时,使用修改/ etc/hosts文件将已知跟踪域重新路由到127.0.0.1)安装“(参数通过argparse模块处理),它会安装”/ usr/local/bin/ModifyTrackingBlocker“,这是一个bash脚本执行
/usr/local/bin/run-as-root-wrapper /usr/local/bin/pyscripts/TrackingBlocker.py [args]
例如
ModifyTrackingBlocker add tracker.ads.com
执行:
/usr/local/bin/run-as-root-wrapper /usr/local/bin/pyscripts/TrackingBlocker.py add tracker.ads.com
,然后显示获得的特权添加所需的认证对话框:
127.0.0.1 tracker.ads.com
到我的主机文件(这是只可写的超级用户) 。
如果你想简化/修改它以root身份运行只有特定的命令,你可以简单地添加到您的脚本(必要进口上述+进口子指出):
def run_as_root(command, args, expand_path = True):
run_as_root_path = find_executable("run-as-root-wrapper")
if(not run_as_root_path):
return 1
else:
if(expand_path):
command = os.path.realpath(command)
command = os.path.abspath(command)
command = os.path.normpath(command)
cmd = []
cmd.append(run_as_root_path)
cmd.append(command)
cmd.extend(args)
return subprocess.call(' '.join(cmd), shell=True)
使用上述(在run_command模块):
>>> ret = run_command.run_as_root("/usr/local/bin/pyscripts/TrackingBlocker.py", ["status", "display"])
>>> /etc/hosts is blocking approximately 16147 domains
不知道,如果你能在OSX做到这一点,通过Python脚本。在一些类Unix操作系统(包括OS X)下,不能授予脚本(如shell,perl,python等)来调用chown/chgrp,这会给你其他特权。 – Drake 2011-04-21 16:33:08