Is it possible to make the same DLL into both a co

2019-07-20 00:37发布

问题:

I have a project that targets .NET Standard 1.5 that is deployed as several DLLs on NuGet. The project was ported from Java. Inside some of the classes of the project are static Main() methods that are meant to be run from the command line.

In .NET Core it seems there are 2 ways to compile a DLL:

  • <OutputType>Exe</OutputType> - compiles into an executable console app (DLL)
  • <OutputType>Library</OutputType> (default) - compiles into a class library (DLL)

What I am wondering is there a way to compile the DLL so it can be used either way without having 2 separate (confusing) DLLs?

Basically, I am trying to get similar functionality to that in Java where a package can be referenced by an application or run on the command line (and to specify the entry target on the command line).

Example

For example, in Java there are files that are both part of the package and contain a static Main(object[] args) method.

public class SomeClass
{
    public void DoSomething(string arg1, string arg2, string arg3)
    {
        // implementation...
    }

    public static void Main(object[] args)
    {
         // parse args...

         new SomeClass().DoSomething(arg1, arg2, arg3);
    }
}

DoSomething is referenced elsewhere within the package (which is equivalent to what my NuGet packages look like now). However, in Java the Main(object[] args) can be run from the command line like...

java <package>.jar <namespace>.SomeClass [args]

without having to download or install anything extra. After all, if the component the user wants to run the command on is there, all of the dependencies are there, too.

Ideally, I can just use similar functionality in dotnet core...

dotnet <assembly>.dll <namespace>.SomeClass [args]

which would be preferable to having to create a separate wrapper DLL around the whole thing, or make a separate project that has to pick and choose all of the dependencies of SomeClass so they are all compiled into a single assembly (console app).

Furthermore, there are several static Main() methods per package, which seems to have been supported in .NET Core earlier which is what my other question is about.

回答1:

With .Net Standard/Core, your best option is to have a second project that compiles to an EXE who has a simple Main() method that points to the library's version. It isn't ideal, but the issue is how the runtime for .Net core works. A project that targets .Net Standard can be used by all projects compatible with that standard version. A project that targets a specific .NetCoreApp can only be referenced by other .NetCoreApps, so you don't get the benefit of targeting the standard.

For the packaging/NuGet deployment, the console app version can be put into the tools folder of the NuGet so an end user can use it. You don't really want executables to be deployed via the standard NuGet content folder because it won't really follow the standard and be confusing for your NuGet users.



回答2:

You get it for free with .Net EXE (which is just an assembly the same way as DLL and can be referenced as such).

To get close with DLL you'd need to make .Net DLL usable in some way from command line. Exposing some native-compatible entry point and using rundll32 to access it from command line is an option to achieve that - Need to run a c# dll from the command line.