2016-12-16 8 views
0

В настоящее время я пытаюсь написать пакетные файлы, которые автоматически создают структуру папок, включая ярлыки. Для создания ярлыков я использую «mklink», для которого требуются права администратора. Я использовал код на этом сайте
(http://winaero.com/blog/how-to-auto-elevate-a-batch-file-to-run-it-as-administrator/) для предоставления мне этих прав автоматически.UNC-пути как текущие каталоги в пакетном файле, где запрашиваются права администратора

Однако код ниже работает отлично, когда я запускаю его локально на своей машине, но когда я помещаю его на место сервера, где он предназначен для работы, командная строка немедленно закрывается после того, как я сделал свое да/нет выбор в диалоговом окне для прав администратора. У меня нет кода ошибки, но я выяснил, что он, вероятно, имеет отношение к , что «CMD НЕ ПОДДЕРЖИВАЕТ ПУТЬ UNC КАК ТЕКУЩИЕ ДИРЕКТОРИИ». Я попытался использовать pushd и другие вещи, которые я нашел на форумах, чтобы решить такую ​​проблему, но теперь я начал бежать от идей.

Есть ли у кого-нибудь, как это решить? Спасибо заранее!

chcp 1252 

:::::::::::::::::::::::::::::::::::::::::::: 
:: Run as admin 
:::::::::::::::::::::::::::::::::::::::::::: 
@echo off 
CLS 
ECHO. 
ECHO ============================= 
ECHO The name of the main folder?  
ECHO ============================= 

:init 
setlocal DisableDelayedExpansion 
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%" 
ECHO UAC.ShellExecute "!batchPath!", args, "", "runas", 1 >>  "%vbsGetPrivileges%" 
"%SystemRoot%\System32\WScript.exe" "%vbsGetPrivileges%" %* 
exit /B 

:gotPrivileges 
setlocal & pushd . 
cd /d %~dp0 
if '%1'=='ELEV' (del "%vbsGetPrivileges%" 1>nul 2>nul & shift /1) 

:::::::::::::::::::::::::::: 
::START 
:::::::::::::::::::::::::::: 

::Dialogwindow. 
@echo off 
title message 

echo Skriv nedan^^! 
set/p "Projektnamn=>" 

:: Creates the folder structure 
md "%~dp0"%Projektnamn% 

md "%~dp0""%Projektnamn%"/"1. Projektpärm" 
md "%~dp0""%Projektnamn%"/"1. Projektpärm"/"1. Tekniska specifikationer" 
md "%~dp0""%Projektnamn%"/"1. Projektpärm"/"2. ÄTA,Beställning & Fakturering" 
md "%~dp0""%Projektnamn%"/"1. Projektpärm"/"3. Tidplan" 
md "%~dp0""%Projektnamn%"/"1. Projektpärm"/"4. Projektmöten" 
md "%~dp0""%Projektnamn%"/"1. Projektpärm"/"5. Dagbok" 
md "%~dp0""%Projektnamn%"/"1. Projektpärm"/"6. Kvalitet" 
:: Genväg enlinjeschema, se kod för genväg 

md "%~dp0""%Projektnamn%"/"2. Kretsschema" 
md "%~dp0""%Projektnamn%"/"2. Kretsschema"/"1. Konstruktionsunderlag från kund" 

md "%~dp0""%Projektnamn%"/"3. Stationsdokumentation" 
md "%~dp0""%Projektnamn%"/"3. Stationsdokumentation"/"1. Enlinjeschema" 
md "%~dp0""%Projektnamn%"/"3. Stationsdokumentation"/"2. Blockschema" 
md "%~dp0""%Projektnamn%"/"3. Stationsdokumentation"/"3. Förreglingsschema" 
md "%~dp0""%Projektnamn%"/"3. Stationsdokumentation"/"4. Ritningsnummer" 

md "%~dp0""%Projektnamn%"/"4. Skåpsdokumentation" 
md "%~dp0""%Projektnamn%"/"4. Skåpsdokumentation"/"1. Skåpslayout" 
md "%~dp0""%Projektnamn%"/"4. Skåpsdokumentation"/"2. Apparatlista" 
md "%~dp0""%Projektnamn%"/"4. Skåpsdokumentation"/"3. Förbindningstabell" 
md "%~dp0""%Projektnamn%"/"4. Skåpsdokumentation"/"4. Skyltlista & Etiketter" 

:: Skapar RELATIVA Genvägarna 
mklink /D "%~dp0%Projektnamn%\1. Projektpärm\7. Enlinjeschema" "..\3.  Stationsdokumentation\1. Enlinjeschema" 
mklink /D "%~dp0%Projektnamn%\1. Projektpärm\8. Blockschema" "..\3. Stationsdokumentation\2. Blockschema" 
mklink /D "%~dp0%Projektnamn%\1. Projektpärm\9. Förreglingsschema" "..\3. Stationsdokumentation\3. Förreglingsschema" 
mklink /D "%~dp0%Projektnamn%\1. Projektpärm\10. Skåpslayout" "..\4. Skåpsdokumentation\1. Skåpslayout" 

pause 
+1

Это не то, что я называю [минимальным, полным и проверяемым примером] (http://stackoverflow.com/help/mcve). В любом случае, вы, вероятно, ищете ['pushd'] (http://ss64.com/nt/pushd.html) и [' popd'] (http://ss64.com/nt/popd.html) .. . – aschipfl

+0

Что произойдет, если вы откроете cmd как администратор и запустите пакет из общего ресурса? По умолчанию локально распределенные общие ресурсы недоступны в режиме UAC – LotPings

+0

@Mofi Когда командный файл хранится на моем диске C: Я запускаю командный файл, это приведет меня в окно диалога, где я получу права администратора, после чего я может написать имя моей основной папки, а командный файл создает структуру папок, включая ярлыки. Когда я, с другой стороны, помещаю файл на \\ server \ share \ Batch.bat и нажимаю на пакетный файл (так я намереваюсь его запустить), командная строка немедленно закрывается после диалогового окна, и это не пусть мой тип имя моей основной папки. Я хочу, чтобы командный файл находился только на сервере. Разве это невозможно? – user7305472

ответ

0

Здесь пакетный код переписан для выполнения этой задачи и прокомментирован полностью:

:::::::::::::::::::::::::::::::::::::::::::: 
:: Run as administrator 
:::::::::::::::::::::::::::::::::::::::::::: 
@echo off 
setlocal EnableExtensions 
chcp 1252 >nul 
cls 

rem Define as target folder path the folder path of this batch file. This can 
rem can be a folder on a local drive or on a network drive or even a UNC path. 

rem It is also possible to use %CD% instead of %~dp0 to specify as target 
rem folder path the current folder on starting this batch file which can 
rem be different to batch file folder. But please note that Windows does 
rem not support by default running a batch script from a network share 
rem using UNC path. This is indicated by Windows with the message: 

rem '\\ComputerName\ShareName\FolderName' 
rem CMD.EXE was started with the above path as the current directory. 
rem UNC paths are not supported. Defaulting to Windows directory. 

rem So on using %CD% and running this batch file from a network share using 
rem UNC path the target folder would be %SystemRoot% which is usually the 
rem folder C:\Windows which is most likely not wanted as target folder path. 

set "TargetFolder=%~dp0" 
set "vbsGetPrivileges=%TEMP%\OEgetPriv_%~n0.vbs" 

rem The console application NET with parameter FILE can be executed 
rem successfully only if the account used for running this batch file 
rem has local administrator privileges. See the Microsoft TechNet article 
rem https://technet.microsoft.com/en-us/library/bb490702.aspx for details 
rem about NET FILE. 

rem The output written to handle STDOUT on successful execution is redirected 
rem to device NUL to suppress it. The exit code of NET assigned to ERRORLEVEL 
rem is in this case 0 indicating a successful execution. 

rem But on a failed execution because of not having administrator 
rem privileges NET outputs to handle STDERR the two error messages 
rem "System error 5 has occurred." and "Access is denied." which 
rem are redirected from handle STDERR to device NUL to suppress them. 
rem And exit/return code of NET is 1 indicating a failed execution. 

rem Read https://technet.microsoft.com/en-us/library/bb490982.aspx 
rem for details about using command redirection operators. 

%SystemRoot%\System32\net.exe FILE >nul 2>nul 
if not errorlevel 1 goto RunMainCode 

if "%~1"=="ELEV" (

    rem This condition is just for safety. If the batch file was started 
    rem already a second time with ELEV as first parameter and execution 
    rem of NET FILE failed nevertheless because of missing permissions, 
    rem the batch file outputs an error message, waits for any key press 
    rem by the user to make sure that the user had the chance to read the 
    rem error message and then exits the batch file processing without 
    rem doing anything at all. 

    echo %~nx0 should run already with elevated privileges, but it isn't. 
    echo/ 
    echo Press any key to exit %~nx0 without doing anything ... 
    pause >nul 
    goto :EOF 
) 

rem This batch file can be started without any parameter result in %* being 
rem expanded to nothing which results in environment variable BatchArgs being 
rem deleted if already existing or with project name as parameter which must 
rem be enclosed in double quotes in case of containing 1 or more spaces. 

rem As the batch file needs to be executed once again in a separate command 
rem process running as local administrator for full access at least on local 
rem machine it is necessary to prepare the parameters/arguments list. Each 
rem double quote in the arguments list must be doubled to be correct escaped 
rem in the VBScript file. 

rem This is necessary as otherwise running this batch file with "My Project" 
rem as first parameter would result in execution of the batch file by 
rem the Windows Script Host as My Project without the double quotes as 
rem arguments for the batch file and therefore the first parameter is on 
rem elevated execution "My" instead of "My Project" as it was initially. 

rem Many "run as administrator" solutions which can be found in world wide web 
rem don't handle parameter strings correct which are enclosed in double quotes 
rem because the parameter string has 1 or more spaces or other critical 
rem characters requiring enclosing the parameter string in double quotes. 

set "BatchArgs=%*" 
setlocal EnableDelayedExpansion 
if defined BatchArgs set "BatchArgs= !BatchArgs:"=""!" 

rem Everything output by the ECHO command lines within the next command block 
rem is redirected into the VBScript file created in the folder for temporary 
rem files of current user with name of batch file in VBScript file name. This 
rem makes it possible that multiple batch files with different names can run 
rem at the same time using same code for creating a VBScript file to run the 
rem batch file once again as administrator with elevated privileges. 

rem For details on ShellExecute parameters see the Microsoft MSDN article 
rem https://msdn.microsoft.com/en-us/library/windows/desktop/gg537745.aspx 

rem The tricky part is quoting the arguments list correct which should be 
rem finally passed to cmd.exe executed from the VBScript. The command process 
rem running the batch file with elevated privileges of local administrator 
rem should automatically close after execution of batch file finished which 
rem is the reason for first argument /C. 

rem The second argument is the command to execute by `cmd.exe` which is 
rem the batch file name with complete path which must be enclosed in double 
rem quotes for safety in case of batch file name or path contains 1 or more 
rem spaces. But additionally the batch file itself must be started with at 
rem least 2 more arguments. 

rem The first argument for the batch file is ELEV which is used as indication 
rem to detected if this batch file is already started a second time with via 
rem the VBScript using local built-in administrator account. 

rem The second argument for the batch file is the target folder path which is 
rem either the batch file folder or the current folder on starting this batch 
rem file the first time depending or whatever is specified above as target 
rem folder path. 

rem And last all parameters passed to this batch file on initial run should 
rem be also passed to second execution of this batch file under the different 
rem environment of local built-in administrator account. 

rem This nesting of batch file arguments in command processor arguments written 
rem into a VBScript file which requires additionally escaping each double quote 
rem within a string with one more double quote results in a strange syntax for 
rem the line to write into the VBScript file. 

(
    echo Set UAC = CreateObject^("Shell.Application"^) 
    echo UAC.ShellExecute "%SystemRoot%\System32\cmd.exe", "/C """"%~f0"" ELEV ""!TargetFolder!""!BatchArgs!""", , "runas", 1 
)>"%vbsGetPrivileges%" 
endlocal 

rem Now the created VBScript file can be executed with Windows Script Host. 
rem Then the VBScript file can be deleted as not longer needed and processing 
rem of this batch file under current user account ends resulting in returning 
rem to command process which results in closing the console window if not 
rem executed by cmd.exe started with option /K to keep the console window 
rem open like on opening a command prompt window and running this batch 
rem file from within the command prompt window. 

%SystemRoot%\System32\wscript.exe "%vbsGetPrivileges%" 
del "%vbsGetPrivileges%" 
goto :EOF 


rem Here starts the main code of the batch file which needs to be 
rem executed with elevated privileges of a local administrator. 

rem First is checked if the first parameter of the batch file is ELEV 
rem which indicates that this batch file was started a second time 
rem using local administrator account. 

:RunMainCode 
if "%~1"=="ELEV" (

    rem In this case the second argument is the target folder passed from 
    rem initial run to this second run of the batch file. The current 
    rem directory is now not anymore the initial current directory, but 
    rem %SystemRoot%\System32 has set by Windows on starting a command 
    rem process using RunAs and administrator account. This must be taken 
    rem into account on further batch file processing. 

    rem For this batch file it does not matter what is the current directory 
    rem as it is written to work with the target folder defined on starting 
    rem the batch file (initially). So there is no need to use CD /D "%~dp0" 
    rem or PUSHD "%~dp0" as many "run as administrator" solutions use to 
    rem change the current directory to directory of the batch file. There 
    rem is also no need for CD /D "%~2" or PUSHD "%~2" here. 

    rem The two additionally added arguments ELEV and the target folder 
    rem path are removed from the arguments lists by using twice the 
    rem command SHIFT to restore the initial arguments list. 

    set "TargetFolder=%~2" 
    shift /1 
    shift /1 
) 

setlocal EnableDelayedExpansion 

rem Now it is checked if the last character of the target folder path is 
rem a backslash character which is not the case when using %CD% and the 
rem current directory on starting the batch file is not the root directory 
rem of a drive. In this case append a backslash to target folder path. 

if not "%TargetFolder:~-1%" == "\" set "TargetFolder=%TargetFolder%\" 

rem If this batch file was started (initially) without any parameter string, 
rem prompt the batch file user for the project folder name and use the input 
rem string without checking if being valid as folder name. Otherwise interpret 
rem the first parameter string as project folder name. 

if "%~1" == "" (
    echo/ 
    echo ============================ 
    echo The name of the main folder? 
    echo ============================ 
    echo/ 
    set "Projektnamn=:invalid:" 
    set /P "Projektnamn=>" 
    echo/ 
) else (
    set "Projektnamn=%~1" 
) 

rem Create the main project folder and check if this was successful. On an 
rem error like such a folder exists already, or the user has no permissions 
rem to create this folder, or the folder name contains characters being not 
rem valid for a folder name like the default string :invalid: used in case 
rem of user just hits RETURN or ENTER instead of entering a folder name, 
rem the command MD outputs an appropriate error message. The batch file 
rem halts in this case the batch file execution until the user hits any 
rem key before exiting without doing anything at all. 

md "%TargetFolder%!Projektnamn!" 
if errorlevel 1 (
    echo/ 
    echo Press any key to exit %~nx0 without doing anything ... 
    pause >nul 
    endlocal 
    goto :EOF 
) 

rem Create the folder structure and the symbolic directory links. 
rem The command MD with command extensions enabled as done at top of this 
rem batch file creates automatically the entire directory tree if necessary. 

md "%TargetFolder%!Projektnamn!\1. Projektpärm\1. Tekniska specifikationer" 
md "%TargetFolder%!Projektnamn!\1. Projektpärm\2. ÄTA,Beställning & Fakturering" 
md "%TargetFolder%!Projektnamn!\1. Projektpärm\3. Tidplan" 
md "%TargetFolder%!Projektnamn!\1. Projektpärm\4. Projektmöten" 
md "%TargetFolder%!Projektnamn!\1. Projektpärm\5. Dagbok" 
md "%TargetFolder%!Projektnamn!\1. Projektpärm\6. Kvalitet" 

:: Genväg enlinjeschema, se kod för genväg 
md "%TargetFolder%!Projektnamn!\2. Kretsschema\1. Konstruktionsunderlag från kund" 

md "%TargetFolder%!Projektnamn!\3. Stationsdokumentation\1. Enlinjeschema" 
md "%TargetFolder%!Projektnamn!\3. Stationsdokumentation\2. Blockschema" 
md "%TargetFolder%!Projektnamn!\3. Stationsdokumentation\3. Förreglingsschema" 
md "%TargetFolder%!Projektnamn!\3. Stationsdokumentation\4. Ritningsnummer" 

md "%TargetFolder%!Projektnamn!\4. Skåpsdokumentation\1. Skåpslayout" 
md "%TargetFolder%!Projektnamn!\4. Skåpsdokumentation\2. Apparatlista" 
md "%TargetFolder%!Projektnamn!\4. Skåpsdokumentation\3. Förbindningstabell" 
md "%TargetFolder%!Projektnamn!\4. Skåpsdokumentation\4. Skyltlista & Etiketter" 

:: Skapar RELATIVA Genvägarna 
mklink /D "%TargetFolder%!Projektnamn!\1. Projektpärm\7. Enlinjeschema" "..\3. Stationsdokumentation\1. Enlinjeschema" >nul 
mklink /D "%TargetFolder%!Projektnamn!\1. Projektpärm\8. Blockschema" "..\3. Stationsdokumentation\2. Blockschema" >nul 
mklink /D "%TargetFolder%!Projektnamn!\1. Projektpärm\9. Förreglingsschema" "..\3. Stationsdokumentation\3. Förreglingsschema" >nul 
mklink /D "%TargetFolder%!Projektnamn!\1. Projektpärm\10. Skåpslayout" "..\4. Skåpsdokumentation\1. Skåpslayout" >nul 
endlocal 
endlocal 

Этого пакетный файл работает с любым текущим каталогом при запуске пакетного файла с текущей учетной записью пользователя или с встроенным в учетной записи локального администратора, поскольку все написано для работы независимо от того, что является текущим каталогом.

Текущий каталог %SystemRoot% в случае, если пакетный файл хранится в папке общего сетевого ресурса, открытой с использованием UNC-пути, и выполняется двойным щелчком по нему.

Текущий каталог %SystemRoot%\System32 при запуске его второй раз с повышенными привилегиями, если текущий пользователь не имеет прав администратора.

Однако, если учетная запись локального администратора не имеет права на чтение &, разрешает выполнение разрешений на сетевой ресурс, cmd.exe не может выполнить командный файл с использованием UNC-пути непосредственно из общего сетевого ресурса.

В длинной строке, написанной в качестве второй строки в файл VBScript заменить /C на /K, чтобы открыть окно консоли открыто второго выполнение пакетного файла после подъема до уровня администратора, чтобы иметь возможность читать вывод сообщений об ошибках на Windows, командный интерпретатор.

Чтобы понять используемые команды и как они работают, откройте окно командной строки, выполните там следующие команды и внимательно прочитайте все страницы справки, отображаемые для каждой команды.

  • chcp /?
  • cls /?
  • del /?
  • echo /?
  • goto /?
  • if /?
  • md /?
  • mklink /?
  • pause /?
  • rem /?
  • set /?
  • setlocal /?
  • shift /?
  • wscript /? (или cscript /? в cscript.exe может быть использована.)

статьи Microsoft, на которые ссылается в комментариях к пакетное сотрудничество де:

Примечание: Все строки, начинающиеся с rem после 0 или более ведущих пространств могут быть безопасно удалены, как и все строки, начинающиеся с :: (недействительный метка, используемая для строк комментариев).

+0

Теперь я получаю диалоговое окно, но исходная проблема остается, когда я запускаю ее на сетевом диске, командная строка сразу же отключается после того, как я сделал выбор «да» для прав администратора. На местном уровне это работает отлично! Если я запускаю его через CMD, он говорит: Ny_mappstruktur.bat не является внутренним коммандо, а также внешним, программным или командным файлом. Это была проблема с самого начала. – user7305472

+0

@ user7305472 Встроенная учетная запись локального администратора, используемая после поднятия командного файла на уровень администратора, обычно не имеет прав доступа к общедоступному ресурсу на сервере в сети. Учетные записи сетевого администратора в домене обычно имеют полный доступ к общим ресурсам на сервере в домене, но не встроенную учетную запись локального администратора Windows. Мой тест работал, поскольку доля была на моем собственном компьютере, поэтому учетная запись локального администратора также имеет полный доступ к этой части. – Mofi

+0

Спасибо! Так что вы говорите, что я не смогу создать структуру папок на сервере, так как я не являюсь сетевым администратором? Я добавлю дополнительную информацию! – user7305472

 Смежные вопросы

  • Нет связанных вопросов^_^