Compress a folder using NTFS compression in .NET

前端 未结 6 1240
Happy的楠姐
Happy的楠姐 2021-02-01 09:48

I want to compress a folder using NTFS compression in .NET. I found this post, but it does not work. It throws an exception (\"Invalid Parameter\").

DirectoryI         


        
6条回答
  •  广开言路
    2021-02-01 10:00

    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;
    }
    

    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.

    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.

提交回复
热议问题