using System; using System.Collections.Generic; using System.Text; using System.ComponentModel; using System.Runtime.InteropServices; using System.IO; namespace Vestris.ResourceLib { /// /// VS_VERSIONINFO /// This structure depicts the organization of data in a file-version resource. It is the root structure /// that contains all other file-version information structures. /// http://msdn.microsoft.com/en-us/library/aa914916.aspx /// public class VersionResource : Resource { ResourceTableHeader _header = new ResourceTableHeader("VS_VERSION_INFO"); FixedFileInfo _fixedfileinfo = new FixedFileInfo(); private Dictionary _resources = new Dictionary(); /// /// The resource header. /// public ResourceTableHeader Header { get { return _header; } } /// /// A dictionary of resource tables. /// public Dictionary Resources { get { return _resources; } } /// /// An existing version resource. /// /// Module handle. /// Resource ID. /// Resource type. /// Resource name. /// Language ID. /// Resource size. public VersionResource(IntPtr hModule, IntPtr hResource, ResourceId type, ResourceId name, UInt16 language, int size) : base(hModule, hResource, type, name, language, size) { } /// /// A new language-netural version resource. /// public VersionResource() : base(IntPtr.Zero, IntPtr.Zero, new ResourceId(Kernel32.ResourceTypes.RT_VERSION), new ResourceId(1), ResourceUtil.USENGLISHLANGID, 0) { _header.Header = new Kernel32.RESOURCE_HEADER(_fixedfileinfo.Size); } /// /// Read a version resource from a previously loaded module. /// /// Module handle. /// Pointer to the beginning of the resource. /// Pointer to the end of the resource. internal override IntPtr Read(IntPtr hModule, IntPtr lpRes) { _resources.Clear(); IntPtr pFixedFileInfo = _header.Read(lpRes); if (_header.Header.wValueLength != 0) { _fixedfileinfo = new FixedFileInfo(); _fixedfileinfo.Read(pFixedFileInfo); } IntPtr pChild = ResourceUtil.Align(pFixedFileInfo.ToInt32() + _header.Header.wValueLength); while (pChild.ToInt32() < (lpRes.ToInt32() + _header.Header.wLength)) { ResourceTableHeader rc = new ResourceTableHeader(pChild); switch (rc.Key) { case "StringFileInfo": StringFileInfo sr = new StringFileInfo(pChild); rc = sr; break; default: rc = new VarFileInfo(pChild); break; } _resources.Add(rc.Key, rc); pChild = ResourceUtil.Align(pChild.ToInt32() + rc.Header.wLength); } return new IntPtr(lpRes.ToInt32() + _header.Header.wLength); } /// /// String representation of the file version. /// public string FileVersion { get { return _fixedfileinfo.FileVersion; } set { _fixedfileinfo.FileVersion = value; } } /// /// String representation of the protect version. /// public string ProductVersion { get { return _fixedfileinfo.ProductVersion; } set { _fixedfileinfo.ProductVersion = value; } } /// /// Write this version resource to a binary stream. /// /// Binary stream. internal override void Write(BinaryWriter w) { long headerPos = w.BaseStream.Position; _header.Write(w); if (_fixedfileinfo != null) { _fixedfileinfo.Write(w); } Dictionary.Enumerator resourceEnum = _resources.GetEnumerator(); while (resourceEnum.MoveNext()) { resourceEnum.Current.Value.Write(w); } ResourceUtil.WriteAt(w, w.BaseStream.Position - headerPos, headerPos); } /// /// Returns an entry within this resource table. /// /// Entry key. /// A resource table. public ResourceTableHeader this[string key] { get { return Resources[key]; } set { Resources[key] = value; } } /// /// Return string representation of the version resource. /// /// public override string ToString() { StringBuilder sb = new StringBuilder(); if (_fixedfileinfo != null) { sb.Append(_fixedfileinfo.ToString()); } sb.AppendLine("BEGIN"); Dictionary.Enumerator resourceEnum = _resources.GetEnumerator(); while (resourceEnum.MoveNext()) { sb.Append(resourceEnum.Current.Value.ToString(1)); } sb.AppendLine("END"); return sb.ToString(); } } }