24

I'm curious if there's a way to execute a static .DLL method in a new process without having to create an .EXE for it?

AFAIK, this isn't possible with native Win32/64 DLLs. How about .NET DLL assemblies?

UPDATE: I forgot to mention I'm primarily interested in doing this programmatically (from C# code, to be specific).

Thanks!

CONCLUSION: Although no one "dared" to spell it out, the answers all seem to lean towards 'no'. One needs to start a process through one of the conventional ways (EXE, PowerShell, etc.) then convince that process to load the DLL and execute the code within. I guess I was falsely hoping that managed DLLs are capable of more.

Thanks again to everyone who chimed in!

aoven
  • 2,248
  • 2
  • 25
  • 36
  • Do you mean from the command line or Run dialog, or from another application? – Justin Mar 02 '11 at 15:58
  • 5
    rundll32 requires a native dll, at least for the portion it intends to execute. – Lasse V. Karlsen Mar 02 '11 at 16:00
  • 2
    Creating your own managed rundll32 that uses Activator.CreateInstance and/or reflection is pretty simple. Or just a quicky console app, this doesn't really require a jet pack. – Hans Passant Mar 02 '11 at 18:17
  • @Hans: You're right, of course. It really is quite simple - the crux of my query, though, was whether it was also absolutely necessary. I guess, now I know. :) – aoven Mar 03 '11 at 09:07
  • I was wondering the same thing, then I realized that you can use an EXE as a library instead of a DLL. In my case, I'm using a managed EXE as a reg-free COM library. You add a static Main() to it for the executable functionality, so it serves as both a library and an executable. – transistor1 Nov 15 '12 at 01:29
  • 1
    It is possible to run a native dll x86 or x64 by calling `rundll(32).exe your_dll_name,your_entry_point` in command line or by launching a process as explained below in the C# code. – Darien Pardinas Aug 17 '14 at 23:19

5 Answers5

18

Just start a PowerShell prompt.

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

I see you want this from C#

Create the Type using the Assembly Qualified name:

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

This should get you started.

I don't exactly know what you mean by "In a new process", but it should not be to difficult to wrap this into a .exe/.ps1 that you can start with some option on the commandline.

So you do not have to create a new .exe for every DLL you want to invoke.

But if you want to start a new process, you should start a new process, this is typically done by starting a new .EXE.

GvS
  • 52,015
  • 16
  • 101
  • 139
  • 1
    Quoth myself: "in a new process". :) – aoven Mar 02 '11 at 16:07
  • PowerShell might do the trick. Just one question: is it included in every Visual Studio 2010 installation, or is it a separate installation? – aoven Mar 02 '11 at 16:09
  • Don't know if Powershell gets installed with Visual Studio. It is part of Windows 7 and Windows 2008. – GvS Mar 02 '11 at 16:13
  • 2
    "it should not be to difficult to wrap this into a .exe/.ps1 that you can start with some option on the commandline" I'm aware of that option. I'm specifically asking if there is any other way? Your answer seems to be no. I will accept that if no one else offers a solution in the next couple of hours. – aoven Mar 02 '11 at 16:16
  • the Powershell thing might be really cool if you -- I don't know... -- actually provide the code to launch powershell in a new (hopefully hidden!) process -- and then actually execute the code to do this... – BrainSlugs83 Sep 07 '14 at 20:30
13

Option 1: .NET InstallUtil (part of the normal .NET install)

Add a reference to System.Configuration.Install then drop something like this in your assembly:

[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...
    }
}

Then abuse the .NET InstallUtil:

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

It may be a bit messy, especially without all the command line parameters disabling logging.

Option 2: use native rundll32 to inverse P/Invoke a static class method

2016 Edit: Now a Nuget package: UnmanagedExports (src)!

Unknown MSIL directives (msdn forum, 2007) links to a beta 1 release of the IL Assembly Language Programmer's Reference (10/3/2000, pg.74) which states:

If fromunmanaged is specified, the runtime will automatically generate a thunk that will convert the unmanaged method call to a managed call, call the method, and return the result to the unmanaged environment.

There is more detail in Expert .NET 2.0 IL assembler and Inside Microsoft. NET IL Assembler. (Best search keywords: ilasm vtentry).

Related reading:

Unmanaged Exports: Cannot compile assembly (stackoverflow, 2010)

Unmanaged Exports / RGiesecke.DllExport.dll (stackoverflow, 2010)

Create a C# DLL That Can Be Imported in a Delphi App Using stdcall (stackoverflow, 2009)

C# Project Template for Unmanaged Exports (Robert Giesecke, 2010) - msbuild, vs2010 integration

IKVM.Reflection Update: export static managed methods as unmanaged DLL exports (mono, 2011)

Simple Method of DLL Export without C++/CLI (codeproject, 2009) - no 64-bit support?

How to Automate Exporting .NET Function to Unmanaged Programs (codeproject, 2006) - supports 64-bit

Has anything been added to .Net 4.0 to support "Reverse P/Invoke" scenarios? (msdn forum, 2010) - code listing

Unmanaged code can wrap managed methods (codeproject, 2004)

Potential drawbacks:

Gotchas with Reverse Pinvoke (unmanaged to managed code callbacks) (msdn blog, 2006)

Reverse P/Invoke and exception (msdn blog, 2008)

Community
  • 1
  • 1
user423430
  • 3,654
  • 3
  • 26
  • 22
  • 3
    +1 for innovative approach. I'll remember this one for the future! :) – aoven Mar 14 '11 at 12:29
  • InstallUtil is part of .NET so it should be available anywhere you can run your assembly; PowerShell is not as guaranteed (for example, Windows XP). It should also be clear which version of the framework will be running. :) – user423430 Mar 15 '11 at 17:51
  • http://subt0x10.blogspot.com/2016/09/bypassing-application-whitelisting.html MSBuild Inline Tasks C# snippets in an XML file, compiled and executed in memory – user423430 Dec 13 '16 at 03:39
1

Look into the the rundll32.exe program that ships with windows. If you know certain information about the dll, you can sometimes use this program to run code in that dll.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
0

You can launch a process and run a dll function by using rundll32.exe dll_name,method_name. In C# you can do something like this:

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

Just make sure the DLL is in your PATH. If you are thinking about running unit testing of some kind, make sure you kill the process on the TearDown / CleanUp method: myProcess.Kill(), otherwise the DLL may remain loaded and you won't be able to overwrite it as part of your development process. You should also look into this article for a command line application that will kill all processes holding your DLL and add it to your Pre-Build events: freelib.exe my_dll_name.dll

Darien Pardinas
  • 5,910
  • 1
  • 41
  • 48
0

A .NET Assembly can be loaded in PowerShell. (Well, PowerShell is an EXE, but not specialized for running code from any particular assembly)

Albin Sunnanbo
  • 46,430
  • 8
  • 69
  • 108