TaskDialog запускает исключение: требуется comctl32.dll в версии 6
Я занимаюсь разработкой современного приложения WPF. Я хочу использовать TaskDialog, но я всегда получаю общую ошибку:
Функция TaskDialog должна загрузить версию 6 файла comctl32.dll, но в данный момент в памяти загружена другая версия.
Я попытался добавить манифест (который уже содержит требуемую зависимость для правильного comctl32.dll) и установить его в качестве манифеста по умолчанию в свойствах проекта.
Это все еще бросает это исключение:-/
Мое приложение построено так: это запускаемое приложение (обычное приложение Windows, не-wpf). Он имеет только "Program.cs", который является точкой входа. Там он динамически загружает реальное приложение (которое является библиотекой, а не проектом приложения WPF). Он вызывает метод запуска, который запускает приложение.
Прекрасно работает, но я всегда получаю это исключение. Я предполагаю, что это из-за этой системы запуска... но какой был бы возможный обходной путь, чтобы исправить это?
Большое спасибо:)
р
3 ответа
Запустите *.exe версию вашей программы, а не ту для Visual Studio *.vshost.exe
Для этого в Visual Studio отключите флажок "Отладка / Включить отладчики / Включить процесс размещения Visual Studio"
Может быть, мое решение поможет вам.
"Приложение" моего C# - это библиотека классов / dll, используемая как CustomAction для WIX. Я хотел TaskDialog вместо MessageBox, но столкнулся с тем же исключением, что и вы, и, насколько мне известно, файлы манифеста не работают для библиотек классов C#. Мне пришлось использовать комбинацию вещей, чтобы получить мой код для загрузки правильной версии comctl32.dll.
Я только что заработал, поэтому мой код немного грязный и жирный.
Источники:
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. Результат:
Я обнаружил, что если вы запускаете с разрешением "RequireAdministrator", он выдает исключение, но не выдает исключение, если разрешение "AsInvoker". Просто мои наблюдения. Если ваше приложение требует прав администратора, то я в тупике