私はWinforms C#アプリケーションを開発しました。他のすべての申請書式(主なものを含む)はそれを必要としません。私は、参照されたDLLが存在するかどうかをプログラムの開始時に確認し、それが真である場合にのみその特定のフォームを作成/ロードすることができるようにしたい。どうすればいい?現在の状態では、dllが存在しない場合、起動中にアプリケーションがクラッシュします。 ありがとう参照されたDLLが存在する場合にのみC#でフォームを作成する方法
答えて
ネイティブインポートとは異なり、C#は依存アセンブリのすべての読み込みを動的に行います。依存コードの失敗により、ユーザコードが実行される前にプログラムがクラッシュする可能性はありますが、それは非常にまれです。
Main
関数(通常はProgram.cs)を呼び出すには、クラスメンバーに使用されるすべての型およびMain(string[] args)
が使用する型をランタイムで解決する必要があります。 Main
(フォームコンストラクターなど)から呼び出される関数で使用される型は、Main
が実行を開始してその関数に到達するまではロードされません。
ほとんどの場合、DLLのロードに関連する例外はTypeLoadException
にInnerException
プロパティとして表示されます。 TypeLoadException
が発生したときにデバッガを中断し、コールスタックをチェックします。そうすれば、try/catchをどこに追加するかを知ることができます。そして、実際に "開始中に"起きた場合は、Program.cs
(または、Main
がどこに住んでいても、移動しました)
TypeLoadException
はキャッチすることができますが、コンパイルに失敗した関数を使用することはできませんが、他のクラスを使用することはできます。コンパイルできなかった関数です。あなたは、明示的な読み込みやアセンブリで何かトリックをする必要はありません。ここで
は、いずれかのクラス全体が(EarlyDependency
)をロードまたはMethodA
(LateDependency
)を除いて使用できるように、クラス全体を許可するために失敗します使用方法の説明図である。
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;
}
}
あなたがいるかどうかを確認できファイルが存在し、存在する場合は、フォームを作成/ロードします。
if(File.Exists("myLibrary.dll")
{
MyForm frm = new MyForm();
frm.ShowDialog();
}
もちろん、正しいパスを探していることを確認する必要があります。
これは動作しません。 'MyForm'はアセンブリをロードするために' myLibrary.dll'への参照を必要としていました。これを行うには、リフレクションを使用してフォームをインスタンス化する必要があります。 – Enigmativity
@Enigmativity:あなたは間違っています、JITはアセンブリ全体、必要に応じて各タイプのみ、必要に応じて各クラスをプリコンパイルしません。他のDLLで見つかったタイプのメンバー変数がある場合、またはそのタイプがメソッドシグネチャ(パラメータタイプまたは戻りタイプ)として表示される場合、タイプは実際に使用するより前のコンパイルプロセスで必要になりますが、ローカル関数内の変数は、その関数が実際に呼び出されるまでアセンブリのロードをトリガーしません。 –
@BenVoigt - 私は、このコードのすべてのバリエーションを完全にテストして、動作させるかどうかを確認する必要があります。 – Enigmativity
参照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();
}
'File.Exists'は、アセンブリが見つかった場所をすべてチェックしません。ロードして、例外が発生した場合にキャッチする方がいいです(なぜなら、 'Assembly.Load'の' TryXYZ'バージョンがないからです)。 –
@BenVoigt - 私はOPが特定の場所にある特定のDLLの存在をチェックします。 – Enigmativity
OPの正確な状況はわかりませんが、この例のようなユースケースが考えられます。プログラムはデータを生成し、「CSVへのエクスポート」と「Excelへのエクスポート」のボタンがあります。 Excelエクスポートを実行する場合、アプリケーションはExcel.Workbookクラスを使用してファイルを作成し、CSVをエクスポートするには.NETに組み込まれたFile.WriteAllText関数を使用します。ユーザーにOfficeがインストールされていない場合、もちろんExcel.Workbookクラスは使用できませんが、プログラムの実行と「CSVへのエクスポート」オプションの実行を妨げません。 –
- 1. ファイルが存在しない場合にのみ作成する
- 2. オブジェクトが存在する場合でもCodedUI null参照例外
- 3. Visual Studioソリューションフォルダに参照されたDLLを保存する
- 4. フォームの値が存在する場合にのみ更新フィールド
- 5. Xamrinがカルーセルビューに存在しない参照を作成する
- 6. ユーザーが既に存在する場合にユーザーコントロールを作成する方法
- 7. mongodbにフィールドが存在する場合にクエリを作成する方法
- 8. C#.NET DLLファイルが存在する場合にのみコードを実行することは可能ですか?
- 9. 変更された場合のみフォームを保存する
- 10. 別の.dllを参照する.dllを作成します。
- 11. サブクラス化されたtxtboxをフォームで参照する方法
- 12. C#:参照されたDLLを使用する
- 13. ファイルが存在しない場合、指定されたパスにテキストファイルを作成する方法
- 14. 既存のファイルがすでに存在する場合、新しいファイルを作成する方法は?
- 15. 値が存在する場合にのみヘッダーを追加する方法?
- 16. プランが存在しない場合の作成方法
- 17. context.xmlで作成されたBeanを参照する方法は?私のプロジェクトで
- 18. Powershellが存在しない場合にフォルダを作成する
- 19. C#COM DLLを使用する場合のVBAの参照(出力)パラメータ
- 20. プロジェクトで既に参照されているDLLをダイナミックに読み込み/リンクする方法(コピーローカルfalse)
- 21. Cが存在しない場合、自動的にフォルダを作成する
- 22. 異なるインデックスからエントリを作成する方法(存在する場合)
- 23. dllで定義されたクラスを参照せずに使用するC#
- 24. ブレードテンプレートが存在する場合にのみ拡張する方法
- 25. 変数が存在する場合、それを返す方法
- 26. Rails ActiveRecordコールバック:存在する場合に更新する、存在しない場合に作成する
- 27. ファイルが存在し、ファイルが存在しない場合にのみlinuxでオープンシステムコールを実行する方法?
- 28. SLF4J +ファイルを作成するためのLogback(存在しない場合)/削除された場合
- 29. hrefファイルが存在する場合にのみリンクが表示されます。
- 30. DBインデックスが存在しない場合に作成する
(https://code.msdn.microsoft.com/windowsdesktop/Creating-a-simple-plugin-b6174b62)[プラグインスタイルのアーキテクチャを作成する]に見て。参照:https://msdn.microsoft.com/en-us/library/ms972962.aspx?f=255&MSPPError=-2147217396 –
[Delay loading in c#?]の可能な複製(http://stackoverflow.com/questions)/8344893/delay-loading-in-c) – GSerg