/// <summary> /// Copies the file version info header from one file to an other /// </summary> /// <param name="fromFile">Source file.</param> /// <param name="toFile">Destination file.</param> /// <param name="keyFile">The key file.</param> /// <param name="keyContainer">The key container.</param> /// <returns></returns> public static bool CopyFileVersionInfo(string fromFile, string toFile, string keyFile, string keyContainer) { if (string.IsNullOrEmpty(fromFile)) { throw new ArgumentNullException("fromFile"); } else if (string.IsNullOrEmpty(toFile)) { throw new ArgumentNullException("toFile"); } else if (!File.Exists(fromFile)) { throw new FileNotFoundException("File not found", fromFile); } else if (!File.Exists(toFile)) { throw new FileNotFoundException("File not found", toFile); } bool signFile = !string.IsNullOrEmpty(keyFile) || !string.IsNullOrEmpty(keyContainer); int handle; int size = NativeMethods.GetFileVersionInfoSize(fromFile, out handle); if (size <= 0) { return(false); } byte[] versionInfo = new byte[size]; if (NativeMethods.GetFileVersionInfo(fromFile, handle, size, versionInfo)) { int originalSize = NativeMethods.GetFileVersionInfoSize(toFile, out handle); if (originalSize == size) { byte[] versionInfo2 = new byte[size]; if (NativeMethods.GetFileVersionInfo(toFile, handle, size, versionInfo2)) { bool changed = false; for (int i = 0; i < size; i++) { if (versionInfo[i] != versionInfo2[i]) { changed = true; break; } } if (!changed) { return(true); // No need to update resource } } } // Find existing resources to make sure we only have one version resource List <ushort> languages = new List <ushort>(); using (DllHandle dllHandle = NativeMethods.LoadLibraryEx(toFile, IntPtr.Zero, 0x2)) { NativeMethods.EnumResourceLanguages(dllHandle, (IntPtr)16, (IntPtr)1, delegate(IntPtr hModule, IntPtr lpszType, IntPtr lpszName, ushort wIDLanguage, IntPtr lParam) { if (wIDLanguage != 0) { languages.Add(wIDLanguage); } return(true); }, IntPtr.Zero); } using (ResourceUpdateHandle resHandle = NativeMethods.BeginUpdateResource(toFile, false)) { if (resHandle != null) { /* Remove all language specific version resources */ foreach (ushort oldLang in languages) { NativeMethods.UpdateResource(resHandle, (IntPtr)16, (IntPtr)1, oldLang, null, 0); } bool ok = NativeMethods.UpdateResource(resHandle, (IntPtr)16, (IntPtr)1, 0, versionInfo, size); ok = resHandle.Commit() && ok; if (ok && signFile) { ok = BuildTools.ResignAssemblyWithFileOrContainer(toFile, keyFile, keyContainer); } return(ok); } else { return(false); } } } return(false); }
public static extern bool EnumResourceLanguages(DllHandle hModule, IntPtr lpszType, IntPtr lpName, EnumResLangDelegate lpEnumFunc, IntPtr lParam);