在 .NET 中使用 NTFS 压缩来压缩文件夹
我想在 .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 压缩吗?
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").
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 );
}
}
Anybody knows how to enable NTFS compression on a folder?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
根据我的经验,使用 P/Invoke 通常比 WMI 更容易。 我相信以下内容应该有效:
由于您尝试在目录上设置此选项,因此您可能需要使用 P/Invoke 来调用 CreateFile 使用
FILE_FLAG_BACKUP_SEMANTICS
获取目录上的 SafeFileHandle。另请注意,在 NTFS 中的目录上设置压缩不会压缩所有内容,它只会使新文件显示为压缩的(加密也是如此)。 如果要压缩整个目录,则需要遍历整个目录并对每个文件/文件夹调用 DeviceIoControl。
Using P/Invoke is, in my experience, usually easier than WMI. I believe the following should work:
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.
我已经测试了代码,它
(来源:typepad.com)
!
完整代码:
I have tested the code and it
(source: typepad.com)
!
Full code:
有一种更简单的方法,我在 Windows 8 64 位中使用,为 VB.NET 重写。 享受。
对我来说效果很好。 如果您需要在另一台计算机上执行此操作,请将 .\root 更改为 \pcname\root。 小心使用。
There is a much simpler way, which I am using in Windows 8 64-bit, rewritten for VB.NET. Enjoy.
works great for me. Chagne .\root to \pcname\root if you need to do it on another computer. Use with care.
创建 Win32_Directory.Name=... 字符串时,您需要双反斜杠,因此例如路径 C:\Foo\Bar 将构建为:
或使用您的示例代码:
显然,该字符串被馈送到某个需要路径字符串转义形式的进程。
When creating the Win32_Directory.Name=... string you need to double the backslashes, so for example the path C:\Foo\Bar would be built up as:
or using your example code:
Apparently the string is fed to some process that expects an escaped form of the path string.
这是对 Igal Serban 答案的轻微改编。 我遇到了一个微妙的问题,
Name
必须采用非常特定的格式。 所以我添加了一些Replace("\\", @"\\").TrimEnd('\\')
magic 首先规范化路径,我还清理了代码有点。This is a slight adaption of Igal Serban answer. I ran into a subtle issue with the
Name
having to be in a very specific format. So I added someReplace("\\", @"\\").TrimEnd('\\')
magic to normalize the path first, I also cleaned up the code a bit.我不相信有一种方法可以在 .NET 框架中设置文件夹压缩,因为文档(备注部分)声称它无法通过 File.SetAttributes。 这似乎仅在使用 DeviceIoControl 的 Win32 API 中可用 函数。 人们仍然可以通过 .NET 使用 PInvoke 来完成此操作。
总体熟悉 PInvoke 后,请查看 pinvoke.net 上的参考资料,其中讨论了 签名需要看起来像这样才能实现这一点。
I don't believe there is a way to set folder compression in the .NET framework as the docs (remarks section) claim it cannot be done through File.SetAttributes. This seems to be only available in the Win32 API using the DeviceIoControl function. One can still do this through .NET by using PInvoke.
Once familiar with PInvoke in general, check out the reference at pinvoke.net that discusses what the signature needs to look like in order to make this happen.
基于 Zack Elan 的解决方案,我在创建 SafeFileHandle 时遇到了一些困难,因此我在这里发布整个类以供参考:
I struggled a bit to create the
SafeFileHandle
, based on Zack Elan's solution, so I'm posting here the whole class for reference: