5

I expected this code:

if (!File.Exists(fullFileName))
{
    File.Create(fullFileName);
}

File.SetAttributes(fullFileName, FileAttributes.Compressed);

To set this flag:

enter image description here

But it doesn't... What am I doing wrong? How do I set that flag on a file?


UPDATE: It says in the documentation

"It is not possible to change the compression status of a File object using the SetAttributes method."

And apparently it doesn't work when using the static File.SetAttributes either.

Given that, how can this be achieved?

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
Jonathan
  • 8,771
  • 4
  • 41
  • 78
  • 1
    This sounds like a job for PInvoke. Start here: https://stackoverflow.com/questions/624125/compress-a-folder-using-ntfs-compression-in-net/624446 – Parrish Husband Aug 27 '18 at 16:16

2 Answers2

2

You can use p/invoke to compress files.

I made myself a static helper function:

public static class FileTools
{
  private const int FSCTL_SET_COMPRESSION = 0x9C040;
  private const short COMPRESSION_FORMAT_DEFAULT = 1;

  [DllImport("kernel32.dll", SetLastError = true)]
  private static extern int DeviceIoControl(
      IntPtr hDevice,
      int dwIoControlCode,
      ref short lpInBuffer,
      int nInBufferSize,
      IntPtr lpOutBuffer,
      int nOutBufferSize,
      ref int lpBytesReturned,
      IntPtr lpOverlapped);

  public static bool EnableCompression(IntPtr 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;
  }
}

Which I use in my code for example with the file name:

using (var fileToCompress = File.Open(fileNameToCompress, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
  FileTools.EnableCompression(fileToCompress.Handle);
Sam
  • 28,421
  • 49
  • 167
  • 247
-1

The attributes are a bitmask.

Try this:

File.SetAttributes(fullFileName,
    File.GetAttributes(fullFileName) | FileAttributes.Compressed);

(Found in File.SetAttributes Method under Examples.)

Jashaszun
  • 9,207
  • 3
  • 29
  • 57
  • Thanks that sort of worked. It set the wrong flag though... Any clue how to set the one I need? http://i.imgur.com/7goaJu6.png – Jonathan Jun 25 '15 at 07:42
  • It should be the right flag... No idea why it doesn't work – Jonathan Jun 25 '15 at 07:55
  • 2
    [Found it...](https://msdn.microsoft.com/en-us/library/system.io.file.setattributes(v=vs.110).aspx#remarksToggle) "It is not possible to change the compression status of a File object using the SetAttributes method." – Jonathan Jun 25 '15 at 08:12