C#:在调试COMCTL32.DLL版本6 [英] C#: comctl32.dll version 6 in debugger

查看:289
本文介绍了C#:在调试COMCTL32.DLL版本6的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是 WindowsAPICodePack 以TaskDialog其实。当我尝试显示对话框它说,它需要加载的COMCTL32.DLL版本6。所以我加了版本6到app.manifest并试图运行它。仍然没有运气。我去了Debug文件夹和运行程序没有Visual Studio和它工作正常。我猜,Visual Studio是不使用清单文件......我想知道是否有办法让它做到这一点。


解决方案

Robpol86,你的代码抛出SEHExceptions,因为ActivateActCtx和DeactivateActCtx签名是不正确的。你必须使用 UIntPtr 而不是 UINT 为lpCookie。



因此,EnableThemingInScope.cs正确的代码是:



<预类=郎-CS prettyprint-覆盖> 使用系统;
:使用System.IO;使用System.Runtime.InteropServices
;
使用System.Security;使用System.Security.Permissions
;使用System.Windows.Forms的
;

命名空间Microsoft.WindowsAPICodePack.Dialogs
{
/// http://support.microsoft.com/kb/830033
///< devdoc>
///这个类是为了与C#'使用'声明
///用来激活激活上下文在
///的开始打开视觉主题化适用范围,并自动在范围退出停用
///。
///< / devdoc>

[SuppressUnmanagedCodeSecurity]
内部类EnableThemingInScope:IDisposable的
{
//私有数据
私人UIntPtr饼干;
私有静态ACTCTX enableThemingActivationContext;
[System.Diagnostics.CodeAnalysis.SuppressMessage(Microsoft.Reliability,CA2006:UseSafeHandleToEncapsulateNativeResources)]
私有静态的IntPtr hActCtx;
私人静态布尔contextCreationSucceeded = FALSE;

公共EnableThemingInScope(BOOL启用)
{
饼干= UIntPtr.Zero;
如果(启用&安培;&安培; OSFeature.Feature.IsPresent(OSFeature.Themes))!
{
如果(EnsureActivateContextCreated())
{
如果(ActivateActCtx (hActCtx,退出cookie))
{
//一定的cookie始终为零,如果激活失败
饼干= UIntPtr.Zero;
}
}
}
}

〜EnableThemingInScope()
{
的Dispose();
}

无效IDisposable.Dispose()
{
的Dispose();
GC.SuppressFinalize(本);
}

私人无效的Dispose()
{
如果(饼干!= UIntPtr.Zero)
{

{
如果(DeactivateActCtx(0,饼干))
{
//去激活成功...
饼干= UIntPtr.Zero;
}
}
赶上(SEHException)
{
//希望解决这个异常
}
}
}

[System.Diagnostics.CodeAnalysis.SuppressMessage(Microsoft.Reliability,CA2002:DoNotLockOnObjectsWithWeakIdentity)]
私人静态布尔EnsureActivateContextCreated()
{
锁(typeof运算(EnableThemingInScope))
{
如果(!contextCreationSucceeded)
{
//拉出清单从.NET框架安装
//目录

字符串assemblyLoc = NULL;

的FileIOPermission fiop =新的FileIOPermission(PermissionState.None);
fiop.AllFiles = FileIOPermissionAccess.PathDiscovery;
fiop.Assert();

{
assemblyLoc = typeof运算(对象).Assembly.Location;
}
终于
{
CodeAccessPermission.RevertAssert();
}

字符串manifestLoc = NULL;
字符串INSTALLDIR = NULL;
如果(assemblyLoc!= NULL)
{
INSTALLDIR = Path.GetDirectoryName(assemblyLoc);
常量字符串manifestName =XPThemes.manifest;
manifestLoc = Path.Combine(INSTALLDIR,manifestName);
}

如果(manifestLoc = NULL&放大器;!&安培;!INSTALLDIR = NULL)
{
enableThemingActivationContext =新ACTCTX();
enableThemingActivationContext.cbSize = Marshal.SizeOf(typeof运算(ACTCTX));
enableThemingActivationContext.lpSource = manifestLoc;

//设置lpAssemblyDirectory到安装
//目录防止的Win32并排从
//寻找在应用
//目录COMCTL32,这可能导致虚假的dll是
//摆在那里,并打开一个安全漏洞。
enableThemingActivationContext.lpAssemblyDirectory = INSTALLDIR;
enableThemingActivationContext.dwFlags = ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID;

//请注意,如果指定的文件
//通过manifestLoc不存在,这将优雅地失败。
hActCtx = CreateActCtx(REF enableThemingActivationContext);
contextCreationSucceeded =(hActCtx =新的IntPtr(-1)!);
}
}

//如果返回false,我们将在下次调用到
// EnsureActivateContextCreated(),这是罚款再试一次。
返回contextCreationSucceeded;
}
}

//所有的PInvoke咕...
函数[DllImport(Kernel32.dll中)]
私有外部静态的IntPtr CreateActCtx (参考ACTCTX actctx);
函数[DllImport(Kernel32.dll中)]
私有外部静态布尔ActivateActCtx(IntPtr的hActCtx,出UIntPtr lpCookie);
函数[DllImport(Kernel32.dll中)]
私有外部静态布尔DeactivateActCtx(UINT dwFlags中,UIntPtr lpCookie);

私人const int的ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID =量0x004;

私人结构ACTCTX
{
公众诠释CBSIZE;
公共UINT dwFlags中;
公共字符串lpSource;
公共USHORT wProcessorArchitecture;
公共USHORT符wLangid;
公共字符串lpAssemblyDirectory;
公共字符串lpResourceName;
公共字符串lpApplicationName;
}
}
}


