I am editing my question I think it is a little confusing and it does not explain what my intent is.
My goal is that when my HelloWorld
application references MyClassLibrary
my code does not compile so that I ensure to initialize some code prior to running the main method. Kind of like a constructor of a class. When I reference MyClassLibrary
I will like to run some code in there before running the main method of my HelloWorld
application. NUnit has a similar functionality. When my HelloWorld
application references NUnit I get the error: Error CS0017 Program has more than one entry point defined. Compile with /main to specify the type that contains the entry point.
As @Alex pointed out that Main method that NUnit creates is auto-generated. I will like to auto-generate a main method with some custom code. How can I do that from MyClassLibrary
without doing anything on my HelloWorld
application just like NUnit does it?
I want to perform the same behavior that NUnit
tests perform that it prevents using a Main
method. In this case the error that I need is a good thing. Let me explain what I mean.
.net core
Project file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
</Project>
Code file: (default hello world c# code)
If I then run that application it runs fine
Add a reference to NUnit
and my project file now contains.
.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
</ItemGroup>
</Project>
Error CS0017 Program has more than one entry point defined. Compile with /main to specify the type that contains the entry point.
That means that there is another Main
method. That method is probably located on the NUnit
nuget package I am referencing. This is the error I am trying to replicate!.
Now this is how I try to replicate the same error:
I remove the NUnit
nugget package having no references to NUnit
on my hello world application.
Create a Project ClassLibrary1
with the following code:
.
public class MyLib
{
static void Main()
{
Console.WriteLine("fooooo");
// do something
}
}
When I compile I get no errors even though there are 2 Main
methods!
How does NUnit
manages to prevent using a Main
method? How can I replicate the same behavior? I want to create an assembly that when referenced it prevents executing the Main
method.
Microsoft.NET.Test.Sdk
making build fail.<GenerateProgramFile>false</GenerateProgramFile>
into <PropertyGroup>
makes it compile and work anyway.static void Main
to the application makes build fail again regardless <GenerateProgramFile>
.Microsoft.NET.Test.Sdk
adds some auto-generated code to your application before compilation. That code is in ...\.nuget\packages\microsoft.net.test.sdk\16.2.0\build\netcoreapp1.0\Microsoft.NET.Test.Sdk.Program.cs
. It's a class with another Main
:// <auto-generated> This file has been auto generated. </auto-generated>
using System;
[Microsoft.VisualStudio.TestPlatform.TestSDKAutoGeneratedCode]
class AutoGeneratedProgram {static void Main(string[] args){}}
BTW: it's absolutely legal to have
Main
method in another assembly. You just cannot have 2Main
s in one exe. But you can have any number of them in dll like this:
public class Class1
{
public static void Main() { }
public static void Main(string[] args) { }
}
public class Class2
{
public static void Main() { }
public static void Main(string[] args) { }
}
It compiles.
Update:
I found the solution. It's all about installing nuget
, not just adding a reference.
.NET Core Class Library
and name it MyCoreLib
.MyCoreClass
.namespace MyCoreLib
{
public static class MyCoreClass
{
public static void Initialize()
{
System.Console.WriteLine("Initialized from 'MyCoreLib'");
}
}
}
├───nuget
└───src
│ MyCoreLib.nuspec
│
├───build
│ └───netcoreapp2.1
│ ForcedEntryPoint.cs
│ MyCoreLib.targets
│
└───lib
└───netcoreapp2.1
MyCoreLib.dll
MyCoreLib.nuspec
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
<metadata>
<id>MyCoreLib</id>
<version>1.0.0</version>
<authors>MyCoreLib</authors>
<owners>MyCoreLib</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Some description here</description>
<dependencies>
<group targetFramework=".NETCoreApp2.1" />
</dependencies>
</metadata>
</package>
ForcedEntryPoint.cs
//╔════════════════════════════════════╗
//║ This code was added automatically. ║
//║ Do not change or remove it. ║
//╚════════════════════════════════════╝
public static class ForcedEntryPoint
{
public static void Main(string[] args)
{
MyCoreLib.MyCoreClass.Initialize();
}
}
MyCoreLib.targets
<Project InitialTargets="ForceEntryPoint" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<OutputType>Exe</OutputType>
</PropertyGroup>
<PropertyGroup>
<ForcedEntryPoint Condition="'$(ForcedEntryPoint)' == ''">$(MSBuildThisFileDirectory)ForcedEntryPoint$(DefaultLanguageSourceExtension)</ForcedEntryPoint>
<ForceEntryPoint Condition="'$(ForceEntryPoint)' == ''">true</ForceEntryPoint>
</PropertyGroup>
<Target Name="ForceEntryPoint" Condition="'$(ForceEntryPoint)' == 'true'">
<ItemGroup>
<Compile Include="$(ForcedEntryPoint)"/>
</ItemGroup>
</Target>
</Project>
D:\nugetwalkthrough\nuget>D:\nugetwalkthrough\nuget.exe pack D:\nugetwalkthrough\src\MyCoreLib.nuspec
.NET Core Console App
and make sure it works.CS0017 Program has more than one entry point defined. Compile with /main to specify the type that contains the entry point.
Main
method from the application, run it and see it prints Initialized from 'MyCoreLib'
.Main
method back to the application and change the project file so that <PropertyGroup>
contains <ForceEntryPoint>false</ForceEntryPoint>
Hello World!
from its own Main
method.<ForceEntryPoint>
to true
makes it use another entry point (not that one of the application) again.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With