/// <summary> /// Applies content of <paramref name="pathToManifest"/> file to current context, invokes <paramref name="thingToDo"/> delegate, deactivates applied context. /// </summary> /// <param name="pathToManifest"></param> /// <param name="thingToDo"></param> /// <exception cref="FileNotFoundException"></exception> public static void UsingManifestDo(string pathToManifest, doSomething thingToDo) { var context = new ACTCTX(); context.cbSize = Marshal.SizeOf(typeof(ACTCTX)); bool wrongContextStructure = (context.cbSize != 0x20 && IntPtr.Size == 4) // ensure stucture is right on 32 bits || (context.cbSize != 52 && IntPtr.Size == 8); // the same for 64 bits if (wrongContextStructure) { throw new Exception("ACTCTX.cbSize is wrong"); } context.lpSource = pathToManifest; IntPtr hActCtx = NativeMethods.CreateActCtx(ref context); if (hActCtx == Constants.INVALID_HANDLE_VALUE) { var error = Marshal.GetLastWin32Error(); if (error == SYSTEM_ERROR_CODES.ERROR_FILE_NOT_FOUND) { throw new System.IO.FileNotFoundException("Failed to find manifest", pathToManifest); } throw new Win32Exception(error); } try // with valid hActCtx { IntPtr cookie = IntPtr.Zero; if (!NativeMethods.ActivateActCtx(hActCtx, out cookie)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } try // with activated context { thingToDo(); } finally { NativeMethods.DeactivateActCtx(0, cookie); } } finally { NativeMethods.ReleaseActCtx(hActCtx); } }
internal extern static IntPtr CreateActCtx(ref ACTCTX actctx);
internal static extern IntPtr CreateActCtx(ref ACTCTX actctx);