TaskDialog 引发异常:需要版本 6 中的 comctl32.dll

Posted

技术标签:

【中文标题】TaskDialog 引发异常:需要版本 6 中的 comctl32.dll【英文标题】:TaskDialog fires exception: comctl32.dll in version 6 required 【发布时间】:2013-04-15 16:23:57 【问题描述】:

我正在开发一个现代 WPF 应用程序。我想使用TaskDialog,但总是遇到常见错误:

TaskDialog 功能需要加载版本 6 的 comctl32.dll 但 当前在内存中加载了不同的版本。

我尝试添加一个清单(其中已包含正确 comctl32.dll 所需的依赖项)并将其设置为项目属性中的默认清单。

它仍然抛出这个异常:-/

我的应用程序是这样构建的: 它是一个启动应用程序(普通的 Windows 应用程序,非 wpf)。它只有作为入口点的“Program.cs”。它在那里动态加载真正的应用程序(这是一个库,而不是 WPF 应用程序项目)。它调用它的启动方法来启动应用程序。

效果很好,但我总是遇到这个异常。我想这是因为这个启动系统......但是有什么可能的解决方法来修复它?

非常感谢:)

R

【问题讨论】:

你为什么要这么做?为什么不直接使用以System.Windows.Application 开头的常规 WPF 应用程序呢?我猜winforms(或者你之前加载的任何东西)正在加载一堆WPF不关心的古老废话。 好吧,这个系统是我之前遇到的错误的一部分。我刚换了系统。它现在通过一个真正的 WPF 项目开始。它仍然行不通。如果我激活“系统自己的调试”,我没有得到任何执行并且对话框打开。唯一的错误是:图标丢失:-/ 这可能是 MS Api 代码包中的问题吗? 你是对的,这是 API 本身的一个错误:***.com/questions/22561584/… C#: comctl32.dll version 6 in debugger的可能重复 【参考方案1】:

也许我的解决方案会对你有所帮助。

我的 C#“应用程序”是一个类库/dll,用作 WIX 的 CustomAction。我想要一个 TaskDialog 而不是 MessageBox,但我遇到了和你一样的异常,据我所知,清单文件不适用于 C# 类库。我必须使用多种方法来让我的代码加载正确版本的 comctl32.dll。

我刚刚开始使用它,所以我的代码有点混乱和臃肿。

来源:

    http://truecheaters.com/f51/%5Bc-%5D-taskdialog-9368.html http://support.microsoft.com/kb/830033

1) 包括上面第二个链接中的 EnableThemingInScope 类。

2) 包含这个修改后的 TaskDialog 枚举/类:

[Flags]
public enum TaskDialogButtons 
    OK = 0x0001,
    Cancel = 0x0008,
    Yes = 0x0002,
    No = 0x0004,
    Retry = 0x0010,
    Close = 0x0020


public enum TaskDialogIcon 
    Information = UInt16.MaxValue - 2,
    Warning = UInt16.MaxValue,
    Stop = UInt16.MaxValue - 1,
    Question = 0,
    SecurityWarning = UInt16.MaxValue - 5,
    SecurityError = UInt16.MaxValue - 6,
    SecuritySuccess = UInt16.MaxValue - 7,
    SecurityShield = UInt16.MaxValue - 3,
    SecurityShieldBlue = UInt16.MaxValue - 4,
    SecurityShieldGray = UInt16.MaxValue - 8


public enum TaskDialogResult 
    None,
    OK,
    Cancel,
    Yes,
    No,
    Retry,
    Close


