# encoding: ascii
# api: csharp
# title: Activation Context API
# description: Functions for entering and exiting an activation context. This provides support for registration free COM in PowerShell.
# version: 0.1
# type: script
# author: Adam Driscoll
# license: CC0
# function: Enter-ActivationContext
# x-poshcode-id: 3826
# x-archived: 2016-04-13T16:31:55
# x-published: 2013-12-14T14:34:00
#
#
<#
By Adam Driscoll
12/14/2012
Twitter: @adamdriscoll
More Information: http://csharpening.net/?p=1427
Description:
Functions for entering and exiting an activation context. This provides support for registration free COM in PowerShell.
#>
Add-Type -TypeDefinition '
namespace Driscoll
{
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
public class ActivationContext
{
IntPtr hActCtx;
uint cookie;
public void CreateAndActivate(string manifest)
{
var actCtx = new ACTCTX();
actCtx.cbSize = Marshal.SizeOf(typeof(ACTCTX));
actCtx.dwFlags = 0;
actCtx.lpSource = manifest;
actCtx.lpResourceName = null;
hActCtx = CreateActCtx(ref actCtx);
if(hActCtx == new IntPtr(-1))
{
throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to create activation context.");
}
if (!ActivateActCtx(hActCtx, out cookie))
{
throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to activate activation context.");
}
}
public void DeactivateAndFree()
{
DeactivateActCtx(0, cookie);
ReleaseActCtx(hActCtx);
}
[DllImport("kernel32.dll")]
private static extern IntPtr CreateActCtx(ref ACTCTX actctx);
[StructLayout(LayoutKind.Sequential)]
private struct ACTCTX
{
public int cbSize;
public uint dwFlags;
public string lpSource;
public ushort wProcessorArchitecture;
public ushort wLangId;
public string lpAssemblyDirectory;
public string lpResourceName;
public string lpApplicationName;
}
[DllImport("Kernel32.dll", SetLastError = true)]
private extern static bool ActivateActCtx(IntPtr hActCtx, out uint lpCookie);
[DllImport("Kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool DeactivateActCtx(int dwFlags, uint lpCookie);
[DllImport("Kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool ReleaseActCtx(IntPtr hActCtx);
private const uint ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID = 0x001;
private const uint ACTCTX_FLAG_LANGID_VALID = 0x002;
private const uint ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID = 0x004;
private const uint ACTCTX_FLAG_RESOURCE_NAME_VALID = 0x008;
private const uint ACTCTX_FLAG_SET_PROCESS_DEFAULT = 0x010;
private const uint ACTCTX_FLAG_APPLICATION_NAME_VALID = 0x020;
private const uint ACTCTX_FLAG_HMODULE_VALID = 0x080;
private const UInt16 RT_MANIFEST = 24;
private const UInt16 CREATEPROCESS_MANIFEST_RESOURCE_ID = 1;
private const UInt16 ISOLATIONAWARE_MANIFEST_RESOURCE_ID = 2;
private const UInt16 ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID = 3;
private const uint FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
private const uint FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
private const uint FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
}
}
'
function Enter-ActivationContext
{
param($manifest)
$global:ActivationContext = New-Object Driscoll.ActivationContext
$global:ActivationContext.CreateAndActivate($manifest)
}
function Exit-ActivationContext
{
$global:ActivationContext.DeactivateAndFree()
}