如何检查是否可以在VB.NET中重命名目录?

时间:2022-04-25 00:04:33

My thought is to use CreateFile from kernel32 and check for sharing violations. I believe this will work because I watched the file system activity with Process Monitor while issuing a rename command from CMD that I knew would fail and the last activity was a failed CreateFile call that resulted in a sharing violation.

我的想法是使用kernel32中的CreateFile并检查共享违规。我相信这会有效,因为我在从CMD发出一个我知道会失败的重命名命令时看到了Process Monitor的文件系统活动,而最后一个活动是导致共享冲突的CreateFile调用失败。

This is the Process Monitor information on the call.

这是有关呼叫的Process Monitor信息。

Desired Access: Read Attributes, Delete, Synchronize
Disposition: Open 
Options: Synchronous IO Non-Alert, Open Reparse Point 
Attributes: n/a 
ShareMode: Read, Write, Delete 
AllocationSize: n/a

Using this VB code, I produced a call which gave the same information in Process Monitor but did not cause the sharing violation.

使用这个VB代码,我产生了一个调用,它在Process Monitor中提供了相同的信息,但没有导致共享冲突。

CreateFile(theDirectoryPath, _
           FILE_READ_ATTRIBUTES Or DELETE Or SYNCHRONIZE, _
           FILE_SHARE_READ Or FILE_SHARE_WRITE Or FILE_SHARE_DELETE, _
           Nothing, _
           OPEN_EXISTING, _
           FILE_ATTRIBUTE_DIRECTORY Or FILE_FLAG_BACKUP_SEMANTICS _
               Or FILE_FLAG_OPEN_REPARSE_POINT, _
           Nothing)

The constants are pulled from various MSDN and pinvoke.net sources.

常量来自各种MSDN和pinvoke.net来源。

If I call the above code recursively on all subfolders it will eventually cause the sharing violation, but when CMD refused to rename, it did not recurse.

如果我在所有子文件夹上递归调用上面的代码,它最终会导致共享冲突,但是当CMD拒绝重命名时,它没有递归。

Yes, I know I could just try and catch the exception. But the point at which I want to know if the directory can be renamed and the point at which I want to rename the directory are not the same.

是的,我知道我可以尝试捕捉异常。但我想知道目录是否可以重命名以及我想重命名目录的点是不一样的。

EDIT:

There may have been a source of confusion in this question. I am not concerned with permissions; I am concerned with file locks.

这个问题可能存在混淆的根源。我不关心权限;我关心文件锁。

2 个解决方案

#1


Yes, I know I could just try and catch the exception. But the point at which I want to know if the directory can be renamed and the point at which I want to rename the directory are not the same.

是的,我知道我可以尝试捕捉异常。但我想知道目录是否可以重命名以及我想重命名目录的点是不一样的。

In my opinion, this is a design problem that creates a race condition. If you check first and rename later, you will not know that the time of rename if your previous check was valid.

在我看来,这是一个创造竞争条件的设计问题。如果您先检查并稍后重命名,则如果您之前的检查有效,则无法知道重命名的时间。

#2


Untested, but this should work:

未经测试,但这应该工作:

Dim fp As New FileIOPermission(FileIOPermissionAccess.Write, "C:\myfolderpath")
Try
    fp.Demand()
Catch e As SecurityException
    Console.WriteLine("I can't rename this folder.")
End Try

This will "demand" Read and Write permissions on the folder without actually renaming anything.

这将“要求”文件夹的读写权限,而不实际重命名任何内容。

Edit: The above doesn't do what I thought it would, see Stephen's comment below.

编辑:以上并没有按照我的想法行事,请参阅Stephen的评论。

If this doesn't work, perhaps attempting to rename the file with the same filename will trigger the security exception without actually doing anything destructive (though it will probably "touch" the directory).

如果这不起作用,可能尝试使用相同的文件名重命名文件将触发安全性异常,而不会实际做任何破坏性的事情(尽管它可能会“触摸”目录)。

#1


Yes, I know I could just try and catch the exception. But the point at which I want to know if the directory can be renamed and the point at which I want to rename the directory are not the same.

是的,我知道我可以尝试捕捉异常。但我想知道目录是否可以重命名以及我想重命名目录的点是不一样的。

In my opinion, this is a design problem that creates a race condition. If you check first and rename later, you will not know that the time of rename if your previous check was valid.

在我看来,这是一个创造竞争条件的设计问题。如果您先检查并稍后重命名,则如果您之前的检查有效,则无法知道重命名的时间。

#2


Untested, but this should work:

未经测试,但这应该工作:

Dim fp As New FileIOPermission(FileIOPermissionAccess.Write, "C:\myfolderpath")
Try
    fp.Demand()
Catch e As SecurityException
    Console.WriteLine("I can't rename this folder.")
End Try

This will "demand" Read and Write permissions on the folder without actually renaming anything.

这将“要求”文件夹的读写权限,而不实际重命名任何内容。

Edit: The above doesn't do what I thought it would, see Stephen's comment below.

编辑:以上并没有按照我的想法行事,请参阅Stephen的评论。

If this doesn't work, perhaps attempting to rename the file with the same filename will trigger the security exception without actually doing anything destructive (though it will probably "touch" the directory).

如果这不起作用,可能尝试使用相同的文件名重命名文件将触发安全性异常,而不会实际做任何破坏性的事情(尽管它可能会“触摸”目录)。