wpf - TaskDialog 需要在版本 6 中触发异常 : comctl32. dll

标签 wpf windows-api-code-pack taskdialog

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

TaskDialog feature needs to load version 6 of comctl32.dll but a different version is current loaded in memory.



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

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

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

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

非常感谢 :)

电阻

最佳答案

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

我的 C#“应用程序”是一个类库/dll,用作 WIX 的 CustomAction。我想要一个 TaskDialog 而不是 MessageBox 但我遇到了和你一样的异常,据我所知, list 文件不适用于 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. 结果:

    enter image description here

    关于wpf - TaskDialog 需要在版本 6 中触发异常 : comctl32. dll,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16020136/

    相关文章:

    c# - 在工具提示 WPF 上使用 Storyboard

    C# Backgroundwork 在抛出异常时不调用 e.Error

    vb6 - 选择另一个应用程序中的菜单项

    c# - 在任务对话框中使用隐藏的安全图标

    c++ - 没有按钮的任务对话框

    wpf - 如何通过 generic.xaml 中定义的键访问资源

    wpf - 如何以编程方式删除 WPF 中的控件(例如组框)?

    c# - IShellItemImageFactory Icon\Thumbnails 不同于 Windows 7 桌面

    c# - 通过Windows API代码包获取网络DWG文件的缩略图