6

私は最新の WPF アプリケーションを開発しています。TaskDialog を使用したいのですが、常に一般的なエラーが発生します。

TaskDialog 機能はバージョン 6 の comctl32.dll をロードする必要がありますが、現在別のバージョンがメモリにロードされています。

マニフェスト (適切な comctl32.dll に必要な依存関係が既に含まれている) を追加して、プロジェクト プロパティで既定のマニフェストとして設定しようとしました。

それでもこの例外がスローされます:-/

私のアプリケーションは次のように構築されています: これは、スタートアップ アプリケーション (通常の Windows アプリケーション、非 wpf) です。エントリポイントである「Program.cs」のみがあります。そこで実際のアプリケーション (これはライブラリであり、WPF アプリ プロジェクトではありません) を動的にロードします。アプリケーションを起動する起動メソッドを呼び出します。

うまく機能しますが、常にこの例外が発生します。この起動システムが原因だと思います...しかし、それを修正するための可能な回避策は何ですか?

どうもありがとう :)

R

4

3 に答える 3

3

多分私の解決策があなたを助けるでしょう。

私の C#「アプリケーション」は、WIX の CustomAction として使用されるクラス ライブラリ/DLL です。MessageBox の代わりに TaskDialog が必要でしたが、あなたと同じ例外に遭遇しました。私の知る限り、マニフェスト ファイルは C# クラス ライブラリでは機能しません。コードが適切なバージョンの comctl32.dll をロードするようにするには、いくつかの組み合わせを使用する必要がありました。

私はそれを機能させたばかりなので、私のコードは少し乱雑で太っています。

ソース:

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

1) 上記の 2 番目のリンクから 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. 結果:

ここに画像の説明を入力

于 2013-05-11T05:45:53.967 に答える
3

Visual Studio *.vshost.exe のプログラムではなく、プログラムの *.exe バージョンを実行します。

Visual Studio でこれを行うには、「デバッグ / デバッガーを有効にする / Visual Studio ホスティング プロセスを有効にする」のフラグを無効にします。

于 2013-09-19T13:09:42.260 に答える