I'm using the WindowsAPICodePack for TaskDialog. When I try to show the dialog it says that it needs to load version 6 of comctl32.dll. So I added version 6 to the app.manifest and tried running it. Still no luck. I went to the Debug folder and ran the program without Visual Studio and it works fine. I'm guessing that Visual Studio isn't using the manifest file... I was wondering if there was a way to make it do this.

解决方案

Robpol86, your code is throwing SEHExceptions, because the signatures for ActivateActCtx and DeactivateActCtx are not correct. You have to use UIntPtr instead of uint for the lpCookie.

Therefore, the correct code for EnableThemingInScope.cs would be:

using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Windows.Forms;

namespace Microsoft.WindowsAPICodePack.Dialogs
{
    /// http://support.microsoft.com/kb/830033
    /// <devdoc>
    ///     This class is intended to use with the C# 'using' statement in
    ///     to activate an activation context for turning on visual theming at
    ///     the beginning of a scope, and have it automatically deactivated
    ///     when the scope is exited.
    /// </devdoc>

    [SuppressUnmanagedCodeSecurity]
    internal class EnableThemingInScope : IDisposable
    {
        // Private data
        private UIntPtr cookie;
        private static ACTCTX enableThemingActivationContext;
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources")]
        private static IntPtr hActCtx;
        private static bool contextCreationSucceeded = false;

        public EnableThemingInScope(bool enable)
        {
            cookie = UIntPtr.Zero;
            if (enable && OSFeature.Feature.IsPresent(OSFeature.Themes))
            {
                if (EnsureActivateContextCreated())
                {
                    if (!ActivateActCtx(hActCtx, out cookie))
                    {
                        // Be sure cookie always zero if activation failed
                        cookie = UIntPtr.Zero;
                    }
                }
            }
        }

        ~EnableThemingInScope()
        {
            Dispose();
        }

        void IDisposable.Dispose()
        {
            Dispose();
            GC.SuppressFinalize(this);
        }

        private void Dispose()
        {
            if (cookie != UIntPtr.Zero)
            {
                try
                {
                    if (DeactivateActCtx(0, cookie))
                    {
                        // deactivation succeeded...
                        cookie = UIntPtr.Zero;
                    }
                }
                catch (SEHException)
                {
                    //Hopefully solved this exception
                }
            }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2002:DoNotLockOnObjectsWithWeakIdentity")]
        private static bool EnsureActivateContextCreated()
        {
            lock (typeof(EnableThemingInScope))
            {
                if (!contextCreationSucceeded)
                {
                    // Pull manifest from the .NET Framework install
                    // directory

                    string assemblyLoc = null;

                    FileIOPermission fiop = new FileIOPermission(PermissionState.None);
                    fiop.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)
                    {
                        enableThemingActivationContext = new ACTCTX();
                        enableThemingActivationContext.cbSize = Marshal.SizeOf(typeof(ACTCTX));
                        enableThemingActivationContext.lpSource = manifestLoc;

                        // 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.
                        enableThemingActivationContext.lpAssemblyDirectory = installDir;
                        enableThemingActivationContext.dwFlags = ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID;

                        // Note this will fail gracefully if file specified
                        // by manifestLoc doesn't exist.
                        hActCtx = CreateActCtx(ref enableThemingActivationContext);
                        contextCreationSucceeded = (hActCtx != new IntPtr(-1));
                    }
                }

                // If we return false, we'll try again on the next call into
                // EnsureActivateContextCreated(), which is fine.
                return 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;
        }
    }
}

这篇关于C#:在调试COMCTL32.DLL版本6的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