[python] Python 스크립트 내에서 UAC 상승을 요청 하시겠습니까?

내 Python 스크립트가 Vista에서 파일을 복사하기를 원합니다. 일반 cmd.exe창 에서 실행하면 오류가 생성되지 않지만 파일은 복사되지 않습니다. 내가 실행하면 cmd.exe“administator로”다음 내 스크립트를 실행, 그것을 잘 작동합니다.

이는 UAC (사용자 계정 컨트롤)가 일반적으로 많은 파일 시스템 작업을 방지하기 때문에 의미가 있습니다.

Python 스크립트 내에서 UAC 권한 상승 요청을 호출 할 수있는 방법이 있습니까 ( “그런 앱에 관리자 액세스가 필요합니다.

그것이 가능하지 않다면, 내 스크립트가 적어도 상승되지 않았 음을 감지하여 정상적으로 실패 할 수있는 방법이 있습니까?



답변

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, " ".join(sys.argv), None, 1)

Python 2.x를 사용하는 경우 다음의 마지막 줄을 바꿔야합니다.

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

또한 실행 파일로 당신에게 파이썬 스크립트를 변환하면 있습니다 (같은 도구를 사용하여는 py2exe, cx_freeze, pyinstaller) 당신은 사용해야하는 sys.argv[1:]대신 sys.argv네 번째 매개 변수에.

여기에 몇 가지 장점은 다음과 같습니다.

  • 외부 라이브러리가 필요하지 않습니다. 그것은 단지 용도 ctypessys표준 라이브러리에서.
  • Python 2와 Python 3 모두에서 작동합니다.
  • 파일 리소스를 수정하거나 매니페스트 파일을 만들 필요가 없습니다.
  • if / else 문 아래에 코드를 추가하지 않으면 코드가 두 번 실행되지 않습니다.
  • 마지막 줄에서 API 호출의 반환 값을 가져와 실패 할 경우 조치를 취할 수 있습니다 (코드 <= 32). 여기에서 가능한 반환 값을 확인 하십시오 .
  • 여섯 번째 매개 변수를 수정하여 생성 된 프로세스의 표시 방법을 변경할 수 있습니다.

기본 ShellExecute 호출에 대한 문서는 여기에 있습니다 .


답변

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)


답변

특정 작업을 수행하기 위해 잠시 동안 응용 프로그램 권한을 높일 수있는 방법이없는 것 같습니다. Windows는 프로그램을 시작할 때 응용 프로그램에 특정 권한이 필요한지 여부를 알아야하며 응용 프로그램이 이러한 권한 이 필요한 작업을 수행 할 때 사용자에게 확인하도록 요청합니다 . 이를 수행하는 두 가지 방법이 있습니다.

  1. 응용 프로그램에 몇 가지 권한이 필요할 수 있음을 Windows에 알리는 매니페스트 파일 작성
  2. 다른 프로그램 내에서 상승 된 권한으로 응용 프로그램 실행

기사는 이것이 어떻게 작동하는지 훨씬 더 자세히 설명합니다.

CreateElevatedProcess API에 대해 불쾌한 ctypes 래퍼를 작성하지 않으려면 코드 프로젝트 문서에 설명 된 ShellExecuteEx 트릭을 사용하면됩니다 (Pywin32에는 ShellExecute 용 래퍼가 함께 제공됨). 어떻게? 이 같은:

프로그램이 시작될 때 관리자 권한이 있는지 확인하고, ShellExecute 트릭을 사용하여 자체적으로 실행되지 않으면 즉시 종료하고, 있으면 즉시 작업을 수행합니다.

귀하의 프로그램을 “스크립트”로 설명 할 때 그 정도면 충분하다고 생각합니다.

건배.


답변

다른 사람들이 Google 검색에서 여기로 안내하는 경우이 답변을 추가하십시오. elevatePython 스크립트 의 모듈과 Windows 10에서 관리자 권한으로 실행 된 스크립트를 사용했습니다 .

https://pypi.org/project/elevate/


답변

다음 예제는 MARTIN DE LA FUENTE SAAVEDRA의 뛰어난 작업과 수용된 답변을 기반으로합니다. 특히 두 개의 열거 형이 도입되었습니다. 첫 번째는 상승 된 프로그램을 여는 방법을 쉽게 지정할 수 있도록하고 두 번째는 오류를 쉽게 식별해야 할 때 도움이됩니다. 모든 명령 줄 인수를 새 프로세스에 전달하려면 sys.argv[0]함수 호출로 대체해야합니다 subprocess.list2cmdline(sys.argv)..

