2017-05-17 5 views
-1

私はWinforms C#アプリケーションを開発しました。他のすべての申請書式(主なものを含む)はそれを必要としません。私は、参照されたDLLが存在するかどうかをプログラムの開始時に確認し、それが真である場合にのみその特定のフォームを作成/ロードすることができるようにしたい。どうすればいい?現在の状態では、dllが存在しない場合、起動中にアプリケーションがクラッシュします。 ありがとう参照されたDLLが存在する場合にのみC#でフォームを作成する方法

+2

(https://code.msdn.microsoft.com/windowsdesktop/Creating-a-simple-plugin-b6174b62)[プラグインスタイルのアーキテクチャを作成する]に見て。参照:https://msdn.microsoft.com/en-us/library/ms972962.aspx?f=255&MSPPError=-2147217396 –

+0

[Delay loading in c#?]の可能な複製(http://stackoverflow.com/questions)/8344893/delay-loading-in-c) – GSerg

答えて

0

ネイティブインポートとは異なり、C#は依存アセンブリのすべての読み込みを動的に行います。依存コードの失敗により、ユーザコードが実行される前にプログラムがクラッシュする可能性はありますが、それは非常にまれです。

Main関数(通常はProgram.cs)を呼び出すには、クラスメンバーに使用されるすべての型およびMain(string[] args)が使用する型をランタイムで解決する必要があります。 Main(フォームコンストラクターなど)から呼び出される関数で使用される型は、Mainが実行を開始してその関数に到達するまではロードされません。

ほとんどの場合、DLLのロードに関連する例外はTypeLoadExceptionInnerExceptionプロパティとして表示されます。 TypeLoadExceptionが発生したときにデバッガを中断し、コールスタックをチェックします。そうすれば、try/catchをどこに追加するかを知ることができます。そして、実際に "開始中に"起きた場合は、Program.cs(または、Mainがどこに住んでいても、移動しました)

TypeLoadExceptionはキャッチすることができますが、コンパイルに失敗した関数を使用することはできませんが、他のクラスを使用することはできます。コンパイルできなかった関数です。あなたは、明示的な読み込みやアセンブリで何かトリックをする必要はありません。ここで

は、いずれかのクラス全体が(EarlyDependency)をロードまたはMethodALateDependency)を除いて使用できるように、クラス全体を許可するために失敗します使用方法の説明図である。

class ClassA : EarlyDependency, IComparable<EarlyDependency> 
{ 
    EarlyDependency field; 
    property EarlyDependency PropertyA { get; set; } 

    int initialized = new EarlyDependency().Calculate(); 
    int initializedB = LateDependency.LiteralConstant; 

    static ClassA 
    { 
     EarlyDependency localInStaticConstructor; 
    } 

    public ClassA() 
    { 
     EarlyDependency localInInstanceConstructor; 

     if (new Random().NextDouble() < .000001) { 
      try { 
       // you can't catch inside the function that fails to compile 
       // because code inside that function can't ever run 
       UsedByConstructor(); 
      } 
      catch (TypeLoadException) 
      { 
      } 
     } 
    } 

    public EarlyDependency MethodWithReturnType(); 
    public static EarlyDependency StaticMethodWithReturnType(); 

    public void MethodWithParameter(EarlyDependency parameter); 

    public void UseIt() 
    { 
     LateDependency localInNonSpecialMethod; 
    } 

    public void Safe() 
    { 
     try { 
      // you can't catch inside the function that fails to compile 
      // because code inside that function can't ever run 
      UseIt(); 
     } 
     catch (TypeLoadException) 
     { 
     } 
    } 

    public static void UseItSomeMore() 
    { 
     LateDependency localInStaticMethod; 
    } 

    private void UsedByConstructor() 
    { 
     LateDependency localInMethodNamedInConstructor; 
    } 
} 
-1

あなたがいるかどうかを確認できファイルが存在し、存在する場合は、フォームを作成/ロードします。

if(File.Exists("myLibrary.dll") 
{ 
    MyForm frm = new MyForm(); 
    frm.ShowDialog(); 
} 

もちろん、正しいパスを探していることを確認する必要があります。

+0

これは動作しません。 'MyForm'はアセンブリをロードするために' myLibrary.dll'への参照を必要としていました。これを行うには、リフレクションを使用してフォームをインスタンス化する必要があります。 – Enigmativity

+1

@Enigmativity:あなたは間違っています、JITはアセンブリ全体、必要に応じて各タイプのみ、必要に応じて各クラスをプリコンパイルしません。他のDLLで見つかったタイプのメンバー変数がある場合、またはそのタイプがメソッドシグネチャ(パラメータタイプまたは戻りタイプ)として表示される場合、タイプは実際に使用するより前のコンパイルプロセスで必要になりますが、ローカル関数内の変数は、その関数が実際に呼び出されるまでアセンブリのロードをトリガーしません。 –

+0

@BenVoigt - 私は、このコードのすべてのバリエーションを完全にテストして、動作させるかどうかを確認する必要があります。 – Enigmativity

0

参照DLLが存在することを確認し、表示するフォームを含む別のアセンブリを動的にロードする必要があります。あなたが正常にアセンブリをロードしようとすると、アプリケーションはあなたが記述した方法でクラッシュします。

このような何かを試してみてください:

if (File.Exists("Referenced.dll") 
{ 
    var assembly = Assembly.LoadFile("AssemblyContainingFormThatReferencesReferenced.dll"); 
    var type = assembly.GetType("TheForm"); 
    var form = Activator.CreateInstance(type) as Form; 
    form.ShowDialog(); 
} 
+0

'File.Exists'は、アセンブリが見つかった場所をすべてチェックしません。ロードして、例外が発生した場合にキャッチする方がいいです(なぜなら、 'Assembly.Load'の' TryXYZ'バージョンがないからです)。 –

+0

@BenVoigt - 私はOPが特定の場所にある特定のDLLの存在をチェックします。 – Enigmativity

+0

OPの正確な状況はわかりませんが、この例のようなユースケースが考えられます。プログラムはデータを生成し、「CSVへのエクスポート」と「Excelへのエクスポート」のボタンがあります。 Excelエクスポートを実行する場合、アプリケーションはExcel.Workbookクラスを使用してファイルを作成し、CSVをエクスポートするには.NETに組み込まれたFile.WriteAllText関数を使用します。ユーザーにOfficeがインストールされていない場合、もちろんExcel.Workbookクラスは使用できませんが、プログラムの実行と「CSVへのエクスポート」オプションの実行を妨げません。 –

関連する問題