Getting a handle for a directory in .NET
On Windows, you can get a handle on a directory. This can be useful to prevent other applications from accessing or deleting the folder while your application is accessing it. You can use the win32 method CreateFile to open a folder. This method is not available in .NET, but it is possible to use it using the Microsoft.Windows.CsWin32 package.
Shell
dotnet new console
dotnet add package Microsoft.Windows.CsWin32 --prerelease
Create a new file named NativeMethods.txt
with the following content:
NativeMethods.txt
CreateFileW
GENERIC_ACCESS_RIGHTS
Add the following section to the .csproj
file. This allows the Microsoft.Windows.CsWin32
to generate the code to access the methods declared in NativeMethods.txt
.
csproj (MSBuild project file)
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<AdditionalFiles Include="NativeMethods.txt" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.18-beta">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
</Project>
Finally you can use the following code to get a handle for a directory:
C#
var path = @"C:\folder";
using var handle = Windows.Win32.PInvoke.CreateFile(
path,
(uint)Windows.Win32.Foundation.GENERIC_ACCESS_RIGHTS.GENERIC_READ,
Windows.Win32.Storage.FileSystem.FILE_SHARE_MODE.FILE_SHARE_NONE, // Choose the share mode you want
null,
Windows.Win32.Storage.FileSystem.FILE_CREATION_DISPOSITION.OPEN_EXISTING,
// FILE_FLAG_BACKUP_SEMANTICS is required to open a directory, see
// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew?WT.mc_id=DT-MVP-5003978#directories
Windows.Win32.Storage.FileSystem.FILE_FLAGS_AND_ATTRIBUTES.FILE_FLAG_BACKUP_SEMANTICS,
null);
if (handle.IsInvalid)
throw new Exception("Cannot open folder");
Do you have a question or a suggestion about this post? Contact me!
Enjoy this blog?💖 Sponsor on GitHub