diff --git a/TimberWinR.ExtractID/Program.cs b/TimberWinR.ExtractID/Program.cs new file mode 100644 index 0000000..ab3ebfc --- /dev/null +++ b/TimberWinR.ExtractID/Program.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using Microsoft.Win32.SafeHandles; +using System.Runtime.InteropServices; + +namespace TimberWinR.ExtractID +{ + class MsiHandle : SafeHandleMinusOneIsInvalid + { + public MsiHandle() + : base(true) + { } + + protected override bool ReleaseHandle() + { + return NativeMethods.MsiCloseHandle(handle) == 0; + } + } + + class NativeMethods + { + const string MsiDll = "Msi.dll"; + + [DllImport(MsiDll, CharSet = CharSet.Unicode, ExactSpelling = true)] + public extern static uint MsiOpenPackageW(string szPackagePath, out MsiHandle product); + + [DllImport(MsiDll, ExactSpelling = true)] + public extern static uint MsiCloseHandle(IntPtr hAny); + + [DllImport(MsiDll, CharSet = CharSet.Unicode, ExactSpelling = true)] + static extern uint MsiGetProductPropertyW(MsiHandle hProduct, string szProperty, StringBuilder value, ref int length); + + + [DllImport(MsiDll, ExactSpelling = true)] + public static extern int MsiSetInternalUI(int value, IntPtr hwnd); + + public static uint MsiGetProductProperty(MsiHandle hProduct, string szProperty, out string value) + { + StringBuilder sb = new StringBuilder(1024); + int length = sb.Capacity; + uint err; + value = null; + if (0 == (err = MsiGetProductPropertyW(hProduct, szProperty, sb, ref length))) + { + sb.Length = length; + value = sb.ToString(); + return 0; + } + + return err; + } + } + + + + class Program + { + [STAThread] + static int Main(string[] args) + { + if (args.Length < 2) + { + Console.Error.WriteLine("Expecting MSI and Tempolate file arguments"); + return 1; + } + + string msiDirectory = args[0]; + string updateFile = args[1]; + string newFile = args[2]; + + string msiFile = Directory.GetFiles(msiDirectory, "TimberWinR*.msi").FirstOrDefault(); + + NativeMethods.MsiSetInternalUI(2, IntPtr.Zero); // Hide all UI. Without this you get a MSI dialog + + MsiHandle msi; + uint err; + if (0 != (err = NativeMethods.MsiOpenPackageW(msiFile, out msi))) + { + Console.Error.WriteLine("Can't open MSI, error {0}", err); + return 1; + } + + // Strings available in all MSIs + string productCode; + using (msi) + { + if (0 != NativeMethods.MsiGetProductProperty(msi, "ProductCode", out productCode)) + throw new InvalidOperationException("Can't obtain product code"); + + string contents = File.ReadAllText(args[1]); + + contents = contents.Replace("${PROJECTGUID}", productCode); + + File.WriteAllText(args[2], contents); + + Console.WriteLine("Updated {0} ProductID: {1}", args[2], productCode); + + return 0; + } + + Console.Error.WriteLine("Failed for some reason"); + } + } +} diff --git a/TimberWinR.ExtractID/Properties/AssemblyInfo.cs b/TimberWinR.ExtractID/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..b1f4977 --- /dev/null +++ b/TimberWinR.ExtractID/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("TimberWinR.ExtractID")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("TimberWinR.ExtractID")] +[assembly: AssemblyCopyright("Copyright © 2014")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("cfb670ee-743d-49c7-b2bf-456bac3a88ef")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/TimberWinR.ExtractID/TimberWinR.ExtractID.csproj b/TimberWinR.ExtractID/TimberWinR.ExtractID.csproj new file mode 100644 index 0000000..d13e8fd --- /dev/null +++ b/TimberWinR.ExtractID/TimberWinR.ExtractID.csproj @@ -0,0 +1,55 @@ + + + + + Debug + AnyCPU + {99096939-E9DD-4499-883D-4726745A5843} + Exe + Properties + TimberWinR.ExtractID + TimberWinR.ExtractID + v4.0 + 512 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TimberWinR.ServiceHost/Properties/AssemblyInfo.cs b/TimberWinR.ServiceHost/Properties/AssemblyInfo.cs index 4333ec8..669faa6 100644 --- a/TimberWinR.ServiceHost/Properties/AssemblyInfo.cs +++ b/TimberWinR.ServiceHost/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.3.9.0")] -[assembly: AssemblyFileVersion("1.3.9.0")] +[assembly: AssemblyVersion("1.3.10.0")] +[assembly: AssemblyFileVersion("1.3.10.0")] diff --git a/TimberWinR.sln b/TimberWinR.sln index 43b314e..aaf3365 100644 --- a/TimberWinR.sln +++ b/TimberWinR.sln @@ -26,6 +26,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProjectSection EndProject Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "TimberWinR.Wix", "TimberWix\TimberWinR.Wix.wixproj", "{82A39B31-61EC-468D-AA71-0D949AC6528F}" + ProjectSection(ProjectDependencies) = postProject + {99096939-E9DD-4499-883D-4726745A5843} = {99096939-E9DD-4499-883D-4726745A5843} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TimberWinR.ExtractID", "TimberWinR.ExtractID\TimberWinR.ExtractID.csproj", "{99096939-E9DD-4499-883D-4726745A5843}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -79,6 +84,16 @@ Global {82A39B31-61EC-468D-AA71-0D949AC6528F}.Release|Mixed Platforms.Build.0 = Release|x86 {82A39B31-61EC-468D-AA71-0D949AC6528F}.Release|x86.ActiveCfg = Release|x86 {82A39B31-61EC-468D-AA71-0D949AC6528F}.Release|x86.Build.0 = Release|x86 + {99096939-E9DD-4499-883D-4726745A5843}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {99096939-E9DD-4499-883D-4726745A5843}.Debug|Any CPU.Build.0 = Debug|Any CPU + {99096939-E9DD-4499-883D-4726745A5843}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {99096939-E9DD-4499-883D-4726745A5843}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {99096939-E9DD-4499-883D-4726745A5843}.Debug|x86.ActiveCfg = Debug|Any CPU + {99096939-E9DD-4499-883D-4726745A5843}.Release|Any CPU.ActiveCfg = Release|Any CPU + {99096939-E9DD-4499-883D-4726745A5843}.Release|Any CPU.Build.0 = Release|Any CPU + {99096939-E9DD-4499-883D-4726745A5843}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {99096939-E9DD-4499-883D-4726745A5843}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {99096939-E9DD-4499-883D-4726745A5843}.Release|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/TimberWix/Product.wxs b/TimberWix/Product.wxs index 2ea72df..c6add2f 100644 --- a/TimberWix/Product.wxs +++ b/TimberWix/Product.wxs @@ -6,6 +6,12 @@ c:\logs Info 5141 + + + + + +