Writing to File Properties (Like from Windows Explorer Properties)

I am trying to write a property (specifically the "Comment" property) of a file programmatically. This would be the same as opening the file properties in Windows Explorer, and changing the field.

If I reference the shell32.dll, I can read the properties using objFolder.GetDetailsOf(objFileItem,14), but I cannot figure out how to write to it.

Any help is appreciated.

James

[390 byte] By [J.Hedrick] at [2007-12-17]
# 1
Comment is a property of a shortcut file (LNK) and not a normal file. As far as I'm aware .NET doesn't expose shortcuts at all. You'll have to use interop to set the value. Alternatively you can simply open the shortcut file and set it directly. It is a text file. Unfortunately if the format changes then your code will break but that is unlikely.
TaylorMichaelL at 2007-10-6 > top of Msdn Tech,Visual C#,Visual C# General...
# 2
This is not correct. Any file has a Comment field, which, as I mentioned, is able to be read with an interop reference to Shell32.

Any other ideas.

James

J.Hedrick at 2007-10-6 > top of Msdn Tech,Visual C#,Visual C# General...
# 3
This is stored in the alternate data stream :?SummaryInformation:$DATA. There's plenty of documentation but I couldn't find a way to write it from .NET properly... However, since it's just a 'file' you could just edit the contents manually assuming you are willing to write out the header format and then the sections that follow.

http://www.rainer-klute.de/~klute/Software/poibrowser/doc/HPSF-Description.html has good details on this.

Here's something to get you started and sorry I couldn't help more, if I find a way at some point I'll update this thread.


using System;

using System.Collections.Generic;

using System.Text;

using System.IO;

using System.Runtime.InteropServices;

namespace ReadStream

{

class Program

{

[DllImport("Kernel32.dll")]

static extern IntPtr CreateFile(string filename, [MarshalAs(UnmanagedType.U4)]FileAccess fileaccess, [MarshalAs(UnmanagedType.U4)]FileShare fileshare, int securityattributes, [MarshalAs(UnmanagedType.U4)]FileMode creationdisposition, int flags, IntPtr template);

static void Main(string[] args)

{

Console.WriteLine("This application will read (and could write to) the SummaryStream that contains properties for files.");

Console.WriteLine();

Char c = Convert.ToChar((byte)5);

string stream = c + "SummaryInformation";

string filename = "YourFilename.doc";

Microsoft.Win32.SafeHandles.SafeFileHandle handle = new Microsoft.Win32.SafeHandles.SafeFileHandle(CreateFile(String.Format("{0}:{1}", filename, stream), FileAccess.ReadWrite, FileShare.ReadWrite, 0, FileMode.OpenOrCreate, 0, IntPtr.Zero), true);

FileStream fs = new FileStream(handle, FileAccess.ReadWrite);

Byte[] byteArray = new byte[fs.Length];

fs.Read(byteArray, 0, (int)fs.Length);

fs.Close();

bool readableStuff = false;

int position = -1;

foreach (Byte b in byteArray)

{

if (b == (byte)30)

{

readableStuff = false;

Console.WriteLine();

Console.WriteLine("New field: ");

position = 0;

}

else

{

if (position >= 0)

{

position++;

}

}

if (position == 7)

{

readableStuff = true;

}

else

{

if (readableStuff)

Console.Write(Convert.ToChar(b));

}

}

Console.WriteLine();

Console.WriteLine("Press any key to continue");

Console.ReadKey();

}

}

}


SimonSoanes at 2007-10-6 > top of Msdn Tech,Visual C#,Visual C# General...
# 4

James,

You can modify the extended attributes for a file by calling ZwCreateFile(): http://msdn.microsoft.com/library/default.asp?url=/library/en-us/Kernel_r/hh/Kernel_r/k111_80b1882a-8617-45d4-a783-dbc3bfc9aad4.xml.asp.

Unfortunately the declaration isn't up on Pinvoke.Net but if you do create it, be sure to update the wiki!

HTH

Rob

RobertGruen at 2007-10-6 > top of Msdn Tech,Visual C#,Visual C# General...
# 5

I think there are several ways to do this, but the simplest is to use the Microsoft ActiveX DLL dsofile.dll, version 2.0. There is are a couple of articles on it at TechNet, and an old Dr GUI column from MSDN magazine. One article on MSDN has a wrapper function for .NET - in fact, search a little and you'll find all you need.

See http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q224351 and also http://www.microsoft.com/downloads/details.aspx?FamilyID=9ba6fac6-520b-4a0a-878a-53ec8300c4c2&DisplayLang=en

and also MSDN Forums http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=346666&SiteID=1 - though this guy is having problems, he's done it before and so have thousands - in Win32 and .NET environments.

Note that although these articles etc talk about Office files and OLE structured storage, it's a fact that the properties of "normal" files (eg, a .TXT file) can be read and written to with DSOFIle.

You may find a problem, writing to a property which has no data already present. The C++ source for dsofile.dll is provided by Microsoft, and a short web search will come up with a couple of forums or blogs which show you exactly what to change. Then, recompile the DLL for your own use, use the COM wrapper or pinvoke and you're home.

CodeTyro at 2007-10-6 > top of Msdn Tech,Visual C#,Visual C# General...