Skip to content

Instantly share code, notes, and snippets.

@GilesBathgate
Last active August 11, 2019 12:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GilesBathgate/326de8355ebc829061de5840e39b043b to your computer and use it in GitHub Desktop.
Save GilesBathgate/326de8355ebc829061de5840e39b043b to your computer and use it in GitHub Desktop.
using Microsoft.Deployment.WindowsInstaller;
using System;
using WixSharp;
using WixSharp.CommonTasks;
namespace Setup1
{
class Program
{
static void Main()
{
var project = new ManagedProject("MyProject",
new Dir(@"%ProgramFiles%\My Company\My Product",
new File("Program.cs")));
project.GUID = new Guid("6fe30b47-2577-43ad-9095-1861ba25889b");
project.AddAction(new ElevatedManagedAction(
CustomActions.DoAction,
Return.check,
When.After,
Step.InstallInitialize,
null));
project.BuildMsi();
}
}
public class CustomActions
{
[CustomAction]
public static ActionResult DoAction(Session session)
{
var baseKey = RegistryExtensions.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64);
var key = baseKey.OpenSubKey(@"SOFTWARE\My Company\My Product");
key.GetValue(...);
key.SetValue(...);
return ActionResult.Success;
}
}
}
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
using System;
using System.ComponentModel;
using System.Reflection;
using System.Runtime.InteropServices;
namespace WixSharp
{
public enum RegistryView
{
Default = 0,
Registry64 = RegistryExtensions.RegistryAccessMask.Wow6464,
Registry32 = RegistryExtensions.RegistryAccessMask.WoW6432
};
public static class RegistryExtensions
{
[Flags]
internal enum RegistryAccessMask
{
QueryValue = 0x0001,
SetValue = 0x0002,
CreateSubKey = 0x0004,
EnumerateSubKeys = 0x0008,
Notify = 0x0010,
CreateLink = 0x0020,
WoW6432 = 0x0200,
Wow6464 = 0x0100,
Write = 0x20006,
Read = 0x20019,
Execute = 0x20019,
AllAccess = 0xF003F
}
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
private static extern int RegOpenKeyEx(
UIntPtr hKey,
string subKey,
uint ulOptions,
uint samDesired,
out IntPtr hkResult);
public static RegistryKey OpenBaseKey(Microsoft.Win32.RegistryHive registryHive, RegistryView registryType)
{
var openBaseKey = typeof(RegistryKey).GetMethod("OpenBaseKey", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(Microsoft.Win32.RegistryHive), typeof(RegistryKey).Assembly.GetType("Microsoft.Win32.RegistryView") ?? typeof(int) }, null);
if (openBaseKey != null)
return (RegistryKey)openBaseKey.Invoke(null, new object[] { registryHive, registryType });
var hiveKey = new UIntPtr((uint)registryHive);
RegistryAccessMask flags = RegistryAccessMask.QueryValue | RegistryAccessMask.EnumerateSubKeys | RegistryAccessMask.SetValue | RegistryAccessMask.CreateSubKey | (RegistryAccessMask)registryType;
var result = RegOpenKeyEx(hiveKey, string.Empty, 0, (uint)flags, out var keyHandlePointer);
if (result == 0)
{
var safeRegistryHandleType = typeof(SafeHandleZeroOrMinusOneIsInvalid).Assembly.GetType("Microsoft.Win32.SafeHandles.SafeRegistryHandle");
var safeRegistryHandleConstructor = safeRegistryHandleType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(IntPtr), typeof(bool) }, null); // .NET < 4
var keyHandle = safeRegistryHandleConstructor.Invoke(new object[] { keyHandlePointer, true });
var net3Constructor = typeof(RegistryKey).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { safeRegistryHandleType, typeof(bool) }, null);
return (RegistryKey)net3Constructor.Invoke(new object[] { keyHandle, true });
}
if (result == 2) return null; // The key does not exist.
throw new Win32Exception(result);
}
public static RegistryKey CreateSubKey(this RegistryKey that, string subkey, bool writable)
{
return that.CreateSubKey(subkey, writable ? RegistryKeyPermissionCheck.ReadWriteSubTree : RegistryKeyPermissionCheck.ReadSubTree);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment