当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《在.NET中使用NTFS压缩压缩文件夹》经验,为你挑选了2个好方法。

我想在.NET中使用NTFS压缩来压缩文件夹.我找到了这篇文章,但它不起作用.它抛出异常("无效参数").

DirectoryInfo directoryInfo = new DirectoryInfo( destinationDir );
if( ( directoryInfo.Attributes & FileAttributes.Compressed ) != FileAttributes.Compressed )
{
   string objPath = "Win32_Directory.Name=" + "\"" + destinationDir + "\"";
   using( ManagementObject dir = new ManagementObject( objPath ) )
   {
      ManagementBaseObject outParams = dir.InvokeMethod( "Compress", null, null );
      uint ret = (uint)( outParams.Properties["ReturnValue"].Value );
   }
}

有谁知道如何在文件夹上启用NTFS压缩?



1> Zack Elan..:

根据我的经验,使用P/Invoke通常比WMI更容易.我认为以下应该有效:

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来调用的CreateFile使用FILE_FLAG_BACKUP_SEMANTICS,以获得SafeFileHandle上的目录.

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



2> Igal Serban..:

我已经测试了代码和它 替代文字!

确保它适用于gui.也许分配单元的大小对于压缩来说太大了.或者您没有足够的权限.

对于您的目标使用格式如下:"c:/ temp/testcomp"使用正斜杠.

完整代码:

using System.IO;
using System.Management;

class Program
{
    static void Main(string[] args)
    {
        string destinationDir = "c:/temp/testcomp";
        DirectoryInfo directoryInfo = new DirectoryInfo(destinationDir);
        if ((directoryInfo.Attributes & FileAttributes.Compressed) != FileAttributes.Compressed)
        {
            string objPath = "Win32_Directory.Name=" + "\"" + destinationDir + "\"";
            using (ManagementObject dir = new ManagementObject(objPath))
            {
                ManagementBaseObject outParams = dir.InvokeMethod("Compress", null, null);
                uint ret = (uint)(outParams.Properties["ReturnValue"].Value);
            }
        }
     }
}


这比解析P/Invoke更简洁,更重要的是,尽管返回成功状态代码,它实际上并没有工作.虽然`ManagementObject` .ctor很挑剔,但我用`string objPath ="Win32_Directory.Name ="+"'"+ dir.FullName.Replace("\\",@"\\").TrimEnd('\ \')+"'";`以确保`ManagementObject`不会抛出无效参数.
谢谢!! f s s s did did did did did did!
推荐阅读
php
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有