X秒后如何使cmd命令超时

时间:2019-07-17 22:09:00

标签: cmd timeout

使用命令提示符,我需要在文件资源管理器中的网络位置上打开一个文件夹,如果该文件夹不可用,请退出我从中运行命令的命令提示符窗口。问题是尝试打开一个不存在的网络位置会花费非常长的时间(超过30秒),当它出现时,它会立即打开,因此我想尝试打开该位置并在5秒后退出。

我已经尝试使用taskkill,但是似乎访问网络位置会阻止它按应有的方式工作,而且taskkill似乎会杀死所有不理想的命令提示符窗口。要复制,请键入以下命令(使用无法访问的网络位置),这需要一段时间才能完成

if exist \\1.2.3.4\c$ (start \\1.2.3.4\c$) else exit

1 个答案:

答案 0 :(得分:0)

使用start command/program/path时,CMD不会直接使用给定路径启动资源管理器。在此之前,必须检查给定的参数以确定其类型(内部命令,外部可执行文件或脚本,其他类型的文件或文件夹)

根据类型,它可以直接启动它,也可以尝试使用ShellExecute API打开它。 ShellExecute API依次检查给定的对象,以确定应使用哪个应用程序打开它。如果对象是本地或远程文件夹的路径,则它将使用资源管理器打开该位置。

在处理通往不可用网络共享的路径时,CMD(和ShellExecute)将需要一段时间才能最终确定网络共享不可访问,因此在此期间将阻止执行CMD命令。

要避免阻塞,您需要使用新的CMD实例异步打开网络共享,然后尝试在超时期限后终止该实例。

使用taskkill终止该实例,应该为其赋予唯一的标题,以区别于其他进程。

一个非常基本和简单的解决方案是使用如下所示的批处理文件

:: ExploreShare.cmd
@echo off
setlocal
set "sharedLoc=%~1"
:: Basic validation
if not defined sharedLoc exit /b
if not "%sharedLoc:~0,2%"=="\\" exit /b

set "uniqTitle=ExploreShare-%time: =%-%random%"
start "%uniqTitle%" /min "CMD " /c start "" "%sharedLoc%"
>nul timeout /t 5
taskkill /fi "WINDOWTITLE eq %uniqTitle%" /f >nul 2>&1

它可以在这样的命令行中使用

> ExploreShare \\127.0.0.1\C$

使用这种基本解决方案的缺点是,无论用户是否通过视觉判断,它都将等待5秒钟,而无法提供任何方法来确定操作是否成功。

可以通过稍微复杂一些的脚本进行改进,该脚本将尝试最大程度地减少成功操作的等待时间,并提供确定成功或失败的机制。

:: ExploreShare2.cmd
@echo off
setlocal
set "sharedLoc=%~1"
:: Basic validation
if not defined sharedLoc exit /b 1
if not "%sharedLoc:~0,2%"=="\\" exit /b 1

set "uniqTitle=ExploreShare-%time: =%-%random%"
echo Attempting to open network share "%sharedLoc%" ...
start "%uniqTitle%" /min "CMD " /c if exist "%sharedLoc%" (start "" "%sharedLoc%") else pause
>nul timeout /t 1
set "childProc="
for /F "skip=2" %%A in ('tasklist /fi "WINDOWTITLE eq %uniqTitle%"') do set "childProc=%%A"
if not defined childProc (
    echo The operation completed successfully.
    exit /b 0
)
:: Give it another 4 seconds
>nul timeout /t 4
set "childProc="
for /F "skip=2" %%A in ('tasklist /fi "WINDOWTITLE eq %uniqTitle%"') do set "childProc=%%A"
if defined childProc (
    >&2 echo The operation timed out.
    taskkill /fi "WINDOWTITLE eq %uniqTitle%" /f >nul 2>&1
    exit /b 1
) else (
    echo The operation completed successfully.
    exit /b 0
)

例如,如果您需要在失败时终止CMD / BatchFile,可以像这样使用它

从命令行:

> ExploreShare2 "\\server\share" || exit


在批处理文件中:

call ExploreShare2 "\\server\share" || exit /b
相关问题