web-dev-qa-db-ja.com

C#.dllアセンブリにエントリポイントを含めることはできますか?

私の目標は、シャドウコピーされたアプリケーションを起動する実行可能ファイルを作成することです。秘訣は、このスタータープログラムに外部依存関係がなく、起動する必要のあるプログラムに関する知識が含まれていないことです。

また、ディレクトリ内で唯一の実行可能ファイルにしたいです。つまり、.exeアセンブリではなく.dllアセンブリを「実行」する必要があります。 (新しいAppDomainにロードされる.dllファイルの名前は、Main.dllなどのように、毎回同じである必要があります。)

AppDomain.ExecuteAssembly は、私が望んでいたことを正確に実行するように見えました。 「.NETFrameworkヘッダーで指定されたエントリポイント」から実行を開始すると書かれています。

その関数を使おうとすると、「アセンブリ 'DllApp'にエントリポイントが見つかりません」というエラーが表示されます。

アセンブリを実行しようとしているだけのスタータープログラム:

static void Main()
{
    AppDomain domain = AppDomain.CreateDomain( "DllApp" );
    domain.ExecuteAssembly( "DllApp.dll" );
}

デフォルトのエントリポイントを持つ.dllファイル内のアプリケーションコード:

static class Program
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault( false );
        Application.Run( new Form1() );
    }
}

Main()関数のこのページ は、「ライブラリとサービスは、エントリポイントとしてMainメソッドを必要としない」と述べています。 cannotにもデフォルトのエントリポイントがあるとは言えません。

Public/private static void main、int return type、string [] argsを引数として、名前空間、名前空間なし、静的/非静的クラスなど、さまざまな組み合わせをすべて試しました。

MarshalByRefObjectから継承するようにコードを変更してから、CreateInstanceを使用してオブジェクトを作成することができましたが、スターターと起動するはずのプログラムをより緊密に結合するようです。 ExecuteAssemblyを使用できれば、起動するアプリケーションには静的なvoid Mainが必要になるだけで、それは本当に単純で混乱しにくいものです。

.dllアセンブリにデフォルトのエントリポイントがあり、ExecuteAssemblyがそれを見つけることは可能ですか、それとも別のルートに進むために辞任する必要がありますか?

18
Sean

.NETアプリをexe(アセンブリ)としてコンパイルし、名前を.DLLに変更すると、通常の.NET.dllアセンブリとして機能します。その後、エントリポイントがあります。

21
Keith Nicholas

アドバイスに従うのはそれほど簡単ではないことがわかりました。いくつかの実験の後、これが私が成功した方法です:

単純なメインでコンソールアプリケーションを作成し、元のDLLの残りのコードを含めました。以下は、DLLを含む簡略化されたプログラムです。

namespace FIT.DLLTest
{
  public class DLLTest
  {
    [STAThread]
    static void Main(string[] args)
    {
      int a = 1;
    }

    public DLLTest()
    {
      int b = 17;
    }

    public int Add(int int1, int int2)
    {
      return int1 + int2;
    }
  }
}

コンパイル後、生成された.exeの名前を.DLLに変更しました。

DLLを使用するマザープログラムでは、最初にDLLTest.dllを参照として追加し、次にDLLを実行するためのコードを追加しました。

namespace TestDLLTest
{
  class TestDLLTest
  {
    static void Main(string[] args)
    {
      AppDomain domain = AppDomain.CreateDomain( "DLLTest" );
      domain.ExecuteAssembly( "DllTest.dll" );

      DLLTest dt = new DLLTest();
      int res2 = dt.Add(6, 8);
      int a = 1;
    }
  }
}

ViolàDLLTest.Mainメソッドを実行してブレークポイントを追加し、DLLTestのメインを呼び出すことができることを確認できました。ディスカッションの皆さん、ありがとう!

1
user3324444