Saya ingin skrip Python saya menyalin file di Vista. Ketika saya menjalankannya dari cmd.exe
jendela normal , tidak ada kesalahan yang dihasilkan, namun file TIDAK disalin. Jika saya menjalankan cmd.exe
"sebagai administrator" dan kemudian menjalankan skrip saya, itu berfungsi dengan baik.
Ini masuk akal karena Kontrol Akun Pengguna (UAC) biasanya mencegah banyak tindakan sistem file.
Adakah cara saya bisa, dari dalam skrip Python, memanggil permintaan elevasi UAC (dialog yang mengatakan sesuatu seperti "aplikasi ini dan itu memerlukan akses admin, apakah ini OK?")
Jika itu tidak memungkinkan, apakah ada cara agar skrip saya setidaknya dapat mendeteksi bahwa itu tidak dinaikkan sehingga dapat gagal dengan baik?
python
windows
windows-vista
uac
jwfearn
sumber
sumber
Jawaban:
Pada 2017, metode mudah untuk mencapainya adalah sebagai berikut:
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)
Jika Anda menggunakan Python 2.x, maka Anda harus mengganti baris terakhir untuk:
ctypes.windll.shell32.ShellExecuteW(None, u"runas", unicode(sys.executable), unicode(" ".join(sys.argv)), None, 1)
Juga catatan bahwa jika Anda dikonversi Anda skrip python menjadi sebuah file executable (menggunakan alat-alat seperti
py2exe
,cx_freeze
,pyinstaller
) maka Anda harus menggunakansys.argv[1:]
bukannyasys.argv
di parameter keempat.Beberapa keunggulannya di sini adalah:
ctypes
dansys
dari perpustakaan standar.Dokumentasi untuk panggilan ShellExecute yang mendasari ada di sini .
sumber
ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, "", None, 1)
sys.executable
memutuskan hanya interpreter python (misalnyaC:\Python27\Python.exe
) Solusinya adalah menambahkan skrip yang sedang berjalan sebagai argumen (replacting""
).ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, __file__, None, 1)
Perhatikan juga, agar ini berfungsi di python 2.x, semua argumen string harus unicode (yaituu"runas"
,unicode(sys.executable)
danunicode(__file__)
)ShellExecuteW
danShellExecuteA
merupakan panggilan keShellExecute
fungsi di Windows API. Yang pertama mewajibkan string dalam format unicode dan yang terakhir digunakan dengan format ANSISaya butuh sedikit waktu untuk mendapatkan jawaban dguaraglia berfungsi, jadi untuk menghemat waktu orang lain, inilah yang saya lakukan untuk menerapkan gagasan ini:
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)
sumber
subprocess.list2cmdline
dengan benar.Tampaknya tidak ada cara untuk meningkatkan hak istimewa aplikasi untuk sementara waktu bagi Anda untuk melakukan tugas tertentu. Windows perlu mengetahui di awal program apakah aplikasi memerlukan hak istimewa tertentu, dan akan meminta pengguna untuk mengonfirmasi saat aplikasi melakukan tugas apa pun yang memerlukan hak istimewa tersebut. Ada dua cara untuk melakukan ini:
Ini dua artikel menjelaskan lebih detail cara kerja ini.
Apa yang akan saya lakukan, jika Anda tidak ingin menulis pembungkus ctypes yang buruk untuk API CreateElevatedProcess, adalah menggunakan trik ShellExecuteEx yang dijelaskan dalam artikel Proyek Kode (Pywin32 dilengkapi dengan pembungkus untuk ShellExecute). Bagaimana? Sesuatu seperti ini:
Ketika program Anda mulai, ia memeriksa apakah ia memiliki hak istimewa Administrator, jika tidak, ia berjalan sendiri menggunakan trik ShellExecute dan segera keluar, jika ya, ia melakukan tugas yang ada.
Saat Anda menggambarkan program Anda sebagai "skrip", saya rasa itu sudah cukup untuk kebutuhan Anda.
Bersulang.
sumber
runas
menampilkan prompt baru. Dan startfile tidak menerima argumen baris perintah ke$EXECUTABLE.
.chm
file.Hanya menambahkan jawaban ini seandainya orang lain diarahkan ke sini oleh Google Penelusuran seperti saya. Saya menggunakan
elevate
modul dalam skrip Python saya dan skrip dijalankan dengan Hak Istimewa Administrator di Windows 10.https://pypi.org/project/elevate/
sumber
elevate
modul dan saya mendapatkan kesalahan "File tidak dapat diakses oleh sistem", ada ide mengapa hal itu terjadi?Contoh berikut dibuat berdasarkan hasil kerja MARTIN DE LA FUENTE SAAVEDRA yang sangat baik dan jawaban yang diterima. Secara khusus, dua pencacahan diperkenalkan. Yang pertama memungkinkan spesifikasi yang mudah tentang bagaimana program yang ditinggikan akan dibuka, dan yang kedua membantu saat kesalahan perlu diidentifikasi dengan mudah. Perlu diketahui bahwa jika Anda ingin semua argumen baris perintah dilewatkan ke proses baru,
sys.argv[0]
mungkin harus diganti dengan panggilan fungsi: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()
sumber
Menyadari pertanyaan ini telah ditanyakan bertahun-tahun yang lalu, saya pikir solusi yang lebih elegan ditawarkan di github oleh frmdstryr menggunakan modul pywinutils:
Kutipan:
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
Ini menggunakan antarmuka COM dan secara otomatis menunjukkan bahwa hak istimewa admin diperlukan dengan prompt dialog yang sudah dikenal yang akan Anda lihat jika Anda menyalin ke direktori di mana hak istimewa admin diperlukan dan juga menyediakan dialog kemajuan file yang khas selama operasi penyalinan.
sumber
Ini mungkin tidak sepenuhnya menjawab pertanyaan Anda, tetapi Anda juga dapat mencoba menggunakan Powertoy Perintah Elevate untuk menjalankan skrip dengan hak istimewa UAC yang ditinggikan.
http://technet.microsoft.com/en-us/magazine/2008.06.elevation.aspx
Saya pikir jika Anda menggunakannya akan terlihat seperti 'elevate python yourscript.py'
sumber
Anda dapat membuat pintasan di suatu tempat dan sebagai target menggunakan: python yourscript.py lalu di bawah properti dan pilih lanjutan jalankan sebagai administrator.
Saat pengguna menjalankan pintasan, ia akan meminta mereka untuk meninggikan aplikasi.
sumber
Jika skrip Anda selalu membutuhkan hak istimewa Administrator, maka:
runas /user:Administrator "python your_script.py"
sumber
your_script.py
sebagai pengguna Administrator. Pastikan Anda memahami komentar @ Kugel .Variasi pada pekerjaan Jorenko di atas memungkinkan proses yang ditinggikan untuk menggunakan konsol yang sama (tetapi lihat komentar saya di bawah):
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
sumber
Ini sebagian besar merupakan peningkatan ke jawaban Jorenko, yang memungkinkan untuk menggunakan parameter dengan spasi di Windows, tetapi juga harus bekerja cukup baik di Linux :) Selain itu, akan berfungsi dengan cx_freeze atau py2exe karena kami tidak menggunakan
__file__
tetapisys.argv[0]
sebagai dapat dieksekusiimport 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:])
sumber