Python 스크립트 내에서 UAC 권한 상승을 요청하시겠습니까?
나는 내 파이썬 스크립트가 비스타에서 파일을 복사하기를 원합니다.정상적인 상태에서 실행할 수 있습니다.cmd.exe
창에는 오류가 생성되지 않지만 파일은 복사되지 않습니다.가 가내뛰면을 하면,cmd.exe
"관리자로서" 스크립트를 실행하면 잘 작동합니다.
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)
("python"과 같은 ) 하십시오.py2exe
,cx_freeze
,pyinstaller
그러면 당신은 사용해야 합니다.sys.argv[1:]
에 sys.argv
네 번째 파라미터에 있습니다.
여기서 얻을 수 있는 이점은 다음과 같습니다.
- 외부 라이브러리가 필요하지 않습니다.사용만 가능합니다.
ctypes
그리고.sys
표준 도서관에서. - 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에 알리는 매니페스트 파일 작성
- 다른 프로그램 내부에서 상승된 권한으로 응용 프로그램 실행
이 두 개의 기사는 이것이 어떻게 작동하는지 훨씬 더 자세히 설명합니다.
CreateElevatedProcess API에 대해 불쾌한 ctypes 래퍼를 작성하고 싶지 않다면 코드 프로젝트 기사에 설명된 ShellExecute 트릭을 사용합니다(Pywin32는 ShellExecute용 래퍼와 함께 제공됨).어떻게요? 이런 거요.
프로그램이 시작되면 관리자 권한이 있는지 확인하고, 프로그램이 실행되지 않으면 ShellExecute 트릭을 사용하여 자동으로 실행되고, 실행되면 즉시 종료되며, 실행 중인 작업을 수행합니다.
당신이 당신의 프로그램을 "스크립트"라고 묘사한 것처럼, 저는 그것이 당신의 필요에 충분하다고 생각합니다.
건배.
다른 사람들이 저처럼 구글 검색에 의해 여기에 지시될 경우를 대비하여 이 답변을 추가하는 것입니다.사용했습니다.elevate
모듈과 Windows 10에서 관리자 권한으로 실행되는 스크립트가 있습니다.
https://pypi.org/project/elevate/
다음 예시는 MARTIN DE LA FUENTE SAVEDRA의 우수한 작업과 수용된 답변을 기반으로 합니다.특히, 두 개의 열거형이 소개됩니다.첫 번째는 상승된 프로그램을 여는 방법을 쉽게 지정할 수 있도록 하고, 두 번째는 오류를 쉽게 식별해야 할 때 도움이 됩니다.모든 명령줄 인수를 새 프로세스에 전달하려면 다음을 수행하십시오.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()
이 질문이 수년 전에 제기된 것임을 인식하고, 저는 frmdstrryr이 모듈 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 권한으로 스크립트를 실행하기 위해 상승 명령 파워토이를 사용해 볼 수도 있습니다.
http://technet.microsoft.com/en-us/magazine/2008.06.elevation.aspx
만약 당신이 그것을 사용한다면 그것은 'python 당신의 스크립트를 상승시키는' 것처럼 보일 것이라고 생각합니다.파이'
어딘가에 바로 가기를 만들 수 있고 대상으로 python yourscript.py 을 사용한 다음 속성 및 고급 선택에서 관리자로 실행을 선택할 수 있습니다.
사용자가 바로 가기를 실행하면 응용프로그램을 올리도록 요청합니다.
위의 Jorenko 작업에 대한 변형을 통해 상승된 프로세스에서 동일한 콘솔을 사용할 수 있습니다(아래 설명 참조).
def spawn_as_administrator():
""" Spawn ourself with administrator rights and wait for new process to exit
Make the new process use the same console as the old one.
Raise Exception() if we could not get a handle for the new re-run the process
Raise pywintypes.error() if we could not re-spawn
Return the exit code of the new process,
or return None if already running the second admin process. """
#pylint: disable=no-name-in-module,import-error
import win32event, win32api, win32process
import win32com.shell.shell as shell
if '--admin' in sys.argv:
return None
script = os.path.abspath(sys.argv[0])
params = ' '.join([script] + sys.argv[1:] + ['--admin'])
SEE_MASK_NO_CONSOLE = 0x00008000
SEE_MASK_NOCLOSE_PROCESS = 0x00000040
process = shell.ShellExecuteEx(lpVerb='runas', lpFile=sys.executable, lpParameters=params, fMask=SEE_MASK_NO_CONSOLE|SEE_MASK_NOCLOSE_PROCESS)
hProcess = process['hProcess']
if not hProcess:
raise Exception("Could not identify administrator process to install drivers")
# It is necessary to wait for the elevated process or else
# stdin lines are shared between 2 processes: they get one line each
INFINITE = -1
win32event.WaitForSingleObject(hProcess, INFINITE)
exitcode = win32process.GetExitCodeProcess(hProcess)
win32api.CloseHandle(hProcess)
return exitcode
이것은 대부분 Windows에서 공백이 있는 매개 변수를 사용할 수 있는 Jorenko의 답변을 업그레이드한 것이지만 Linux에서도 상당히 잘 작동할 것입니다 :) 또한 사용하지 않기 때문에 cx_freeze 또는 py2exe와 함께 작동할 것입니다.__file__
그렇지만sys.argv[0]
실행할 수 있는 대로
[EDIT] 고지 사항:이 게시물의 코드는 오래되었습니다.권한 상승 코드를 파이썬 패키지로 게시했습니다.설치 대상pip install command_runner
용도:
from command_runner.elevate import elevate
def main():
"""My main function that should be elevated"""
print("Who's the administrator, now ?")
if __name__ == '__main__':
elevate(main)
[/편집]
import sys,ctypes,platform
def is_admin():
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
raise False
if __name__ == '__main__':
if platform.system() == "Windows":
if is_admin():
main(sys.argv[1:])
else:
# Re-run the program with admin rights, don't use __file__ since py2exe won't know about it
# Use sys.argv[0] as script path and sys.argv[1:] as arguments, join them as lpstr, quoting each parameter or spaces will divide parameters
lpParameters = ""
# Litteraly quote all parameters which get unquoted when passed to python
for i, item in enumerate(sys.argv[0:]):
lpParameters += '"' + item + '" '
try:
ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, lpParameters , None, 1)
except:
sys.exit(1)
else:
main(sys.argv[1:])
한 줄기의 경우, UAC가 필요한 곳에 코드를 놓습니다.
UAC 요청, 실패할 경우 계속 실행:
import ctypes, sys
ctypes.windll.shell32.IsUserAnAdmin() or ctypes.windll.shell32.ShellExecuteW(
None, "runas", sys.executable, " ".join(sys.argv), None, 1) > 32 and exit()
UAC 요청, 실패할 경우 종료:
import ctypes, sys
ctypes.windll.shell32.IsUserAnAdmin() or (ctypes.windll.shell32.ShellExecuteW(
None, "runas", sys.executable, " ".join(sys.argv), None, 1) > 32, exit())
함수 스타일:
# Created by BaiJiFeiLong@gmail.com at 2022/6/24
import ctypes
import sys
def request_uac_or_skip():
ctypes.windll.shell32.IsUserAnAdmin() or ctypes.windll.shell32.ShellExecuteW(
None, "runas", sys.executable, " ".join(sys.argv), None, 1) > 32 and sys.exit()
def request_uac_or_exit():
ctypes.windll.shell32.IsUserAnAdmin() or (ctypes.windll.shell32.ShellExecuteW(
None, "runas", sys.executable, " ".join(sys.argv), None, 1) > 32, sys.exit())
스크립트에 항상 관리자 권한이 필요한 경우:
runas /user:Administrator "python your_script.py"
언급URL : https://stackoverflow.com/questions/130763/request-uac-elevation-from-within-a-python-script
'source' 카테고리의 다른 글
컨테이너 뷰 내에서 여러 뷰의 간격을 균등하게 지정합니다. (0) | 2023.04.27 |
---|---|
튜플 투 딕셔너리 목록 (0) | 2023.04.27 |
엔티티 프레임워크의 모든 엔티티 삭제 (0) | 2023.04.27 |
대규모 테이블에서 SQL Server 쿼리 성능 향상 (0) | 2023.04.27 |
Eclipse용 플러그인을 작성하는 방법은 무엇입니까? (0) | 2023.04.27 |