我要压缩文件夹中使用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压缩在一个文件夹?

有帮助吗?

解决方案

根据我的经验,使用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。

其他提示

我已经测试的和它的代码 alt text!

  • 确保你的作品,与图形用户界面。也许分配单元的尺寸太大了压缩。或者你没有足够的权限。
  • 您的目的地使用的格式,像这样:"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);
            }
        }
     }
}

创建Win32_Directory.Name = ...字符串时,需要加倍反斜杠,例如路径C:\ Foo \ Bar将构建为:

  

Win32_Directory.Name = QUOT; C:\\富\\酒吧及QUOT;,

或使用您的示例代码:

  

string objPath =" Win32_Directory.Name = \" C:\\\\ Foo \\\\ Bar \"&quot ;;

显然字符串被送到某个需要转义形式的路径字符串的进程。

我不相信有一种方法可以在.NET框架中设置文件夹压缩,因为文档(备注部分)声称无法通过 File.SetAttributes 。这似乎仅在Win32 API中使用 DeviceIoControl 功能。我们仍然可以通过使用 PInvoke 来实现这一目的。

一旦熟悉PInvoke,请查看 pinvoke.net 上的参考文献,该文章讨论了签名需要看起来像是为了实现这一目标。

有一种更简单的方法,我在Windows 8 64位中使用,为VB.NET重写。享受。

    Dim Path as string = "c:\test"
    Dim strComputer As String = "."
    Dim objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
    Dim colFolders = objWMIService.ExecQuery("Select * from Win32_Directory where name = '" & Replace(path, "\", "\\") & "'")
    For Each objFolder In colFolders
        objFolder.Compress()
    Next

对我很有用。 Chagne。\ root to \ pcname \ root如果你需要在另一台计算机上执行它。小心使用。

这是Igal Serban答案的略微改编。我遇到了一个微妙的问题, Name 必须采用非常特定的格式。所以我添加了一些替换(“\\”,@" \\")。TrimEnd('\\') magic 以首先规范化路径,我还清理了一些代码。

var dir = new DirectoryInfo(_outputFolder);

if (!dir.Exists)
{
    dir.Create();
}

if ((dir.Attributes & FileAttributes.Compressed) == 0)
{
    try
    {
        // Enable compression for the output folder
        // (this will save a ton of disk space)

        string objPath = "Win32_Directory.Name=" + "'" + dir.FullName.Replace("\\", @"\\").TrimEnd('\\') + "'";

        using (ManagementObject obj = new ManagementObject(objPath))
        {
            using (obj.InvokeMethod("Compress", null, null))
            {
                // I don't really care about the return value, 
                // if we enabled it great but it can also be done manually
                // if really needed
            }
        }
    }
    catch (Exception ex)
    {
        System.Diagnostics.Trace.WriteLine("Cannot enable compression for folder '" + dir.FullName + "': " + ex.Message, "WMI");
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top