4

シンプルなスタンドアロンの .net winforms アプリを作成しています。Microsoft.SqlServer.SqlWmiManagementクライアントのマシンに存在する場合と存在しない場合がある .Net Framework 4のアセンブリを参照します。そのアセンブリが存在しない場合、実行時にアプリが正常に失敗し、クラッシュしないようにします。

開始するコンポーネントがあります:

...
using Microsoft.SqlServer.SqlWmiManagement;
...
try {
    // do something that uses SqlWmiManagement
}
catch {
    // handle the missing assembly
}

残念ながら、コンポーネントが読み込まれると、小さな try ブロックの前に未処理の例外がスローされます。

これを行う正しい方法は何ですか?

インストーラーはありません。これはドラッグ アンド ドロップの exe である必要があります。

4

5 に答える 5

7

アセンブリが見つからない場合は、AssemblyResolve イベントが発生します。それをキャッチして、そこでアプリを終了してみてください。この MSDN を参照してください

public static void Main()
{
    // Note: AssemblyResolve occurs when the resolution of an assembly fails.
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);
}

private static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
{
    if ( args.Name.Contains("SqlWmiManagement"))
    {
        // assembly not found
    }

    return null;
}
于 2013-02-28T23:45:20.013 に答える
2

Main() 関数を含むクラスがアセンブリに関連するものを参照していないことを確認してください。

メイン フォームの一部として定義されている場合は、独自のクラスに取り出します。

次に、メソッドの最初で Assembly.Load() を使用します。SqlWmiManagement.dll アセンブリの完全修飾名をパラメーターとして渡す必要があります。

于 2013-02-28T23:53:42.777 に答える
2

コードのスコープを修正することでこれを解決したと思います。この記事からの作業:

https://sites.google.com/site/craigandera/craigs-stuff/clr-workings/dealing-with-assembly-load-failure

必要なメソッドをMicrosoft.SqlServer.SqlWmiManagement別のクラスに移動しました。try {}それを分離することは、アセンブリを暗黙的にロードするスコープの前に開始するブロック内から呼び出すことができることを意味します。つまり、失敗したアセンブリの読み込みから例外をキャッチできます。

それ以外の:

using Microsoft.SqlServer.SqlWmiManagement;

// .net implicitly loads assembly when current class is instantiated

// ... code ...

try {
   // problem method using missing assembly
} 
catch {
   // this is ineffective because the ass'y load already failed before the try block
}

私はできました:

try {
    // invoke problem method in another class
    // implicitly loads assembly here instead, inside the try block 
} 
catch {
    // this now catches ass'y load failure
}
于 2013-03-01T20:33:20.723 に答える
2

関数が JIT されると、例外がスローされます。コードを次のように変更します。

void DoSomethingThatUsesSqlWmiManagement_()
{
   ...
}
void DoSomethingThatUsesSqlWmiManagement()
{
   try
   { 
          DoSomethingThatUsesSqlWmiManagement_();
   }
   catch
   {   
            handle the missing assembly
   }
}

おそらくcatch、特定のException.

于 2013-02-28T23:44:10.703 に答える