且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在.NET中使用NTFS压缩来压缩文件夹

更新时间:2023-09-25 22:15:46

使用P/Invoke通常比WMI容易.我相信以下方法应该有效:

Using P/Invoke is, in my experience, usually easier than WMI. I believe the following should work:

private const int FSCTL_SET_COMPRESSION = 0x9C040;
private const short COMPRESSION_FORMAT_DEFAULT = 1;

[DllImport("kernel32.dll", SetLastError = true)]
private static extern int DeviceIoControl(
    SafeFileHandle hDevice,
    int dwIoControlCode,
    ref short lpInBuffer,
    int nInBufferSize,
    IntPtr lpOutBuffer,
    int nOutBufferSize,
    ref int lpBytesReturned,
    IntPtr lpOverlapped);

public static bool EnableCompression(SafeFileHandle handle)
{
    int lpBytesReturned = 0;
    short lpInBuffer = COMPRESSION_FORMAT_DEFAULT;

    return DeviceIoControl(handle, FSCTL_SET_COMPRESSION,
        ref lpInBuffer, sizeof(short), IntPtr.Zero, 0,
        ref lpBytesReturned, IntPtr.Zero) != 0;
}

由于要在目录上进行设置,因此可能需要使用P/Invoke来调用

Since you're trying to set this on a directory, you will probably need to use P/Invoke to call CreateFile using FILE_FLAG_BACKUP_SEMANTICS to get the SafeFileHandle on the directory.

此外,请注意,在NTFS中的目录上设置压缩并不会压缩所有内容,只会使新文件显示为已压缩(加密也是如此).如果要压缩整个目录,则需要遍历整个目录并在每个文件/文件夹上调用DeviceIoControl.

Also, note that setting compression on a directory in NTFS does not compress all the contents, it only makes new files show up as compressed (the same is true for encryption). If you want to compress the entire directory, you'll need to walk the entire directory and call DeviceIoControl on each file/folder.