Можно ли выполнить .NET DLL без EXE, чтобы загрузить его? - PullRequest
24 голосов
/ 02 марта 2011

Мне интересно, есть ли способ выполнить статический метод .DLL в новом процессе, не создавая для него .EXE?

AFAIK, это невозможно с родными библиотеками Win32 / 64. Как насчет сборок .NET DLL?

ОБНОВЛЕНИЕ : Я забыл упомянуть, что в первую очередь я заинтересован в том, чтобы сделать это программно (точнее, из кода C #).

Спасибо!

ЗАКЛЮЧЕНИЕ : Хотя никто не «осмелился» это объяснить, все ответы, похоже, склоняются к «нет». Нужно запустить процесс одним из обычных способов (EXE, PowerShell и т. Д.), А затем убедить этот процесс загрузить DLL и выполнить код внутри. Наверное, я ошибочно надеялся, что управляемые библиотеки DLL способны на большее.

Еще раз спасибо всем, кто присоединился!

Ответы [ 5 ]

15 голосов
/ 02 марта 2011

Просто запустите приглашение PowerShell.

  [Reflection.Assembly]::LoadFile("Name of your dll")
  [Your.NameSpace.And.TypeName]::YourMethod()

Я вижу, вы хотите это от C #

Создать тип, используя квалифицированное имя сборки:

 var t = Type.GetType("NameSpace.Type,Name Of Dll");
 var m = t.GetMethod("NameOfMethod");
 m.Invoke(null, new object[] { params });

Это должно помочь вам начать.

Я точно не знаю, что вы подразумеваете под «В новом процессе», но не должно быть сложным заключить это в .exe / .ps1, который вы можете запустить с какой-либо опцией в командной строке.

Таким образом, вам не нужно создавать новый .exe для каждой DLL, которую вы хотите вызвать.

Но если вы хотите начать новый процесс, вы должны начать новый процесс, обычно это делается путем запуска нового .EXE.

12 голосов
/ 10 марта 2011

Вариант 1: .NET InstallUtil (часть обычной установки .NET)

Добавьте ссылку на System.Configuration.Install, затем добавьте что-то подобное в вашу сборку:

[System.ComponentModel.RunInstaller(true)]
public class Sample : System.Configuration.Install.Installer
{
    public override void Uninstall(System.Collections.IDictionary savedState)
    {
        base.Uninstall(savedState);

        this.Context.LogMessage("This can be in a .dll.");
        // Do your thing...
    }
}

Затем злоупотребьте .NET InstallUtil:

%windir%\Microsoft.NET\Framework\v2.0.50727\installutil /logtoconsole=false /logfile= /u [your assembly .dll here]

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

Опция 2:используйте встроенный rundll32 для инвертирования P / Invoke статического метода класса

2016 Редактировать: Теперь пакет Nuget: UnmanagedExports ( src )!

Неизвестные директивы MSIL (msdn forum, 2007) - ссылка на бета-версию Справочника программиста на языке ассемблера IL (10/3/2000, стр.74), в которой говорится:

Если задано fromunmanaged, среда выполнения автоматически сгенерирует thunk, который преобразует вызов неуправляемого метода в управляемый вызов, вызовет метод и вернет результат в неуправляемую среду.

Подробнее см. В Expert .NET 2.0 IL на ассемблере и Внутри Microsoft.NET IL Assembler .(Лучшие ключевые слова для поиска: ilasm vtentry).

Похожие материалы:

Неуправляемый экспорт: не удается скомпилировать сборку (stackoverflow, 2010)

Неуправляемый экспорт / RGiesecke.DllExport.dll (stackoverflow, 2010)

Создание библиотеки DLL C #, которую можно импортировать в приложение Delphi с помощью stdcall (stackoverflow, 2009)

Шаблон проекта C # для неуправляемых экспортов ( Robert Giesecke , 2010) - msbuild, интеграция vs2010

Обновление IKVM.Reflection: экспорт статических управляемых методовкак неуправляемый экспорт DLL (моно, 2011)

Простой метод экспорта DLL без C ++ / CLI (codeproject, 2009) - 64-битная поддержка отсутствует?

Как автоматизировать экспорт функции .NET в неуправляемые программы (codeproject, 2006) - поддерживает 64-разрядные

Что-нибудь было добавлено в .Net 4.0 для поддержки "Обратного P /Вызывать "сценарии? (форум MSDN, 2010) - список кодов

UnmanaGed-код может переносить управляемые методы (codeproject, 2004)

Потенциальные недостатки:

Поправки с обратным пинвоуком (неуправляемые к обратным вызовам управляемого кода) (блог msdn,2006)

Обратный P / Invoke и исключение (MSDN блог, 2008)

1 голос
/ 02 марта 2011

Посмотрите на программу rundll32.exe, которая поставляется с windows. Если вы знаете определенную информацию о dll, вы можете иногда использовать эту программу для запуска кода в этой dll.

0 голосов
/ 18 августа 2014

Вы можете запустить процесс и запустить функцию dll, используя rundll32.exe dll_name,method_name. В C # вы можете сделать что-то вроде этого:

myProcess = new Process {StartInfo = {FileName = "rundll32.exe", Arguments = "my_dll_name.dll,my_function_name"}};
myProcess.Start();

Просто убедитесь, что DLL находится в вашем PATH. Если вы думаете о запуске какого-либо модульного тестирования, убедитесь, что вы завершили процесс с помощью метода TearDown / CleanUp: myProcess.Kill(), в противном случае DLL может остаться загруженной, и вы не сможете перезаписать ее как часть своей разработки. процесс. Вам также следует заглянуть в эту статью , чтобы найти приложение командной строки, которое уничтожит все процессы, в которых хранится ваша DLL, и добавит его в события Pre-Build: freelib.exe my_dll_name.dll

0 голосов
/ 02 марта 2011

Сборка .NET может быть загружена в PowerShell . (Ну, PowerShell - это EXE-файл, но он не предназначен для запуска кода из какой-либо конкретной сборки)

...