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的主要内容,如果未能解决你的问题,请参考以下文章