Я хочу, чтобы мой командный файл работал только с повышенными правами. Если уровень не повышен, предоставьте пользователю возможность перезапустить пакет с повышенными правами.
Я пишу командный файл для установки системной переменной, копирую два файла в папку Program Files и запускаю установщик драйвера. Если пользователь Windows 7 / Windows Vista ( UAC включен и даже если он является локальным администратором) запускает его без щелчка правой кнопкой мыши и выбора «Запуск от имени администратора», он получит «Отказано в доступе», скопировав два файла и записав системную переменную. ,
Я хотел бы использовать команду для автоматического перезапуска пакета с повышенными правами, если пользователь фактически является администратором. В противном случае, если они не администратор, я хочу сказать им, что им нужны права администратора для запуска командного файла. Я использую xcopy для копирования файлов и REG ADD для записи системной переменной. Я использую эти команды для работы с возможными компьютерами с Windows XP. Я нашел похожие вопросы по этой теме, но ничего, что касалось перезапуска командного файла с повышенными правами.
источник
@powershell Start-Process cmd -Verb runas
. От Powershell просто капля@powershell
. Это запускает cmd с повышенными правами.Ответы:
Вы можете иметь вызов сценария сам с Psexec «s
-h
вариантом запуска повышен.Я не уверен, как вы могли бы определить, работает ли он с повышенными правами или нет ... может быть, повторите попытку с повышенными привилегиями только в случае ошибки «Отказано в доступе»?
Или вы можете просто использовать команды для
xcopy
иreg.exe
всегда запускать ихpsexec -h
, но для конечного пользователя будет раздражать, если ему нужно будет каждый раз вводить свой пароль (или небезопасно, если вы включите пароль в сценарий) ...источник
psexec -h
не работает: «Не удалось установить службу PSEXESVC: доступ запрещен». У вас уже должны быть права администратора для запуска psexec.Существует простой способ без необходимости использования внешнего инструмента - он отлично работает с Windows 7, 8, 8.1 и 10 и обратно совместим (также Windows XP не имеет UAC, поэтому повышение прав не требуется - в этом на всякий случай скрипт просто продолжается).
Проверьте этот код (я был вдохновлен кодом от NIronwolf, размещенным в ветке Batch File - «Доступ запрещен» в Windows 7? ), Но я улучшил его - в моей версии нет никакого каталога, созданного и удаленного для проверьте наличие прав администратора):
Сценарий использует тот факт, что
NET FILE
требует прав администратора и возвращается,errorlevel 1
если у вас его нет. Повышение достигается путем создания сценария, который повторно запускает пакетный файл для получения привилегий. Это заставляет Windows представить диалоговое окно UAC и запрашивает учетную запись администратора и пароль.Я проверил его с Windows 7, 8, 8.1, 10 и с Windows XP - он отлично работает для всех. Преимущество заключается в том, что после начальной точки вы можете разместить все, что требует привилегий системного администратора, например, если вы собираетесь переустановить и повторно запустить службу Windows для целей отладки (предполагается, что mypackage.msi является пакетом установки службы) :
Без этого сценария повышения привилегий UAC трижды запросил бы у вас имя пользователя и пароль администратора - теперь вас спрашивают только один раз в начале и только при необходимости.
Если вашему сценарию просто нужно показать сообщение об ошибке и выйти, если у него нет прав администратора вместо автоматического повышения, это еще проще: это можно сделать, добавив в начало сценария следующее:
Таким образом, пользователь должен щелкнуть правой кнопкой мыши и выбрать «Запуск от имени администратора» . Сценарий будет продолжен после
REM
оператора, если обнаружит права администратора, в противном случае завершится с ошибкой. Если вам не требуетсяPAUSE
, просто удалите его. Важно:NET FILE [...] EXIT /D)
должно быть на одной линии. Это отображается здесь в несколько строк для лучшей читаемости!На некоторых машинах я столкнулся с проблемами, которые уже решены в новой версии выше. Одна из них была связана с другой обработкой двойных кавычек, а другая проблема была связана с тем, что UAC был отключен (установлен на самый низкий уровень) на компьютере с Windows 7, поэтому скрипт вызывает себя снова и снова.
Я исправил это сейчас, убрав кавычки в пути и добавив их позже, и добавил дополнительный параметр, который добавляется при повторном запуске сценария с повышенными правами.
Двойные кавычки удаляются следующим (подробности здесь ):
Затем вы можете получить доступ к пути с помощью
!batchPath!
. Он не содержит двойных кавычек, так что это можно сказать"!batchPath!"
позже в сценарии.Линия
проверяет, был ли сценарий уже вызван сценарием VBScript для повышения прав, что позволяет избежать бесконечных рекурсий. Удаляет параметр используя
shift
.Обновить:
Чтобы избежать регистрации
.vbs
расширения в Windows 10 , я заменил строку"%temp%\OEgetPrivileges.vbs"
на
"%SystemRoot%\System32\WScript.exe" "%temp%\OEgetPrivileges.vbs"
в приведенном выше сценарии; также добавлено
cd /d %~dp0
по предложению Стивена (отдельный ответ) и Томаша Зато (комментарий), чтобы установить каталог скриптов по умолчанию.Теперь скрипт учитывает параметры командной строки, передаваемые ему. Спасибо jxmallet, TanisDLJ и Peter Mortensen за наблюдения и вдохновение.
Согласно подсказке Артжома Б., я проанализировал его и заменил
SHIFT
наSHIFT /1
, который сохраняет имя файла для%0
параметраДобавлено
del "%temp%\OEgetPrivileges_%batchName%.vbs"
в:gotPrivileges
раздел для очистки (как предложено MLT ). Добавлено,%batchName%
чтобы избежать влияния, если вы запускаете разные партии параллельно. Обратите внимание, что вам нужно использовать,for
чтобы иметь возможность воспользоваться расширенными строковыми функциями, такими как%%~nk
, который извлекает только имя файла.Оптимизированная структура скрипта, улучшения (добавлена переменная, на
vbsGetPrivileges
которую теперь ссылаются все, что позволяет легко изменять путь или имя файла, удалять.vbs
файл только в том случае, если требуется повысить пакет)В некоторых случаях для повышения прав потребовался другой синтаксис вызова. Если сценарий не работает, проверьте следующие параметры:
set cmdInvoke=0
set winSysFolder=System32
либо измените 1-й параметр на
set cmdInvoke=1
и проверьте, устраняет ли это уже проблему. Это добавитcmd.exe
к сценарию выполнения возвышения.Или попробуйте изменить второй параметр на
winSysFolder=Sysnative
, это может помочь (но в большинстве случаев не требуется) в 64-битных системах. (ADBailey сообщил об этом). «Sysnative» требуется только для запуска 64-разрядных приложений с 32-разрядного хоста сценария (например, процесс сборки Visual Studio или вызов сценария из другого 32-разрядного приложения).Чтобы было понятнее, как интерпретируются параметры, я теперь отображаю это следующим образом
P1=value1 P2=value2 ... P9=value9
. Это особенно полезно, если вам нужно заключить такие параметры, как пути, в двойные кавычки, например"C:\Program Files"
.Если вы хотите отладить сценарий VBS, вы можете добавить
//X
параметр в WScript.exe в качестве первого параметра, как предлагается здесь (он описан для CScript.exe, но работает и для WScript.exe).Полезные ссылки:
кавычки (") , удар (!) , Каретка (^) , амперсанд (&) , другие специальные символы
источник
Как упоминали jcoder и Matt, PowerShell сделал это легко, и его даже можно было встроить в пакетный скрипт без создания нового скрипта.
Я изменил сценарий Мэтта:
источник
WorkingDirectory
Start-Process
runas
Я использую отличный ответ Мэтта, но я вижу разницу между моими системами Windows 7 и Windows 8 при запуске сценариев с повышенными правами.
Как только сценарий повышен в Windows 8, текущий каталог устанавливается в
C:\Windows\system32
. К счастью, существует простой обходной путь, если изменить текущий каталог на путь к текущему сценарию:Примечание. Используйте,
cd /d
чтобы убедиться, что буква диска также изменилась.Чтобы проверить это, вы можете скопировать следующее в скрипт. Запустите нормально на любой версии, чтобы увидеть тот же результат. Запустите от имени администратора и увидите разницу в Windows 8:
источник
cd %~dp0
что он сохраняет свой текущий путь (я предполагаю, что это работает и в Win7, поэтому можно использовать ту же команду, но только для Win8 +). +1 за это!pushd %~dp0
вместо ... почему? потому чтоpopd
Я делаю это так:
Таким образом, это просто и использовать только команды Windows по умолчанию. Это здорово, если вам нужно распространять пакетный файл.
CD /d %~dp0
Устанавливает текущий каталог в текущий каталог файла (если его нет, независимо от того, на каком диске находится файл, благодаря/d
опции).%~nx0
Возвращает текущее имя файла с расширением (если вы не включите расширение и в папке есть исполняемый файл с тем же именем, он вызовет исполняемый файл).На это сообщение так много ответов, что я даже не знаю, увидят ли мой ответ.
В любом случае, я нахожу этот способ проще, чем другие решения, предложенные в других ответах, надеюсь, это кому-нибудь поможет.
источник
/d
. Спасибо, приятель :) (PS: здесь тоже пианист!)cd
команду в начало (это гарантирует, что путь также доступен для сценария с повышенными правами - в противном случае сценарий с повышенными правами просто запускается из system32). Вы также должны перенаправить команду net на nul, чтобы скрыть вывод:net session >nul 2>&1
У Мэтта отличный ответ, но он убирает все аргументы, переданные сценарию. Вот моя модификация, которая сохраняет аргументы. Я также включил исправление Стивена для проблемы с рабочим каталогом в Windows 8.
источник
ECHO UAC.ShellExecute....
строке,"batchArgs!"
не будет расширять переменную. Использование"!batchArgs!"
. Мои изменения были отклонены, поэтому я комментирую.test.bat "a thing"
или"test script.bat" arg1 arg2
. Все исправлено сейчас.Я использую PowerShell, чтобы перезапустить сценарий с повышенными правами, если это не так. Поместите эти строки в самый верх вашего сценария.
Я скопировал метод 'net name' из ответа @ Matt. Его ответ гораздо лучше задокументирован и содержит сообщения об ошибках и тому подобное. Преимущество этого заключается в том, что PowerShell уже установлен и доступен в Windows 7 и более поздних версиях. Нет временных файлов VBScript (* .vbs), и вам не нужно загружать инструменты.
Этот метод должен работать без какой-либо настройки или настройки, если ваши разрешения на выполнение PowerShell не заблокированы.
источник
/c %~fnx0 %*'
часть, кажется, оставляет каждую часть, кроме первой. Например,test.bat "arg1 arg2 arg3"
только arg1 передается впередnetsh int set int %wifiname% Enable/Disable
.net file 1>nul 2>nul && goto :run || powershell -ex unrestricted -Command "Start-Process -Verb RunAs -FilePath '%comspec%' -ArgumentList '/c ""%~fnx0""""'"
Для некоторых программ установка суперсекретной
__COMPAT_LAYER
переменной средыRunAsInvoker
будет работать. Проверьте это:Хотя, как это, UAC не будет предлагать пользователю продолжить работу без прав администратора.
источник
regedit
. Он просто пропустил UAC.Я вставил это в начале сценария:
источник
cacls
устарела в Windows 7 и более новых версиях Windows.pushd "%CD%"
сохраняет текущий рабочий каталог и изменяет текущий рабочий каталог?Я написал
gsudo
, для окон : что возвышает в текущей консоли (контекста не переключение в новое окно), с кэшем мандатных (уменьшенная UAC всплывающих окон), а также возводит команду PowerShell .sudo
Это позволяет поднять команды, которые требуют прав администратора, или весь пакет, если хотите. Просто подготовьтесь,
gsudo
прежде чем что-либо, что должно работать с повышенными правами.Пример командного файла, который поднимается с помощью gsudo:
РЕДАКТИРОВАТЬ: Новая версия с одним вкладышем, которая работает с любым языком Windows и позволяет избежать проблем с whoami :
Альтернатива (оригинальная версия):
Установка:
choco install gsudo
scoop install gsudo
Смотрите gsudo в действии:
источник
.Net Framework 4.6
там. К счастью,choco install dotnet4.6.2
принес некоторые труднодоступные зависимости. Затемgsudo config Prompt "$p# "
исправленаConHost
ошибка с отображением неверного приглашения (вместо красной резкости используются экранирующие символы). @RockPaperLizardХотя это не относится непосредственно к этому вопросу, потому что он хочет получить некоторую информацию для пользователя, Google привел меня сюда, когда я хотел запустить мой .bat-файл с повышенными правами из планировщика задач.
Простейшим подходом было создать ярлык для файла .bat, потому что ярлык можно установить
Run as administrator
прямо из расширенных свойств.Запустив ярлык из планировщика задач, запустим файл .bat с повышенными правами.
источник
Если вам не нужно передавать аргументы, вот компактный сценарий запроса UAC длиной в одну строку. Это делает то же самое, что и сценарий повышения прав в ответе с верхним голосом, но не передает аргументы, поскольку нет надежного способа сделать это, обрабатывая все возможные комбинации ядовитых символов.
источник
Использование powershell.
Если cmd-файл длинный, я использую первый, требующий повышения прав, а затем вызываю тот, который выполняет реальную работу.
Если скрипт простая команда, все может поместиться в одном файле cmd. Не забудьте указать путь к файлам скрипта.
Шаблон:
Пример 1:
Пример 2:
источник
Попробуй это:
Если вам нужна информация об этом пакетном файле, запустите фрагмент кода HTML / JS / CSS:
источник
Следующее решение является чистым и работает отлично.
Загрузите почтовый файл Elevate по адресу https://www.winability.com/download/Elevate.zip.
Внутри zip вы должны найти два файла: Elevate.exe и Elevate64.exe. (Последняя представляет собой встроенную 64-разрядную компиляцию, если вам требуется, хотя обычная 32-разрядная версия Elevate.exe должна нормально работать как с 32-, так и с 64-разрядными версиями Windows)
Скопируйте файл Elevate.exe в папку, где Windows всегда может его найти (например, C: / Windows). Или вы лучше можете скопировать в ту же папку, где вы планируете сохранить файл bat.
Чтобы использовать его в командном файле, просто добавьте команду, которую вы хотите выполнить от имени администратора, с помощью команды elevate, например:
источник