尽管从命令行调用该批处理文件可以正常工作,但为什么从快捷方式调用该批处理文件却会立即关闭呢?

时间:2019-05-06 13:45:03

标签: windows batch-file command-line

编辑3(解决方案):

正如michael_heath在他的回答中所描述的,问题归结为两件事:通过快捷方式执行某些操作时,windows如何准确地构建命令,以及{{1}的后果非常具体(坦率地荒谬) }开启\C。供以后参考,如果有其他可怜的人遇到这个StackOverflow问题,则可以通过将快捷方式中的“ Target”属性更改为经过稍微修改的Michael答案(具体为cmd.exe)来解决此问题。 Here's a screenshot too,(如有必要),尽管很遗憾,您看不到整个目标行。

再次感谢迈克尔。


我正在尝试创建一个个人批处理实用程序,以在桌面上创建符号链接,这与“发送到...>桌面”与快捷方式的工作方式大致相同。我经常使用符号链接,以使诸如bash配置文件(.bashrc和.bash_profile等)之类的内容在其他地方受到版本控制,以实现可移植性以及计算机上的其他功能。

为了易于使用,我的想法是创建一个简单的批处理文件来为我执行此操作,并将符号链接放置在桌面上。然后,我将在“发送到”文件夹中放置此文件的快捷方式,使其显示在上下文菜单的“发送到”中(我知道mklink需要管理员权限,因此该快捷方式也设置为以管理员身份运行)。

以下是我编写的文件:

C:\Windows\System32\cmd.exe /C @"C:\{path-to-script}\link.bat"

这是我要执行的操作的总体思路:

  1. 对输入的双引号(如果有)(%〜1)
  2. 检查输入内容是否为目录
  3. 获取输入(%%〜nxi)的基本名称和文件扩展名
  4. 建立链接
  5. 如果发生错误,请暂停以使其可见而不是退出(因为从快捷方式调用了批处理文件)

在我给它输入包含文件或目录名称中的空格的输入之前,它可以很好地工作。实际上,我还没有测试如果路径中有空格但实际文件或目录的基本名称中没有空格,会发生什么情况,但是我认为会出现同样的问题。

我进行了一些更改,以尝试使它与带有空格的文件一起使用,包括在第一行中去除输入中的引号,以便以后不将引号加倍,并且将“ delims =“ for循环。实际上,我在这里找到了这两个解决方案。

但是,尽管我尽了最大的努力,但是无论我做什么,当输入带有空格的文件时,该文件都会立即关闭。我已经用@echo off set f=%~1 set switch= if exist "%f%\*" set switch=/D for /F "delims=" %%i in ("%f%") do set name=%%~nxi mklink %switch% "%USERPROFILE%\Desktop\%name%" "%f%" if not %ERRORLEVEL%==0 pause 乱填充了每一行,使用手动输入的输入从命令行运行脚本以使其不会退出,并从命令行运行每个单独的命令(如果可能)。

令人震惊的是,当我从命令行运行它或运行单个命令时,即使输入中有空格,它们也都可以完美地工作。我什至创建了另一个批处理文件,该批处理文件什么也不做,只输出接收到的输入,然后从Send To运行 ,并确认输入与我从命令行输入的输入相同。

从发送至中的快捷方式调用时,到底出了什么问题?


编辑1:快捷方式本身的属性如下:

  • 目标:C:\ Users {用户名} \ vc \ git \ util-scripts \ bat \ link.bat
  • 开始于:C:\ Users {用户名} \ vc \ git \ util-scripts \ bat

以下是屏幕截图:

Because I just made my account here I can't embed the picture but here it is


编辑2:这是我使用的当前代码,如Gerhard Barnard所建议,但是问题仍然存在:

pause

2 个答案:

答案 0 :(得分:1)

尝试不使用此处不需要的/F选项,我们也不需要设置变量,因为它可以与扩展的meta变量完美配合:

@echo off
set "fname=%~1"
set switch=
if exist "%fname%\.*" set "switch=/D"

for %%i in ("%fname%") do (
    echo mklink %switch% "%USERPROFILE%\Desktop\%%~nxi" "%fname%"
    if errorlevel 1 pause
)

答案 1 :(得分:0)

@echo off
setlocal

rem Set the path for the created symlink.
set "linkdir=%USERPROFILE%\Desktop"

for %%A in (%*) do call :link "%%~A"

rem Check results.
echo: & dir /A:L "%linkdir%" & pause
exit /b

:link
set "switch="
if exist "%~1\*" set "switch=/D"
for /F "delims=" %%A in ("%~1") do set "name=%%~nxA"
if not defined name echo Variable "name" not defined.& exit /b 1
mklink %switch% "%linkdir%\%name%" "%~1"
exit /b 0

您的批处理文件代码正在运行。 此代码可以处理多个文件或文件夹。 该代码还有助于一次测试所有内容, 文件,文件夹,符号链接文件和符号链接 文件夹作为目标。

如果您只希望处理1个目标, 然后只需将%*更改为"%~1"

主要问题是快捷方式中的命令字符串。

C:\Users\{username}\vc\git\util-scripts\bat\link.bat

.bat的文件类型将构建一个命令,例如:

C:\Windows\System32\cmd.exe /C "C:\Users\{username}\vc\git\util-scripts\bat\link.bat" %*

%*替换为传递的参数。

如果您的命令带有带双引号的参数, 它可能看起来像:

C:\Windows\System32\cmd.exe /C "C:\Users\{username}\vc\git\util-scripts\bat\link.bat" "C:\Users\a file.txt"

/C之后的命令字符串有4个双引号 和双引号都在两端。 行为由于双引号而改变。

引用cmd /?

If /C or /K is specified, then the remainder of the command line after
the switch is processed as a command line, where the following logic is
used to process quote (") characters:

    1.  If all of the following conditions are met, then quote characters
        on the command line are preserved:

        - no /S switch
        - exactly two quote characters
        - no special characters between the two quote characters,
          where special is one of: &<>()@^|
        - there are one or more whitespace characters between the
          two quote characters
        - the string between the two quote characters is the name
          of an executable file.

    2.  Otherwise, old behavior is to see if the first character is
        a quote character and if so, strip the leading character and
        remove the last quote character on the command line, preserving
        any text after the last quote character.

在第1节中,“否/ S开关” 为true,则下一个为 “正好是两个引号字符” ,这是错误的。 现在,这适用于第2节,它可以使 /C之后的命令字符串,带双引号:

C:\Users\{username}\vc\git\util-scripts\bat\link.bat" "C:\Users\a file.txt

尽管其余部分已暴露,但仍引用了空格, 在这种情况下,这是无效的命令字符串。 请注意,C:\Users\a file.txt是一个示例 传递的参数被双引号引用为 "C:\Users\a file.txt"

快捷方式中的命令字符串更改为:

C:\Windows\System32\cmd.exe /C echo: & "C:\Users\{username}\vc\git\util-scripts\bat\link.cmd"

命令现在为C:\Windows\System32\cmd.exe,其中 使用命令字符串提供更多控制。 在/C之后,使用echo:来避免该命令 以双引号开头的字符串,这有助于 防止双引号在两端被剥离,因为 命令字符串不再以双引号开头。 &之后是重要的命令 现在即使参数以双引号结尾也可以工作。

您可以用另一个初始命令替换echo: &。 您还可以在命令字符串前使用@,因此快捷方式 命令字符串为:

C:\Windows\System32\cmd.exe /C @"C:\Users\{username}\vc\git\util-scripts\bat\link.cmd"

因此,最适合您的用例的东西。