public class StatusDialog 
    #region API
    [DllImport( "comctl32.dll", CharSet = CharSet.Unicode )]
    public static extern int TaskDialog( IntPtr hWndParent, IntPtr hInstance, string pszWindowTitle, string pszMainInstruction, string pszContent, int dwCommonButtons, IntPtr pszIzon, out int pnButton );
    #endregion

    #region Modal
    public static TaskDialogResult Show( IWin32Window owner, string text ) 
        return Show( owner, text, null, null, TaskDialogButtons.OK );
    

    public static TaskDialogResult Show( IWin32Window owner, string text, string instruction ) 
        return Show( owner, text, instruction, null, TaskDialogButtons.OK, 0 );
    

    public static TaskDialogResult Show( IWin32Window owner, string text, string instruction, string caption ) 
        return Show( owner, text, instruction, caption, TaskDialogButtons.OK, 0 );
    

    public static TaskDialogResult Show( IWin32Window owner, string text, string instruction, string caption, TaskDialogButtons buttons ) 
        return Show( owner, text, instruction, caption, buttons, 0 );
    

    public static TaskDialogResult Show( IWin32Window owner, string text, string instruction, string caption, TaskDialogButtons buttons, TaskDialogIcon icon ) 
        return ShowInternal( owner.Handle, text, instruction, caption, buttons, icon );
    
    #endregion

    #region Non-Modal
    public static TaskDialogResult Show( string text ) 
        return Show( text, null, null, TaskDialogButtons.OK );
    

    public static TaskDialogResult Show( string text, string instruction ) 
        return Show( text, instruction, null, TaskDialogButtons.OK, 0 );
    

    public static TaskDialogResult Show( string text, string instruction, string caption ) 
        return Show( text, instruction, caption, TaskDialogButtons.OK, 0 );
    

    public static TaskDialogResult Show( string text, string instruction, string caption, TaskDialogButtons buttons ) 
        return Show( text, instruction, caption, buttons, 0 );
    

    public static TaskDialogResult Show( string text, string instruction, string caption, TaskDialogButtons buttons, TaskDialogIcon icon ) 
        return ShowInternal( IntPtr.Zero, text, instruction, caption, buttons, icon );
    
    #endregion

    #region Core Implementation
    private static TaskDialogResult ShowInternal( IntPtr owner, string text, string instruction, string caption, TaskDialogButtons buttons, TaskDialogIcon icon ) 
        int p;
        using ( new EnableThemingInScope( true ) ) 
            int resss = TaskDialog( owner, IntPtr.Zero, caption, instruction, text, (int) buttons, new IntPtr( (int) icon ), out p );
            if ( resss != 0 )
                throw new InvalidOperationException( "Something weird has happened." + resss.ToString() );
        

        switch ( p ) 
            case 1:
                return TaskDialogResult.OK;
            case 2:
                return TaskDialogResult.Cancel;
            case 4:
                return TaskDialogResult.Retry;
            case 6:
                return TaskDialogResult.Yes;
            case 7:
                return TaskDialogResult.No;
            case 8:
                return TaskDialogResult.Close;
            default:
                return TaskDialogResult.None;
        
    
    #endregion

3.要调用它,只需:

try 
    StatusDialog.Show( "About to test this...", "Heading I won't use.", "Dialog Title", TaskDialogButtons.OK );
 catch ( Exception e ) 
    MessageBox.Show( e.ToString(), "Error Found", MessageBoxButtons.OK );

4.结果:

【讨论】:

我收到一个异常,即在 comctl.dll 中找不到入口点“TaskDialog”:-/ 另外我不喜欢这样的事实,即这种方式锁定了设置进度条等控件的可能性或别的东西:-/但谢谢你的回答:) 我也发现了这个:***.com/questions/1415270/… 所以这可能是 Visual Studio 本身的错误。正如我所说,在发布模式下它工作正常(唯一的是缺少图标)...... @Razer 对于进度条之类的东西,您必须改用 TaskDialogIndirect。在 \source\WindowsAPICodePack\Core\Interop\TaskDialogs\TaskDialogNativeMethods.cs 中查看该 Windows® API 代码包的源代码。虽然它要复杂得多,所以我没有一个简单的解决方案。至于异常,不知道是怎么回事。确保您的 DllImport 行与我在第 2 步中的行完全相同。如果它已经是那样了......那我不确定 :( 。不客气! 使用 ***.com/a/22376552/1703887 的 EnableThemingInScope 类,因为它修复了曾经在现已失效的 kb/830033 链接中找到的内容。【参考方案2】:

运行程序的 *.exe 版本,而不是 Visual Studio *.vshost.exe 的版本

要在 Visual Studio 中执行此操作,请禁用“调试/启用调试器/启用 Visual Studio 托管进程”中的标志

【讨论】:

参见此处:***.com/questions/2069940/… 似乎是对这个问题的一个合乎逻辑的答案......只要我仍然能够调试应用程序,这应该是一个可能的修复。我会尽快测试它。 好的,这很奇怪......现在它工作正常了。我有大约半年没有接触这个项目。现在它运行良好,无需禁用托管进程。也许问题已通过众多 Windows/Visual Studio 更新之一解决。【参考方案3】:

我发现如果您使用“RequireAdministrator”权限运行它会抛出异常,但如果权限“AsInvoker”则不会抛出异常。只是我的观察。如果您的应用程序需要管理员权限,那么我很难过

【讨论】:

以上是关于TaskDialog 引发异常:需要版本 6 中的 comctl32.dll的主要内容,如果未能解决你的问题,请参考以下文章

C#:调试器中的 comctl32.dll 版本 6

异常中的else

ASP.NET Core 2 中的依赖注入引发异常

自 v1.1 起 TaskDialog 中的命令链接中的垂直空间

在引发之前恢复python尝试异常块中的更改

“/”应用程序中的服务器错误。引发类型为“System.OutOfMemoryException”的异常。