当前位置:  开发笔记 > 编程语言 > 正文

从Python脚本中请求UAC提升?

如何解决《从Python脚本中请求UAC提升?》经验,为你挑选了3个好方法。

我希望我的Python脚本能够在Vista上复制文件.当我从普通cmd.exe窗口运行它时,不会生成错误,但不会复制文件.如果我运行cmd.exe"作为管理员",然后运行我的脚本,它工作正常.

这是有道理的,因为用户帐户控制(UAC)通常会阻止许多文件系统操作.

有没有办法可以在Python脚本中调用UAC提升请求(这些对话框说"像这样的应用程序需要管理员访问权限,这样可以吗?")

如果那是不可能的,那么我的脚本是否有一种方法可以至少检测到它没有被提升以便它可以优雅地失败?



1> Martín De la..:

截至2017年,实现这一目标的简单方法如下:

import ctypes, sys

def is_admin():
    try:
        return ctypes.windll.shell32.IsUserAnAdmin()
    except:
        return False

if is_admin():
    # Code of your program here
else:
    # Re-run the program with admin rights
    ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, __file__, None, 1)

如果您使用的是Python 2.x,那么您应该替换最后一行:

ctypes.windll.shell32.ShellExecuteW(None, u"runas", unicode(sys.executable), unicode(__file__), None, 1)

还要注意的是,如果你转换你的Python脚本到一个可执行文件(使用工具,如py2exe,cx_freeze,pyinstaller),那么你应该更换第四个参数为空字符串("").

这里的一些优点是:

不需要外部库(也不是用于Windows扩展的Python).它仅使用ctypes标准库.

适用于Python 2和Python 3.

无需修改文件资源也无需创建清单文件.

如果你没有在if/else语句下面添加代码,那么代码将不会被执行两次.

如果用户拒绝UAC提示,您可以轻松地将其修改为具有特殊行为.

您可以指定修改第四个参数的参数.

您可以指定修改第六个参数的显示方法.

底层ShellExecute调用的文档在这里.


我不得不使用unicode实例作为ShellExecuteW的参数(如u'runas'和unicode(sys.executable))来运行它.
@Janosch,那是因为你使用的是Python 2.x,而我的代码是在Python 3中(其中所有字符串都被视为unicodes).但是值得一提,谢谢!
我的回答是假设我们实际上并不关心参数.所以,在python脚本中使用`sys.argv [0]`或`__file__`就可以了.如果你把它转换成一个可执行文件,那么你可以使用``"`,`"anyrandomstring"`,`sys.argv [0]`它也可以工作(但不是`__file__`,因为它没有定义) .现在,如果你关心参数,你应该使用`"".join(sys.argv)`作为python脚本,使用`"".join(sys.argv [1:])`作为转换后的脚本.@HrvojeT
@Martin如果我从Windows命令行运行这样的代码:"python yourcode.py"它只是打开python.exe.有办法解决吗?
@HrvojeT,ShellExecuteW`和`ShellExecuteA`都是对Windows API中`ShellExecute`函数的调用.前者要求字符串采用unicode格式,后者使用ANSI格式

2> Jorenko..:

我花了一点时间让dguaraglia的答案正常工作,所以为了节省他人的时间,这就是我为实现这个想法而采取的措施:

import os
import sys
import win32com.shell.shell as shell
ASADMIN = 'asadmin'

if sys.argv[-1] != ASADMIN:
    script = os.path.abspath(sys.argv[0])
    params = ' '.join([script] + sys.argv[1:] + [ASADMIN])
    shell.ShellExecuteEx(lpVerb='runas', lpFile=sys.executable, lpParameters=params)
    sys.exit(0)


@JoranBeasley,你不会看到任何输出.ShellExecuteEx不会将其STDOUT发布回原始shell.在这方面,调试将是......具有挑战性.但特权提升技巧肯定有效.
这是我见过的最酷的技巧之一.
对于报价,您可以使用subprocess.list2cmdline正确执行。

3> dguaraglia..:

似乎没有办法提升应用程序权限一段时间来执行特定任务.Windows需要在程序开始时知道应用程序是否需要某些特权,并要求用户确认应用程序何时执行需要这些特权的任务.有两种方法可以做到这一点:

    编写一个清单文件,告诉Windows应用程序可能需要一些权限

    从另一个程序内部使用提升的权限运行应用程序

这两篇 文章更详细地解释了它是如何工作的.

如果您不想为CreateElevatedProcess API编写令人讨厌的ctypes包装器,我会使用代码项目文章中解释的ShellExecuteEx技巧(Pywin32带有ShellExecute的包装器).怎么样?像这样的东西:

当你的程序启动时,它会检查它是否具有管理员权限,如果它没有使用ShellExecute技巧自行运行并立即退出,如果是,则执行手头的任务.

当您将程序描述为"脚本"时,我认为这足以满足您的需求.

干杯.


您可能需要注意的一点是,您可以使用os.startfile($ EXECUTABLE,"runas")在没有PyWin32的情况下执行ShellExecute(我在安装它时遇到了问题).
推荐阅读
围脖上的博博_771
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有