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

Wpf TaskDialog引发异常:需要版本6中的comctl32.dll,wpf,windows-api-code-pack,taskdialog,Wpf,Windows Api Code Pack,Taskdialog,我正在开发一个现代WPF应用程序。我想使用TaskDialog,但总是会出现常见错误: TaskDialog功能需要加载comctl32.dll的版本6,但 内存中当前加载了不同的版本 我试图添加一个清单(它已经包含正确的comctl32.dll所需的依赖项),并在项目属性中将其设置为默认清单 它仍然抛出此异常:-/ 我的应用程序是这样构建的: 它是一个启动应用程序(普通Windows应用程序,非wpf)。它只有“Program.cs”作为入口点。它在那里动态加载真实的应用程序(它是一个库,而不

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

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

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

它仍然抛出此异常:-/

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

效果很好,但我总是遇到这个例外。我想这是因为这个启动系统。。。但有什么可能的解决办法来修复它呢

非常感谢:)


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

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

我刚开始工作,所以我的代码有点凌乱和油腻

来源:

[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
}
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 );
}
  • 1)按照上面第二个链接的方式包括EnableThemingScope类。

    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
    }
    
    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 );
    }
    
    3。简单地说:

    [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
    }
    
    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。结果:

    [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
    }
    
    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 );
    }
    

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


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

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

    你为什么要这么做?为什么不让一个常规的WPF应用程序由
    System.Windows.application
    启动呢?我猜winforms(或者你之前加载的任何东西)正在加载一堆WPF不关心的古老垃圾。好吧,这个系统是我之前遇到的一个bug的一部分。我刚改变了系统。它现在通过一个真正的WPF项目启动。还是不行。如果我激活“系统自己的调试”,我不会得到任何执行选项,对话框将打开。唯一的错误是:缺少图标:-/这可能是MS Api代码包中的一个问题吗?您是正确的,这是Api本身的一个错误:可能与我得到的异常重复,入口点“TaskDialog”在comctl.dll中找不到:-/我也不喜欢这样的事实,即这种方式锁定了设置进度条或其他控件的可能性:-/但感谢您的回答:)我还发现了这样一个问题:因此,可能这是Visual Studio本身的一个缺陷。正如我所说,在发布模式下,它工作得很好(唯一的问题是缺少图标)..@Razer对于进度条之类的东西,您必须使用TaskDialogIndirect。在\source\WindowsAPICodePack\Core\Interop\TaskDialogs\TaskDialogNativeMethods.cs中查看该Windows®API代码包的源代码。但是它要复杂得多,所以我没有一个简单的解决方案。至于例外情况,我不知道发生了什么。确保您的DllImport线路与步骤2中的线路完全相同。如果已经是这样了。。。那么我不确定:(.不客气!使用上的EnableThemingScope类,因为它已修复了在现已失效的kb/830033链接中发现的内容。另请参见此处:似乎是问题的合理答案…只要我仍然能够调试应用程序,这应该是一个可能的修复。我将很快对其进行测试。好的,这很奇怪…现在它工作正常。我没有触摸该项目大约半年。现在它运行良好,无需禁用托管进程。可能问题已通过许多Windows/Visual Studio更新之一修复。