24

我很好奇是否有一种方法可以在新进程中执行静态 .DLL 方法而无需为其创建 .EXE?

AFAIK,这对于本机 Win32/64 DLL 是不可能的。.NET DLL 程序集怎么样?

更新:我忘了提到我主要对以编程方式执行此操作感兴趣(具体而言,来自 C# 代码)。

谢谢!

结论:虽然没有人“敢”说出它,但答案似乎都倾向于“不”。需要通过一种传统方式(EXE、PowerShell 等)启动进程,然后说服该进程加载 DLL 并执行其中的代码。我想我错误地希望托管 DLL 能够提供更多功能。

再次感谢所有参与的人!

4

5 回答 5

18

只需启动 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 中应该不难,您可以从命令行上的某个选项开始。

因此,您不必为要调用的每个 DLL 创建新的 .exe。

但是如果你想启动一个新进程,你应该启动一个新进程,这通常是通过启动一个新的.EXE来完成的。

于 2011-03-02T16:01:08.537 回答
13

选项 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 论坛,2007)链接到 IL 汇编语言程序员参考(10/3/2000,pg.74)的 beta 1 版本,其中指出:

如果指定了fromunmanaged,则运行时会自动生成一个thunk,它将非托管方法调用转换为托管调用,调用该方法,并将结果返回给非托管环境。

Expert .NET 2.0 IL assemblerInside Microsoft中有更多详细信息。NET IL 汇编程序。(最佳搜索关键字:ilasm vtentry)。

相关阅读:

非托管导出:无法编译程序集(stackoverflow,2010)

非托管导出/RGiesecke.DllExport.dll(stackoverflow,2010

使用 stdcall 创建可以在 Delphi 应用程序中导入的 C# DLL (stackoverflow, 2009)

非托管导出的 C# 项目模板Robert Giesecke,2010 年)- msbuild,vs2010 集成

IKVM.Reflection 更新:将静态托管方法导出为非托管 DLL 导出(单声道,2011)

没有 C++/CLI 的简单 DLL 导出方法(codeproject,2009) - 不支持 64 位?

如何自动将 .NET 函数导出到非托管程序(codeproject,2006)- 支持 64 位

.Net 4.0 中是否添加了任何内容以支持“反向 P/Invoke”方案?(msdn 论坛,2010 年)- 代码清单

非托管代码可以包装托管方法(codeproject,2004)

潜在的缺点:

反向 Pinvoke 的陷阱(非托管到托管代码回调)(msdn 博客,2006 年)

反向 P/Invoke 和异常(msdn blog, 2008)

于 2011-03-09T21:40:57.457 回答
1

查看 Windows 附带的 rundll32.exe 程序。如果您知道有关 dll 的某些信息,您有时可以使用该程序在该 dll 中运行代码。

于 2011-03-02T16:01:28.973 回答
0

可以在 PowerShell 中加载.NET 程序集。(好吧,PowerShell 是一个 EXE,但不是专门用于从任何特定程序集中运行代码)

于 2011-03-02T16:01:53.947 回答
0

您可以使用 启动进程并运行 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 的进程并将其添加到您的预构建事件中:freelib.exe my_dll_name.dll

于 2014-08-17T23:16:39.197 回答