using System; using System.IO; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Windows.Forms; namespace JD.MessageService { // http://support.microsoft.com/kb/830033 // http://stackoverflow.com/questions/1612351/entrypointnotfoundexception-when-using-taskdialog-in-c-sharp [SuppressUnmanagedCodeSecurity] internal class EnableThemingInScope : IDisposable { #region Variables private UIntPtr m_cookie; private static ACTCTX ms_enableThemingActivationContext; private static IntPtr ms_hActCtx; private static bool ms_contextCreationSucceeded; #endregion public EnableThemingInScope() { m_cookie = UIntPtr.Zero; if (OSFeature.Feature.IsPresent(OSFeature.Themes)) { if (EnsureActivateContextCreated()) { if (!ActivateActCtx(ms_hActCtx, out m_cookie)) { // Be sure cookie always zero if activation failed m_cookie = UIntPtr.Zero; } } } } ~EnableThemingInScope() { Dispose(false); } void IDisposable.Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { if (m_cookie != UIntPtr.Zero) { if (DeactivateActCtx(0, m_cookie)) { // deactivation succeeded... m_cookie = UIntPtr.Zero; } } } private static bool EnsureActivateContextCreated() { if (!ms_contextCreationSucceeded) { // Pull manifest from the .NET Framework install // directory string assemblyLoc; FileIOPermission fiop = new FileIOPermission(PermissionState.None) { AllFiles = FileIOPermissionAccess.PathDiscovery }; fiop.Assert(); try { assemblyLoc = typeof(Object).Assembly.Location; } finally { CodeAccessPermission.RevertAssert(); } string manifestLoc = null; string installDir = null; if (assemblyLoc != null) { installDir = Path.GetDirectoryName(assemblyLoc); const string manifestName = "XPThemes.manifest"; manifestLoc = Path.Combine(installDir, manifestName); } if (manifestLoc != null && installDir != null) { ms_enableThemingActivationContext = new ACTCTX { cbSize = Marshal.SizeOf(typeof(ACTCTX)), lpSource = manifestLoc, lpAssemblyDirectory = installDir, dwFlags = ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID }; // Set the lpAssemblyDirectory to the install // directory to prevent Win32 Side by Side from // looking for comctl32 in the application // directory, which could cause a bogus dll to be // placed there and open a security hole. // Note this will fail gracefully if file specified // by manifestLoc doesn't exist. ms_hActCtx = CreateActCtx(ref ms_enableThemingActivationContext); ms_contextCreationSucceeded = (ms_hActCtx != new IntPtr(-1)); } } // If we return false, we'll try again on the next call into // EnsureActivateContextCreated(), which is fine. return ms_contextCreationSucceeded; } // All the pinvoke goo... [DllImport("Kernel32.dll")] private extern static IntPtr CreateActCtx(ref ACTCTX actctx); [DllImport("Kernel32.dll")] private extern static bool ActivateActCtx(IntPtr hActCtx, out UIntPtr lpCookie); [DllImport("Kernel32.dll")] private extern static bool DeactivateActCtx(uint dwFlags, UIntPtr lpCookie); private const int ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID = 0x004; 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; } } }