#! /usr/bin/env python3
import ctypes
import enum
import subprocess
import sys

# Reference:
# msdn.microsoft.com/en-us/library/windows/desktop/bb762153(v=vs.85).aspx


# noinspection SpellCheckingInspection
class SW(enum.IntEnum):
    HIDE = 0
    MAXIMIZE = 3
    MINIMIZE = 6
    RESTORE = 9
    SHOW = 5
    SHOWDEFAULT = 10
    SHOWMAXIMIZED = 3
    SHOWMINIMIZED = 2
    SHOWMINNOACTIVE = 7
    SHOWNA = 8
    SHOWNOACTIVATE = 4
    SHOWNORMAL = 1


class ERROR(enum.IntEnum):
    ZERO = 0
    FILE_NOT_FOUND = 2
    PATH_NOT_FOUND = 3
    BAD_FORMAT = 11
    ACCESS_DENIED = 5
    ASSOC_INCOMPLETE = 27
    DDE_BUSY = 30
    DDE_FAIL = 29
    DDE_TIMEOUT = 28
    DLL_NOT_FOUND = 32
    NO_ASSOC = 31
    OOM = 8
    SHARE = 26


def bootstrap():
    if ctypes.windll.shell32.IsUserAnAdmin():
        main()
    else:
       # noinspection SpellCheckingInspection
        hinstance = ctypes.windll.shell32.ShellExecuteW(
            None,
            'runas',
            sys.executable,
            subprocess.list2cmdline(sys.argv),
            None,
            SW.SHOWNORMAL
        )
        if hinstance <= 32:
            raise RuntimeError(ERROR(hinstance))


def main():
    # Your Code Here
    print(input('Echo: '))


if __name__ == '__main__':
    bootstrap()


답변

이 질문이 몇 년 전에 질문되었다는 것을 인식하면 frmdstryr가 pywinutils 모듈을 사용하여 github 에서 더 우아한 솔루션을 제공한다고 생각합니다 .

발췌 :

import pythoncom
from win32com.shell import shell,shellcon

def copy(src,dst,flags=shellcon.FOF_NOCONFIRMATION):
    """ Copy files using the built in Windows File copy dialog

    Requires absolute paths. Does NOT create root destination folder if it doesn't exist.
    Overwrites and is recursive by default
    @see http://msdn.microsoft.com/en-us/library/bb775799(v=vs.85).aspx for flags available
    """
    # @see IFileOperation
    pfo = pythoncom.CoCreateInstance(shell.CLSID_FileOperation,None,pythoncom.CLSCTX_ALL,shell.IID_IFileOperation)

    # Respond with Yes to All for any dialog
    # @see http://msdn.microsoft.com/en-us/library/bb775799(v=vs.85).aspx
    pfo.SetOperationFlags(flags)

    # Set the destionation folder
    dst = shell.SHCreateItemFromParsingName(dst,None,shell.IID_IShellItem)

    if type(src) not in (tuple,list):
        src = (src,)

    for f in src:
        item = shell.SHCreateItemFromParsingName(f,None,shell.IID_IShellItem)
        pfo.CopyItem(item,dst) # Schedule an operation to be performed

    # @see http://msdn.microsoft.com/en-us/library/bb775780(v=vs.85).aspx
    success = pfo.PerformOperations()

    # @see sdn.microsoft.com/en-us/library/bb775769(v=vs.85).aspx
    aborted = pfo.GetAnyOperationsAborted()
    return success is None and not aborted

이것은 COM 인터페이스를 활용하고 관리자 권한이 필요한 디렉토리로 복사하는 경우 볼 수있는 친숙한 대화 상자 프롬프트를 통해 관리자 권한이 필요함을 자동으로 나타내며 복사 작업 중에 일반적인 파일 진행 대화 상자를 제공합니다.


답변

이것은 귀하의 질문에 완전히 답하지 못할 수도 있지만 상승 된 UAC 권한으로 스크립트를 실행하기 위해 Elevate Command Powertoy를 사용해 볼 수도 있습니다.

http://technet.microsoft.com/en-us/magazine/2008.06.elevation.aspx

그것을 사용하면 ‘elevate python yourscript.py’처럼 보일 것이라고 생각합니다.