Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« : 09-02-2012 15:13 » |
|
Вот есть у меня некая папка, в которой лежат некие программы и bat-файлы для всяких операций с этими программами. Операции подразумевают административные права. Поэтому я запускаю bat-файл через проводник. Щёлкаю правой кнопкой на bat-файле, выбираю "Запуск от имени администратора". Получаю такой эффект, что мелькает окошко консоли, что там написано - не вижу, и ничего. Запуск этого же bat-файла без прав администратора приводит к нормальной отработке сценария, но программы, конечно, работают неправильно из-за нехватки прав. Некоторыми экспериментами мне удалось установить, что при обычном запуске bat-файла текущей будет та папке, в которой он лежит, а при "Запуске от имени администратора" текущей будет системная папка Windows/system32. Попытка создать ярлык на bat файл с указанием рабочего каталога ни к чему не приводит - административный запуск игнорирует все настройки. Есть полезный совет в начале bat-файла записывать шаманскую строчку: Осуществляющую смену папки куда нужно. Сама по себе эта строчка работает. Но самое грустное, что bat-файл с правами администратора, похоже, вообще не выполняется. Даже если в нём написать просто одну строчку pause. По этому поводу была некогда тема: https://forum.shelek.ru/index.php/topic,24932.0.htmlНо, вроде бы, всё же о другом. Посему стоит вопрос. P.S. Я знаю, что всякие крутые программисты первым делом скажут "забей на проводник - FAR наше всё" или "из консоли запускай". Эти умные и очевидные мысли меня не интересуют. Поскольку запускать не мне. Мне нужно решение с кликами на нечто в проводнике и никакое другое. Из консоли, запущенной с правами администратора, кстати, всё прекрасно работает, но мне не это нужно.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #1 : 09-02-2012 15:21 » |
|
Попробуй не батничек, а виндовый шел.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #2 : 09-02-2012 15:58 » |
|
RXL, именно в эту сторону я и двигаюсь. В PowerShell есть возможность запуска с правами Run as administrator.
Какие ещё будут предложения?
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #3 : 09-02-2012 16:11 » |
|
CScript?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
zubr
Гость
|
|
« Ответ #4 : 09-02-2012 17:21 » |
|
Странно. У меня прога создавала батник во временной папке и запускала его через runas, все работало.
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #5 : 09-02-2012 18:42 » |
|
RXL, пробовал WSH. У него вообще runas отсутствует в контекстном меню.
zubr, согласен. Местами работает. Но местами почему-то не работает.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #6 : 09-02-2012 19:45 » |
|
А так? > runas /user:ADMIN "cscript.exe script.wsh"
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
v2
Помогающий
Offline
|
|
« Ответ #7 : 09-02-2012 22:01 » |
|
Местами работает. Но местами почему-то не работает. Это как? на разных пк? - может проблема в службе "Сведения о приложении" (AppInfo) На Win7 c рабочей "Служба помощника по совместимости программ" в свойствах exe можно задать запуск от admin Мне нужно решение с кликами на нечто в проводнике и никакое другое. А пароль то будет кто-то вводить? Коли заранее известен user и pass то слепить запускалку на базе CreateProcessWithLogonW Попробуй также runas /env /savecred /user:admin "cmd /c run.cmd"возможно удастся избежать шаманства и повторного ввода админ пароля.
|
|
« Последнее редактирование: 09-02-2012 22:06 от v2 »
|
Записан
|
|
|
|
HandKot
Молодой специалист
Offline
|
|
« Ответ #8 : 10-02-2012 04:10 » |
|
мне кажется проблема в самом батнике при запуске из-под админа поробуйте поставить в начале батнрика такие команды: ЗЫЖ возможно комаеда pause просто не отрабатывает ЗЗЫЖ кстати, какая битность оси? у меня на 32 все нормуль отработало, проверить на 64 смогу только дома
|
|
« Последнее редактирование: 10-02-2012 04:13 от HandKot »
|
Записан
|
I Have Nine Lives You Have One Only THINK!
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #9 : 10-02-2012 07:22 » |
|
Это как? на разных пк? Да. RXL, а где тут проводник? А пользователь ещё должен знать логин и пароль администратора? Да ещё и править bat-ник на свой логин перед запуском? Ибо где-то пользователь "Administrator", а где-то "Администратор", а ещё где-то вообще иероглифами. HandKot, см. топик, 9 абзац сверху, второй после строчки кода. Win7 x64. Но надо на любых.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Basurman
|
|
« Ответ #10 : 10-02-2012 08:12 » |
|
А запускать приложение через execute с ключом wait - какой даст эффект?
|
|
|
Записан
|
|
|
|
v2
Помогающий
Offline
|
|
« Ответ #11 : 10-02-2012 10:11 » |
|
А пользователь ещё должен знать логин и пароль администратора?
А зачем ему тогда запускать то, что такого знания требует? Думаю один exe (который будет запущен от админа с проводника) с кнопками "Действие ААА" и "Действие БББ" ... более интересно для пользователя чем bat's которые необходимо постоянно "дружить" с UAC.
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #12 : 10-02-2012 19:14 » |
|
v2, думать не возбраняется, только попусту всё. Есть setup нормальный, который всё делает и нормально работает, только не хотят, хотят bat-ники или что-то такое. Basurman, естественно, я прописывал длительно исполняющиеся команды вроде которые будут работать несколько секунд. Команды не исполняются. И никакой wait тут ни причём. Что особенно печально, так это идейная нищета. За десяток ответов были перебраны все очевидные идеи, которые мною были переброваны ещё до создания темы. Корень проблемы никто не знает. А PowerShell я пока ещё не опробовал - отвлекли на более приоритетную задачу.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
v2
Помогающий
Offline
|
|
« Ответ #13 : 10-02-2012 23:44 » |
|
Dimka, извини конечно, но как я понял, проявление проблемы таково: На некоторых пк происходит "холостой" запуск bat-файлов от имени администратора без видимых причин (запрос пароля есть и окошек об ошибках нет). При этом exe-файлы от имени администратора запускаются нормально.Проверил везде где смог - подобного поведения не увидел. Возможно что-то в политиках или происки архи антивируса. Также посмотреть на проблемном пк сюда PS. Решение проблемы - лекция о идейной нищете среди нежелающих устанавливать/запускать программы через нормальный setup.
|
reg.gif (32.52 Кб - загружено 10442 раз.)
|
« Последнее редактирование: 11-02-2012 00:08 от v2 »
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #14 : 11-02-2012 06:43 » |
|
В общем, bat-ник не работает при запуске "Run as administrator" в том случае, если в пути к этому батнику у какой-нибудь папки в имени присутствуют, например, скобки. Может и другие хитрые символы есть (особенно с учётом, что bat-ник этот китайцы запускать будут ). А если путь содержит штатные символы (в том числе пробелы, много точек и т.п.), то работает. Если же bat-ник запускать просто (без "Run as administrator"), то работает во всех случаях. Похоже на багу в Win7.
|
|
« Последнее редактирование: 11-02-2012 06:45 от Dimka »
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
v2
Помогающий
Offline
|
|
« Ответ #15 : 11-02-2012 08:36 » |
|
Учитывая, что запуск bat-файла "as admin" происходит через %SystemRoot%\System32\cmd.exe /C "%1" %* а в > cmd /? есть такие строчки Если указаны ключи /C или /K, то остальная часть командной строки после такого ключа обрабатывается как командная строка, а обработка символов кавычек (") ведется по следующим правилам:
1. Если выполняются все перечисленные ниже условия, то символы кавычек в командной строке сохраняются:
- ключ /S отсутствует - есть ровно два символа кавычек - между ними нет других специальных символов, как-то: &<>()@^| - между ними имеются один или несколько пробелов - строка, заключенная в кавычки, является именем исполнимого файла.
2. В противном случае, проверяется первый символ, и если он является символом кавычек, то он удаляется, также удаляется последнийто это узаконенный баг. Обойти можно добавив дополнительную пару кавычек: %SystemRoot%\System32\cmd.exe /C ""%1" " %* Как это сделать без админа - вопрос. PS. В свете того, что задача поставлена именно так (exe as admin ни-ни, а bat-ничек - пожалуйста) - очень похоже на подставу.
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #16 : 11-02-2012 09:17 » |
|
v2, это не может быть узаконенным багом.
Поскольку запуск с правами администратора и без таких прав я, прикинувшись рядовым пользователем, делаю из проводника. И при этом вижу разную реакцию системы.
И не надо мне тут ключи командной строки описывать. Я, как "домохозяйка", про командную строку ничего не знаю и знать не хочу.
Не работало бы во всех случаях - не было бы вопросов.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
v2
Помогающий
Offline
|
|
« Ответ #17 : 11-02-2012 14:57 » |
|
Dimka, это не может быть узаконенным багом называй как хочешь - это корень проблемы с которой ты столкнулся. И при этом вижу разную реакцию системы. Дык, разные действия - разная реакция. Я, как "домохозяйка", про командную строку ничего не знаю и знать не хочу. А проводник то знает, и на самом деле передает в WinApi ShellExecuteEx на повышение привилегий строку %SystemRoot%\System32\cmd.exe /C "%1" %* в которой 'cmd /c' срезает одну пару кавычек с "%1" если в "%1" присутствуют &<>()@^| поэтому моргает окошко cmd.exe, который говорит о том, что путь или команда не распознаны и закрывается. 1. - Исправить можно подкрутив реестр в той ветке, что на рисунке - добавив пару кавычек. 2. - Обойти можно добавив exe (наверное можно и скрипт) следующего содержания program Runa; uses ShellApi; var Info : SHELLEXECUTEINFO; begin Info.nShow := 1; Info.cbSize := sizeof(Info); Info.lpVerb := PChar('runas'); Info.lpFile := PChar('"'+ParamStr(1)+'"'); ShellExecuteEx(@Info); end. а в bat-ники первые 9 строк (и контекстное меню не нужно - click only) @echo off if not exist C:\Users\Public\RERUN ( md C:\Users\Public\RERUN echo ""%0"" Runa.exe ""%0"" timeout /t 1 > nul && rd C:\Users\Public\RERUN goto :EOF ) rd C:\Users\Public\RERUN rem - ^ and next lines work as admin - start compmgmt.msc Усё
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #18 : 11-02-2012 16:08 » |
|
PowerShell - просто прелесть. PS C:\Users\user> C:\Users\user\Documents\test.ps1 Не удается загрузить файл C:\Users\user\Documents\test.ps1, так как выполнение скриптов запрещено для данной системы. Введите "get-help about_signing" для получения дополнительных сведений. At line:0 char:0 Зато я теперь знаю, что скрипт PowerShell непременно надо подписать цифровым сертификатом. И если это скрипт "для себя", то достаточно сертификата локальной машины, а если этот скрипт надо отдавать другим, то непременно нужно иметь хороший сертификат, выдаваемый за денюжку. Это Microsoft'у хорошо удалось послать, это реально power - покруче пешего эротического путешествия. Ждём Win8 с магазином приложений...
|
|
« Последнее редактирование: 11-02-2012 16:09 от Dimka »
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #19 : 12-02-2012 06:28 » |
|
А я, Дим, фигею со времен win95 и никак не могу остановиться. И за это они еще хотят кучу денег...
Ну, а если сделать свой exe для "запуска от"?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #20 : 12-02-2012 08:10 » |
|
RXL, не надо. После перспектив цифрового сертификата они уже согласны либо на setup, либо не будут делать пути с запрещёнными символами.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #21 : 12-02-2012 10:28 » |
|
Не люблю я такие подлости, дело принципа. Результат дела - решение для WSH: <?xml version="1.0" encoding="WINDOWS-1251"?> <package> <job id="Test"> <script language="JScript">
// Текст нужного bat-файла. function getBatFileText(currentDirectory) { var batFileText = ""; // Важны переносы строк в конце команд! batFileText += "cd \"" + currentDirectory + "\" \n" batFileText += "pause \n"; return batFileText; }
// Текст ps1-скрипта для запуска bat-файла с правами администратора. function getPs1Text(batFilePath) { var ps1Text = ""; // Важно отсутствие переносов строк! ps1Text += "$startInfo = New-Object System.Diagnostics.ProcessStartInfo; "; ps1Text += "$startInfo.FileName = 'cmd'; "; ps1Text += "$startInfo.Arguments = '/s /c \"" + batFilePath + "\"'; "; ps1Text += "$startInfo.Verb = 'RunAs'; "; ps1Text += "$process = [System.Diagnostics.Process]::Start($startInfo); "; ps1Text += "$process.WaitForExit(); "; return ps1Text; }
// Узнаём версию операционной системы. // Вещественное число: мажорная часть - целая, минорная - дробная. function getOsVersion(shell) { try { var command = "cmd /c ver"; var process = shell.Exec(command); var version = process.StdOut.ReadAll(); var regexp = /Microsoft Windows \[Version (\d+)\.(\d+)\.(\d*)\]/; var matches = regexp.exec(version); var majorVersion = Number(matches[1]); var minorVersion = Number(matches[2]); while(minorVersion >= 1.0) { minorVersion /= 10.0; } return majorVersion + minorVersion; } catch(error) { return 0.0; } }
// Исполнение bat-файла с правами администратора. function runBatFileWithRunAs(batFilePath, shell) { try { var ps1Text = getPs1Text(batFilePath) var command = "powershell -Command " + ps1Text; var result = shell.Run(command, 0, true); return result == 0; } catch(error) { return false; } }
// Обычное исполнение bat-файла. function runBatFileWithoutRunAs(batFilePath, shell) { var command = "cmd /s /c \"" + batFilePath + "\""; shell.Run(command, 1, true); }
// Поехали. var shell = WScript.CreateObject("WScript.Shell"); var fileSystem = new ActiveXObject("Scripting.FileSystemObject");
var currentDirectory = shell.CurrentDirectory;
// Создаём временный bat-файл. var batFileText = getBatFileText(currentDirectory); var batFilePath = currentDirectory + "\\" + fileSystem.GetTempName() + ".bat"; var batFile = fileSystem.CreateTextFile(batFilePath, true); batFile.Write(batFileText); batFile.Close();
// В зависимости от версии операционной системы выбираем способ исполнения bat-файла. var osVersion = getOsVersion(shell); if(osVersion >= 6.1) { // Windows 7, Windows 2008 Server R2 или более поздние. var result = runBatFileWithRunAs(batFilePath, shell); if(!result) { runBatFileWithoutRunAs(batFilePath, shell); } } else { // Более ранние версии. runBatFileWithoutRunAs(batFilePath, shell); }
// Удаляем временный bat-файл. fileSystem.DeleteFile(batFilePath);
</script> </job> </package>
Суть в том, что у PowerShell есть приём команд через командную строку. Единственное, что меня здесь беспокоит - потенциально большой размер этой строки. Но PowerShell умеет читать команды из стандартного потока (ключ "-Command -"), соответственно, PS1-скрипт можно сбросить в temp-файл и запустить обычный межпроцессный pipe вида type temp.ps1 | powershell -Command -
Однако и без этого на путях вменяемой длины работает.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
|
Bonkler
Новенький
Offline
|
|
« Ответ #23 : 14-12-2013 01:07 » |
|
Лучше всего cd /D %~dp0 Пояснения: (click to show) %~d1 - разворачивает %1 в букву диска D: %~p1 - разворачивает %1 в путь \a\a\ %~dp1 - разворачивает %1 в путь с буквой диска D:\a\a\ %0 - нулевой параметр (имя вызванного бат файла) Параметр /D используется для одновременной смены текущих диска и каталога. Взято с http://www.rsdn.ru/article/winshell/batanyca.xml#EHBAE
|
|
|
Записан
|
|
|
|
|