dbe*_*ham 61

不确定锁定的目录(Windows有吗?)

但是检测文件是否被另一个进程写入并不困难.

@echo off
2>nul (
  >>test.txt echo off
) && (echo file is not locked) || (echo file is locked)
Run Code Online (Sandbox Code Playgroud)

我使用另一个窗口中的以下测试脚本来锁定文件.

(
  >&2 pause
) >> test.txt
Run Code Online (Sandbox Code Playgroud)

当我从一个窗口运行第二个脚本然后从第二个窗口运行第一个脚本时,我得到了"锁定"消息.一旦我按下<Enter>第一个窗口,如果我重新运行第一个脚本,我会收到"解锁"消息.

说明

只要将命令的输出重定向到文件,就必须打开文件以进行写访问.Windows CMD会话将尝试打开该文件,即使该命令不产生任何输出.

>>重定向操作员打开追加模式的文件.

因此>>test.txt echo off将尝试打开文件,它不会向文件写入任何内容(假设echo已经关闭),然后它会关闭文件.该文件不会以任何方式进行修改.

大多数进程在打开文件进行写访问时都会锁定文件.(有OS系统调用允许打开文件以便在共享模式下写入,但这不是默认设置).因此,如果另一个进程已经锁定"test.txt"进行写入,则重定向将失败,并将以下错误消息发送到stderr - "进程无法访问该文件,因为它正被另一个进程使用." .在重定向失败时也会生成错误代码.如果命令和重定向成功,则返回成功代码.

只需添加2>nul命令就不会阻止错误消息,因为它会重定向命令的错误输出,而不是重定向.这就是为什么我将命令括在括号中,然后将错误输出重定向到parens之外的nul.

因此错误消息被有效隐藏,但错误代码仍然在parens之外传播.标准Windows &&||运算符用于检测parens中的命令是成功还是失败.大概echo off永远不会失败,因此失败的唯一可能原因是重定向失败.最有可能因为锁定问题而失败,但从技术上讲,可能还有其他原因导致失败.

除非使用||运算符,否则Windows在重定向失败时不会将%ERRORLEVEL%动态变量设置为错误,这是一个奇怪的"功能" .(请参阅Windows中的文件重定向和%errorlevel%).因此,||操作员必须在某个较低级别读取返回的错误代码,而不是通过%ERRORLEVEL%变量.

使用这些技术检测重定向失败在批处理上下文中非常有用.它可用于建立允许在并行进程中序列化多个事件的锁.例如,它可以使多个进程在"相同"时间安全地写入同一个日志文件.你如何在Windows下共享日志文件?


编辑

关于锁定文件夹.我不确定Windows是如何实现这一点的,也许是锁定.但是,如果进程具有涉及该文件夹的活动目录,则无法重命名该文件夹.这可以很容易地使用

2>nul ren folderName folderName && echo Folder is NOT locked || echo folder is LOCKED
Run Code Online (Sandbox Code Playgroud)

编辑

我已经知道(call ) (带空格)是一个非常快速的命令,没有副作用,保证在ERRORLEVEL设置为0时成功.而且(call) (没有空格)是一个没有副作用的快速命令,保证ERRORLEVEL 1失败.

所以我现在使用以下内容来检查文件是否被锁定:

2>nul (
  >>test.txt (call )
) && (echo file is not locked) || (echo file is locked)
Run Code Online (Sandbox Code Playgroud)

  • @Adriano - 解释添加:-) (2认同)

luk*_*ukk 10

除了来自dbenham的很好的答案,以下表格最终帮助我理解使用的技术:

( type nul >> file.txt ) 2>nul || echo File is locked!
Run Code Online (Sandbox Code Playgroud)

type nul命令给出一个空输出,并不像echo offorginal中的命令那样影响当前的echo设置.

如果你想使用if–then–else条件记住正确的顺序 - 成功语句(&&)将首先进行,而备用语句(||)将进入第二个:

command && (echo Command is successful) || (echo Command has failed) 
Run Code Online (Sandbox Code Playgroud)

  • 注意`if && then || else`格式,请记住,如果`then`块失败,也会执行`else`块. (2认同)

Jus*_*rce 7

如果下载并安装Windows Server 2003资源工具包工具oh.exe,则会调用一个实用程序,该实用程序将列出给定文件的打开文件句柄:

http://www.microsoft.com/en-us/download/details.aspx?id=17657

安装后,重新启动计算机,即可使用该实用程序.您可以在"帮助和支持"中心查看所有选项,也可以oh /?在命令提示符下键入.

(来自:http://windowsxp.mvps.org/processlock.htm)