Может ли сборка C # .dll содержать точку входа? - PullRequest
17 голосов
/ 06 марта 2012

Моя цель - создать исполняемый файл, который запустит теневое копирование приложения.Хитрость в том, что я хочу, чтобы эта стартовая программа не имела внешних зависимостей и не должна была содержать никаких сведений о программе, которую она должна запускать.

Я также хочу, чтобы она была единственным исполняемым файлом в каталоге.Другими словами, я хочу, чтобы он запускал сборку .dll, а не сборку .exe.(Я могу потребовать, чтобы имя файла .dll, загружаемого в новый домен приложений, всегда было одинаковым, например Main.dll или что-то в этом роде.)

Это выглядело как AppDomain.ExecuteAssembly сделал бы именно то, что я хотел.Он говорит, что начнет выполнение с «точки входа, указанной в заголовке .NET Framework.».

Когда я пытаюсь использовать эту функцию, я получаю ошибку «Точка входа не найдена в сборке« 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 в качестве точки входа».Он не говорит, что они не могут иметь точку входа по умолчанию.

Я пробовал все различные перестановки public / private static void main, тип возврата int, string [] argsв качестве аргументов, с пространством имен, без пространства имен, статическим / нестатическим классом и т. д.

Я смог изменить свой код для наследования от MarshalByRefObject, а затем использовать CreateInstance для создания объекта, но это выглядит такбудет более тесно связывать стартер с программой, которую предполагается запустить.Если бы я мог использовать ExecuteAssembly, запускаемое приложение просто нуждалось бы в статической пустоте Main, и это действительно просто и сложно испортить.

Возможно ли, чтобы сборка .dll имела точку входа по умолчанию,и для ExecuteAssembly, чтобы найти его, или я просто должен смириться с тем, чтобы идти другим путем?

Ответы [ 3 ]

21 голосов
/ 06 марта 2012

Вы можете скомпилировать приложение .NET как исполняемый файл (который является сборкой) и переименовать его в .DLL, и оно будет действовать как обычная сборка .NET .dll. Тогда у вас будет точка входа.

1 голос
/ 18 февраля 2014

Я обнаружил, что совету не так легко следовать. После некоторых экспериментов я пришел к успеху:

Я создал консольное приложение с простым main и включил остальную часть кода из моей оригинальной 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 и увидеть, что я могу вызвать Main of DLLTest. Спасибо за обсуждение, ребята!

0 голосов
/ 06 марта 2012

Короткий ответ - нет. Файл .DLL - это динамически связанная библиотека, код которой вызывается другой библиотекой. Я думаю, что, по словам Кейта, будет работать технически ... вы можете переименовать его так, как вам нужно, даже в формат .txt или .pdf, если вы правильно запустите приложение. Главный вопрос, который у меня есть, заключается в следующем; Что ты пытаешься сделать?? Если вы не пытаетесь писать вредоносные программы, зачем вам это делать? Не то чтобы я потворствовал написанию вредоносных программ для плохих целей, но я знаю, что людям нравится экспериментировать в собственной лаборатории, поэтому я, например, не осуждаю их. Если вы пишете вредоносное ПО, лучше подойдет что-то вроде c ++, c или ассемблера, я думаю, C # справится с работой, но ме ...

...