我想在.NET中使用NTFS压缩来压缩文件夹。 我发现这篇文章 ,但它不工作。 它引发一个exception(“无效的参数”)。
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压缩?
ShowDialog返回types:窗体与窗口
.NET是否支持Windows Eventing 6.0?
如何在ColdFusion中运行.net函数
如何获得任务栏的背景颜色
我们可以在我们的安装包中捆绑mono吗?
根据我的经验,使用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,ref lpBytesReturned,IntPtr.Zero) != 0; }
由于您正试图将其设置在目录中,因此您可能需要使用P / Invoke来使用FILE_FLAG_BACKUP_SEMANTICS调用CreateFile以获取目录上的SafeFileHandle。
另外,请注意,在NTFS目录中设置压缩不会压缩所有内容,只会使新文件显示为压缩(对于加密也是如此)。 如果要压缩整个目录,则需要遍历整个目录,并在每个文件/文件夹上调用DeviceIoControl。
我已经测试了代码和它
!
确保它与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); uint ret = (uint)(outParams.Properties["ReturnValue"].Value); } } } }
在创建Win32_Directory.Name = …字符串时,需要将反斜杠加倍,所以例如路径C: Foo Bar将被构建为:
Win32_Directory.Name = “C:\ \富酒吧”,
或使用您的示例代码:
string objPath =“Win32_Directory.Name = ”C:\\ Foo \\ Bar “”;
显然这个字符串被送到某个需要路径字符串的转义形式的进程。
我不相信有一种方法来在.NET框架中设置文件夹压缩,因为文档(注释部分)声称无法通过File.SetAttributes完成。 这似乎只在使用DeviceIoControl函数的Win32 API中可用。 仍然可以通过使用PInvoke通过.NET来做到这一点。
一般来说,一旦熟悉PInvoke,请查看pinvoke.net上的参考资料 ,讨论签名需要什么样才能实现此目的。
有一个更简单的方法,我正在使用Windows 8 64位,重写为VB.NET。 请享用。
Dim Path as string = "c:test" Dim strComputer As String = "." Dim objWMIService = Getobject("winmgmts:{impersonationLevel=impersonate}!\.rootcimv2") Dim colFolders = objWMIService.ExecQuery("Select * from Win32_Directory where name = '" & Replace(path,"","\") & "'") For Each objFolder In colFolders objFolder.Compress() Next
对我很好。 Chagne。根目录到 pcname 根目录,如果你需要在另一台计算机上。 小心使用。
这是Igal Serban答案的轻微调整。 我碰到一个微妙的问题, Name必须是一个非常具体的格式。 所以我添加了一些Replace("\",@"\").TrimEnd('\') 魔术来首先规范化路径,我也清理了一下代码。
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)) { // 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"); } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。