Ada cara mudah tanpa perlu menggunakan alat eksternal - ini berjalan dengan baik dengan Windows 7, 8, 8.1 dan 10 dan juga kompatibel-mundur (Windows XP tidak memiliki UAC, sehingga peningkatan tidak diperlukan - dalam hal itu huruf skrip hanya melanjutkan).
Lihatlah kode ini (saya terinspirasi oleh kode oleh NIronwolf yang diposting di File Batch utas - "Akses Ditolak" Pada Windows 7? ), Tapi saya telah memperbaikinya - dalam versi saya tidak ada direktori yang dibuat dan dihapus untuk periksa hak administrator):
::::::::::::::::::::::::::::::::::::::::::::
:: Elevate.cmd - Version 4
:: Automatically check & get admin rights
:: see "https://stackoverflow.com/a/12264592/1016343" for description
::::::::::::::::::::::::::::::::::::::::::::
@echo off
CLS
ECHO.
ECHO =============================
ECHO Running Admin shell
ECHO =============================
:init
setlocal DisableDelayedExpansion
set cmdInvoke=1
set winSysFolder=System32
set "batchPath=%~0"
for %%k in (%0) do set batchName=%%~nk
set "vbsGetPrivileges=%temp%\OEgetPriv_%batchName%.vbs"
setlocal EnableDelayedExpansion
:checkPrivileges
NET FILE 1>NUL 2>NUL
if '%errorlevel%' == '0' ( goto gotPrivileges ) else ( goto getPrivileges )
:getPrivileges
if '%1'=='ELEV' (echo ELEV & shift /1 & goto gotPrivileges)
ECHO.
ECHO **************************************
ECHO Invoking UAC for Privilege Escalation
ECHO **************************************
ECHO Set UAC = CreateObject^("Shell.Application"^) > "%vbsGetPrivileges%"
ECHO args = "ELEV " >> "%vbsGetPrivileges%"
ECHO For Each strArg in WScript.Arguments >> "%vbsGetPrivileges%"
ECHO args = args ^& strArg ^& " " >> "%vbsGetPrivileges%"
ECHO Next >> "%vbsGetPrivileges%"
if '%cmdInvoke%'=='1' goto InvokeCmd
ECHO UAC.ShellExecute "!batchPath!", args, "", "runas", 1 >> "%vbsGetPrivileges%"
goto ExecElevation
:InvokeCmd
ECHO args = "/c """ + "!batchPath!" + """ " + args >> "%vbsGetPrivileges%"
ECHO UAC.ShellExecute "%SystemRoot%\%winSysFolder%\cmd.exe", args, "", "runas", 1 >> "%vbsGetPrivileges%"
:ExecElevation
"%SystemRoot%\%winSysFolder%\WScript.exe" "%vbsGetPrivileges%" %*
exit /B
:gotPrivileges
setlocal & cd /d %~dp0
if '%1'=='ELEV' (del "%vbsGetPrivileges%" 1>nul 2>nul & shift /1)
::::::::::::::::::::::::::::
::START
::::::::::::::::::::::::::::
REM Run shell as admin (example) - put here code as you like
ECHO %batchName% Arguments: P1=%1 P2=%2 P3=%3 P4=%4 P5=%5 P6=%6 P7=%7 P8=%8 P9=%9
cmd /k
Script mengambil keuntungan dari fakta yang NET FILE
membutuhkan hak administrator dan kembali errorlevel 1
jika Anda tidak memilikinya. Ketinggian dicapai dengan membuat skrip yang meluncurkan kembali file batch untuk mendapatkan hak istimewa. Ini menyebabkan Windows menyajikan dialog UAC dan meminta Anda untuk akun administrator dan kata sandi.
Saya telah mengujinya dengan Windows 7, 8, 8.1, 10 dan dengan Windows XP - ini berfungsi dengan baik untuk semua. Keuntungannya adalah, setelah titik awal Anda dapat menempatkan apa pun yang memerlukan hak administrator sistem, misalnya, jika Anda ingin menginstal ulang dan menjalankan kembali layanan Windows untuk keperluan debugging (diasumsikan bahwa mypackage.msi adalah paket pemasang layanan) :
msiexec /passive /x mypackage.msi
msiexec /passive /i mypackage.msi
net start myservice
Tanpa skrip pengangkat hak istimewa ini, UAC akan meminta Anda tiga kali untuk pengguna dan kata sandi administrator Anda - sekarang Anda hanya diminta satu kali di awal, dan hanya jika diperlukan.
Jika skrip Anda hanya perlu menampilkan pesan kesalahan dan keluar jika tidak ada hak administrator, bukan pengangkatan otomatis, ini bahkan lebih sederhana: Anda dapat mencapainya dengan menambahkan yang berikut di awal skrip Anda:
@ECHO OFF & CLS & ECHO.
NET FILE 1>NUL 2>NUL & IF ERRORLEVEL 1 (ECHO You must right-click and select &
ECHO "RUN AS ADMINISTRATOR" to run this batch. Exiting... & ECHO. &
PAUSE & EXIT /D)
REM ... proceed here with admin rights ...
Dengan cara ini, pengguna harus mengklik kanan dan memilih "Run as administrator" . Script akan dilanjutkan setelah REM
pernyataan jika mendeteksi hak administrator, jika tidak keluar dengan kesalahan. Jika Anda tidak memerlukannya PAUSE
, hapus saja.
Penting: NET FILE [...] EXIT /D)
harus di jalur yang sama. Ini ditampilkan di sini dalam beberapa baris untuk keterbacaan yang lebih baik!
Pada beberapa mesin, saya mengalami masalah, yang sudah diselesaikan pada versi baru di atas. Salah satunya adalah karena penanganan penawaran ganda yang berbeda, dan masalah lainnya adalah karena fakta bahwa UAC dinonaktifkan (diatur ke level terendah) pada mesin Windows 7, karenanya skrip menyebut dirinya berulang kali.
Saya telah memperbaikinya sekarang dengan menghilangkan tanda kutip di jalur dan menambahkannya kembali nanti, dan saya telah menambahkan parameter tambahan yang ditambahkan ketika skrip diluncurkan kembali dengan hak yang ditingkatkan.
Kutipan ganda dihapus oleh yang berikut (detail ada di sini ):
setlocal DisableDelayedExpansion
set "batchPath=%~0"
setlocal EnableDelayedExpansion
Anda kemudian dapat mengakses jalur dengan menggunakan !batchPath!
. Itu tidak mengandung tanda kutip ganda, jadi aman untuk mengatakannya "!batchPath!"
nanti dalam skrip.
Garis
if '%1'=='ELEV' (shift & goto gotPrivileges)
memeriksa apakah skrip telah dipanggil oleh skrip VBScript untuk meningkatkan hak, sehingga menghindari rekursi yang tak ada habisnya. Ini menghapus parameter menggunakan shift
.
Memperbarui:
Untuk menghindari harus mendaftarkan .vbs
ekstensi di Windows 10 , saya telah mengganti baris
"%temp%\OEgetPrivileges.vbs"
dengan
"%SystemRoot%\System32\WScript.exe" "%temp%\OEgetPrivileges.vbs"
skrip di atas; juga ditambahkan cd /d %~dp0
seperti yang disarankan oleh Stephen (jawaban terpisah) dan oleh Tomáš Zato (komentar) untuk menetapkan direktori skrip sebagai default.
Sekarang skrip menghormati parameter baris perintah yang diteruskan ke sana. Berkat jxmallet, TanisDLJ dan Peter Mortensen untuk pengamatan dan inspirasi.
Menurut petunjuk Artjom B., saya menganalisanya dan telah menggantinya SHIFT
dengan SHIFT /1
, yang mempertahankan nama file untuk %0
parameter
Ditambahkan del "%temp%\OEgetPrivileges_%batchName%.vbs"
ke :gotPrivileges
bagian untuk membersihkan (sebagai MLT disarankan). Ditambahkan %batchName%
untuk menghindari dampak jika Anda menjalankan batch berbeda secara paralel. Perhatikan bahwa Anda perlu menggunakan for
untuk dapat memanfaatkan fungsi string lanjutan, seperti %%~nk
, yang mengekstrak hanya nama file.
Struktur skrip yang dioptimalkan, perbaikan (variabel tambahan vbsGetPrivileges
yang sekarang direferensikan di mana-mana memungkinkan untuk mengubah jalur atau nama file dengan mudah, hanya menghapus .vbs
file jika batch perlu ditingkatkan)
Dalam beberapa kasus, sintaks panggilan yang berbeda diperlukan untuk elevasi. Jika skrip tidak berfungsi, periksa parameter berikut:
set cmdInvoke=0
set winSysFolder=System32
Ubah parameter 1 ke set cmdInvoke=1
dan periksa apakah sudah memperbaiki masalah. Ini akan menambah cmd.exe
skrip yang melakukan elevasi.
Atau coba ubah parameter ke-2 winSysFolder=Sysnative
, ini mungkin membantu (tetapi dalam banyak kasus tidak diperlukan) pada sistem 64 bit. (ADBailey telah melaporkan ini). "Sysnative" hanya diperlukan untuk meluncurkan aplikasi 64-bit dari host skrip 32-bit (mis. Proses pembuatan Visual Studio, atau permintaan skrip dari aplikasi 32-bit lainnya).
Untuk membuatnya lebih jelas bagaimana parameter ditafsirkan, saya menampilkannya sekarang seperti P1=value1 P2=value2 ... P9=value9
. Ini sangat berguna jika Anda perlu menyertakan parameter seperti jalur dalam tanda kutip ganda, misalnya "C:\Program Files"
.
Jika Anda ingin men-debug skrip VBS, Anda dapat menambahkan //X
parameter ke WScript.exe sebagai parameter pertama, seperti yang disarankan di sini (dijelaskan untuk CScript.exe, tetapi juga berfungsi untuk WScript.exe).
Tautan yang bermanfaat: