I'm sure it's a stupid question with an obvious answer, but I just can't figure it out. I'm practicing C# in VS Code, and putting all of my projects in a folder. Now when I try to test the start of my second program using "dotnet run", the terminal keeps trying to access the first project, not the one that's open.
"AdditionCalc.cs(7,17): error CS0017: Program has more than one entry point defined. Compile with /main to specify the type that contains the entry point. [C:\Users\dylan\Desktop\C# practice\C# practice.csproj]"
is the error message i get. "AdditionCalc.cs" is my first project, where I made a simple addition calculator.
using System;
namespace Practice
{
class Calculator
{
static void Main(string[] args)
{
string str1;
string str2;
int number1;
int number2;
Console.WriteLine("Enter Number One");
str1 = Console.ReadLine();
Console.WriteLine("Enter Number Two");
str2 = Console.ReadLine();
number1 = Int32.Parse(str1);
number2 = Int32.Parse(str2);
int answer = number1 + number2;
Console.WriteLine("Those two numbers added up is: " + answer);
string fivehundo = (answer >=500) ? "That number is bigger than 500" : "That number is smaller than 500";
Console.WriteLine(fivehundo);
}
}
}
This is my first Project
using System;
namespace Test {
class NumberGuesser {
static void Main(string[] args){
Random rnd = new Random();
int number = rnd.Next(1, 11);
Console.WriteLine(number);
}
}
}
this is my second project, where the user will guess a number and each time the console will return if the actual number is higher or lower than the one entered.
Do i specifically have to save these files in completely separate places and create a new console every time? Or is it that I have to open the file in a specific way?
Help is greatly appreciated, and I know it's probably a stupid question and I'm overlooking something very basic
It is pretty standard to have a different folder for each project, so that would be my recommendation.
There might be an alternative way to get it to work all in one folder, but you might as well do it the typical way right from the get-go.
I'd definitely follow E.J. Brennans advice and move your code into separate folders, but I'd also add that the issue you're seeing isn't related to VS Code at all - from what you've described, you've created a new class, but not a new project.
The Terminal in VS Code is just a regular terminal session - no different than if you opened Command Prompt or Powershell on a Windows machine, or just your regular command line on Linux. When you're calling 'dotnet run', you're calling the .NET Core CLI.See the .NET doco for more information on that.
Generally speaking, 'dotnet run' with no other parameters passed to it is looking for the .csproj file in your current directory, and attempting to call a Main method that it thinks is a part of that Project. If it can see multiple Main methods but the .csproj file doesn't specify which Class's Main to use (see this question), it doesn't know what to do and throws this error for you.
Which gets us to what I think is the main problem you're facing. You've created a new file, I imagine 'NumberGuesser.cs' with the new Main method that you want to use, but you haven't actually created a new project - which would come with a new and distinct .csproj file.
I'd recommend moving your NumberGuesser code to a new project - 'dotnet new console -o NumberGuesser' from one directory level up, and then move your class into the new project directory that creates for you.
Related
So here's the deal, I have 2 classes at the moment (planning on adding multiple), and I get this error when i'm trying to call functions from both classes. Same namespace. I double-checked and look at my properties tab to see that it's set to compile.
using System;
namespace Game
{
public class SecondSet
{
public void SituationSecondOne()
{
Console.WriteLine(" ");
Console.WriteLine("Choices:");
Console.WriteLine("1: First");
Console.WriteLine("2: Second");
Console.WriteLine(" ");
int ChoiceOne = Convert.ToInt32(Console.ReadLine());
switch (ChoiceOne)
{
case (1):
Console.WriteLine("TEST2");
break;
case (2):
Console.WriteLine("TEST2");
break;
case (1337):
Console.WriteLine(" ");
Console.WriteLine("Thank you for playing");
Console.ReadLine();
Environment.Exit(1);
break;
default:
Console.WriteLine(" ");
Console.WriteLine("Now, let's try that again ... (¬_¬)");
SituationSecondOne();
break;
}
}
}
}
Now, when I call the function from the second to the first, I get no error. What type of Main() method do I need for this? (I also tried to add the original public void Main(string[] args), once added, I can no longer add public to the function I want to call to the first class)
NOTE: I added this to the first class
SecondSet s2 = new SecondSet();
And it works fine as the code is posted above, but I get the compile error mentioned. valve pls fix :/
It's not clear what you mean.But
I was looking at this issue as well, and in my case the solution was too easy. I added a new empty project to the solution. The newly added project is automatically set as a console application. But since the project added was a 'empty' project, no Program.cs existed in that new project. (As expected)
All I needed to do was change the output type of the project properties to Class library
Change the Output Type under the Project > Properties to that of a “Class Library”. By default, this setting may have been set to a “Console Application”.
static void Main()
{
}
You can also receive this error is you change your Main method to be async and forget to change void to be Task.
May be your program doest not contain Main which is the entry point of console application so replace with and read this
class Hello
{
public void SituationSecondOne()
{
Console.WriteLine(" ");
Console.WriteLine("Choices:");
Console.WriteLine("1: First");
Console.WriteLine("2: Second");
Console.WriteLine(" ");
int ChoiceOne = Convert.ToInt32(Console.ReadLine());
switch (ChoiceOne)
{
case (1):
Console.WriteLine("TEST2");
break;
case (2):
Console.WriteLine("TEST2");
break;
case (1337):
Console.WriteLine(" ");
Console.WriteLine("Thank you for playing");
Console.ReadLine();
Environment.Exit(1);
break;
default:
Console.WriteLine(" ");
Console.WriteLine("Now, let's try that again ... (¬_¬)");
SituationSecondOne();
break;
}
}
static void Main()
{
SecondSet s2 = new SecondSet();
Console.ReadKey();
}
}
Please follow this way and its working and resolved your error.
public class Program{
static async Task Main()
{ }
}
This was happening to me when running my code in VS2017.
Opening in VS2019 fixed the error.
async Task Main() entry point requires C# 7.1 or later, so perhaps you don't have required version installed.
For me it was that I set a startup project that have an Output Type (Console Application)
it was the wrong project anyway, so I set the top layer as a startup project.
also changed the other layers to be of Output Type (Class Library)
As OP did not restricted to WinForms, and I have this error because of a mixed WinForms => WPF approach, I feel that is OK to answer here.
In my case I have .NET Framework 4.8 that gets data from an ancient Outlook .pst file; on top of this I want to display contacts with a WPF UI - I know, I know, why not with a WinForms?
For WPF, I had to add System.Xaml, PresentationCore and PresentationFramework and of course deleted the Form1.cs and Program.cs causing the error msg "CS5001 Program does not contain a static 'Main' method suitable for an entry point" that immediately appeared.
After some SO Googling, I came here and to another thread and came up with this change at .csproj:
<ItemGroup>
<!--<Page Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>-->
<!-- ^^^^^^^^ ERROR ^^^^^^^^ -->
<!-- Above leads to an error Message "CS5001 Program does not contain a static 'Main' method suitable for an entry point"-->
<!-- Below is the fix for WPF in NET Framework -->
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
...
<ItemGroup>
PS: As a side note, when you unload the project and click Edit Project File and ask for Find App.Xaml with CTRL-F do you notice that - sometimes, at least - the default scope is Current Project? And as your Project is unloaded, although you are in the .csproj it does not find anything inside the current .csproj?
I lose a lot of minutes in that :( before I realize that I had to change scope to Current Document...
I've got some issues running Puma.Net. I've got all the functions looking fine in the code but when it comes this point:
Value = pumaPage.RecognizeToString();
It then gives an error saying the library dibapi.dll can't be found. But I just can't even add it as a reference it says something like
Can't add reference Make sure the file is accessible and that it is a assembly or Com-Component.
So I gave it all the rights it needs to be read, write & executed. I even gave it full controll on all the users but it just won't work.
Maybe I made a mistake somewhere so here is the full code of the programm.
static void Main()
{
string Image = "V:/Test_images/value.PNG";
Console.WriteLine("Running the Program!");
var pumaPage = new PumaPage(Image);
string Value;
using (pumaPage)
{
pumaPage.FileFormat = PumaFileFormat.RtfAnsi;
pumaPage.EnableSpeller = false;
pumaPage.Language = PumaLanguage.Digits;
Value = pumaPage.RecognizeToString();
}
Console.WriteLine("The Value is" + Value);
Console.ReadLine();
}
I've added the Puma.Net dll and "using Puma.Net;" so it should work. Does someone got any idea what could be wrong?
Here is also the errormessage that appears all the time.
The Error Message which appears
If you need a translation just tell me.
Btw it is a Console Application and I would love to keep it that way. If it is not possible then I can also try to use turn it into a Form Application but that's a whole new part for me so it could take a while to get into it.
You need to copy dibapi.dll to the output folder as described in the documentation:
Steps to add Puma.NET to your project:
1. Add reference to Puma.Net.dll;
2. Make sure that after project building the output folder (i.e. bin\Debug or bin\Release)
contains files Puma.Net.dll and puma.interop.dll. If the last is not present (IDE didn’t
copy it) copy it to the folder manually;
3. Copy dibapi.dll to the output folder;
I was under the impression Mono's compiler was usable in Microsoft.NET
edit: updated blog posting here that I originally missed that explains some of it (is consistent with Justin's answers)
I created a simple class to try to use it
[TestFixture]
class Class1
{
[Test]
public void EXPR()
{
Evaluator.Run("using System;");
int sum = (int)Evaluator.Evaluate("1+2");
}
}
And a project in Visual Studio 2010 that references C:\Program Files (x86)\Mono-2.10.1\lib\mono\4.0\Mono.CSharp.dll.
However when I try to run this task I get the following exception, thrown at the Evaluator.Run call:
System.TypeInitializationException was unhandled by user code
Message=The type initializer for 'Mono.CSharp.Evaluator' threw an exception.
Source=Mono.CSharp
TypeName=Mono.CSharp.Evaluator
StackTrace:
at Mono.CSharp.Evaluator.Run(String statement)
at Experiments.Class1.EXPR() in W:\Experiments\Class1.cs:line 16
InnerException: System.TypeLoadException
Message=Method 'Mono.CSharp.Location.ToString()' is security transparent, but is a member of a security critical type.
Source=Mono.CSharp
TypeName=Mono.CSharp.Location.ToString()
StackTrace:
at Mono.CSharp.Evaluator..cctor()
InnerException:
A google confirms one other person asking this question but no answer. I tried to start reading the microsoft article on security transparent code but got confused quite quickly. Would someone be able to suggest a quick workaround to allow me to use this? And possibly summarise the security implications, if any, to me (in the context of my situation - in the future I hope to package it with a thick client application, to be used both internally and by end-users)
It has worked under .NET since April of last year.
Small point but I notice you are missing a semi-colon in your expression for sum.
int sum = (int)Evaluator.Evaluate("1+2;");
I only have Mono 2.11 (from git) at the moment and they have changed to using a multi-instance version of the compiler instead of the static version. So, my code looks a little different:
using System;
using Mono.CSharp;
namespace REPLtest
{
class MainClass
{
public static void Main (string[] args)
{
var r = new Report (new ConsoleReportPrinter ());
var cmd = new CommandLineParser (r);
var settings = cmd.ParseArguments (args);
if (settings == null || r.Errors > 0)
Environment.Exit (1);
var evaluator = new Evaluator (settings, r);
evaluator.Run("using System;");
int sum = (int) evaluator.Evaluate("1+2;");
Console.WriteLine ("The sum of 1 + 2 is {0}", sum);
}
}
}
EDIT: I guess I should confirm that I did in fact successfully execute this on .NET 4 (using Visual C# Express 2010 on Windows XP)
EDIT AGAIN: If you have Visual Studio, you can download the latest version of Mono.CSharp and compile it yourself. There is a .sln (solution file) included with the source so you can build it on Windows without Mono. The resulting assembly would run the code above. Miguel has a post explaining the new Mono.CSharp here.
FINAL EDIT: I uploaded the compiled Mono.CSharp.dll assembly that I actually used here. Include it as a reference to compile the code above.
It looks like this is a bug in Mono.
.NET 4 abandoned Code Access Security but kept the concept of Security Transparent Code. In a nutshell, low-level code that does stuff, like call unmanaged code, must be "security critical". Application level code is marked "transparent". "Transparent" code cannot call into "security critical" code.
It sounds like Mono.CSharp.Location.ToString() needs to be marked with the [SecuritySafeCritical] attribute if you want the Mono 2.10 code to work with .NET 4. Maybe even better would be marking all of Mono.CSharp as SecuritySafeCritical.
http://msdn.microsoft.com/en-us/library/system.security.securitycriticalattribute.aspx
PS. Sorry to have multiple answers for one question. After I realized that 2.11 would work, I became more curious about what the error with 2.10 meant. I cannot really combine this answer with the others.
I decided I should have kept the code more like the question but I did not want to overwrite my previous answer:
The code below works with version 2.11 of Mono.CSharp (available here including a solution file for building with Visual Studio/.NET). It was tested with .NET 4 on Windows XP. I do not have access to Mono 2.10 at the moment.
[TestFixture]
class Class1
{
private Evaluator evaluator;
public Class1()
{
var report = new Report(new ConsoleReportPrinter());
evaluator = new Evaluator(new CompilerSettings(), report);
}
[Test]
public void EXPR()
{
evaluator.Run("using System;");
int sum = (int)evaluator.Evaluate("1+2;");
}
}
EDIT: I uploaded the Mono.CSharp.dll assembly that I actually used here. Include it as a reference to compile the code above.
IronRuby and VS2010 noob question:
I'm trying to do a spike to test the feasibility of interop between a C# project and an existing RubyGem rather than re-invent that particular wheel in .net. I've downloaded and installed IronRuby and the RubyGems package, as well as the gem I'd ultimately like to use.
Running .rb files or working in the iirb Ruby console is without problems. I can load the both the RubyGems package, and the gem itself and use it, so, at least for that use case, my environment is set up correctly.
However, when I try to do the same sort of thing from within a C# (4.0) console app, it complains about the very first line:
require 'RubyGems'
With the error:
no such file to load -- rubygems
My Console app looks like this:
using System;
using IronRuby;
namespace RubyInteropSpike
{
class Program
{
static void Main(string[] args)
{
var runtime = Ruby.CreateRuntime();
var scope = runtime.ExecuteFile("test.rb");
Console.ReadKey();
}
}
}
Removing the dependencies and just doing some basic self-contained Ruby stuff works fine, but including any kind of 'requires' statement seems to cause it to fail.
I'm hoping that I just need to pass some additional information (paths, etc) to the ruby runtime when I create it, and really hoping that this isn't some kind of limitation, because that would make me sad.
Short answer: Yes, this will work how you want it to.You need to use the engine's SetSearchPaths method to do what you wish.
A more complete example
(Assumes you loaded your IronRuby to C:\IronRubyRC2 as the root install dir)
var engine = IronRuby.Ruby.CreateEngine();
engine.SetSearchPaths(new[] {
#"C:\IronRubyRC2\Lib\ironruby",
#"C:\IronRubyRC2\Lib\ruby\1.8",
#"C:\IronRubyRC2\Lib\ruby\site_ruby\1.8"
});
engine.Execute("require 'rubygems'"); // without SetSearchPaths, you get a LoadError
/*
engine.Execute("require 'restclient'"); // install through igem, then check with igem list
engine.Execute("puts RestClient.get('http://localhost/').body");
*/
Console.ReadKey();
I have a requirement to install multiple web setup projects (using VS2005 and ASP.Net/C#) into the same virtual folder. The projects share some assembly references (the file systems are all structured to use the same 'bin' folder), making deployment of changes to those assemblies problematic since the MS installer will only overwrite assemblies if the currently installed version is older than the one in the MSI.
I'm not suggesting that the pessimistic installation scheme is wrong - only that it creates a problem in the environment I've been given to work with. Since there are a sizable number of common assemblies and a significant number of developers who might change a common assembly but forget to update its version number, trying to manage versioning manually will eventually lead to massive confusion at install time.
On the flip side of this issue, it's also important not to spontaneously update version numbers and replace all common assemblies with every install, since that could (temporarily at least) obscure cases where actual changes were made.
That said, what I'm looking for is a means to update assembly version information (preferably using MSBuild) only in cases where the assembly constituents (code modules, resources etc) has/have actually changed.
I've found a few references that are at least partially pertinent here (AssemblyInfo task on MSDN) and here (looks similar to what I need, but more than two years old and without a clear solution).
My team also uses TFS version control, so an automated solution should probably include a means by which the AssebmlyInfo can be checked out/in during the build.
Any help would be much appreciated.
Thanks in advance.
I cannot answer all your questions, as I don't have experience with TFS.
But I can recommend a better approach to use for updating your AssemblyInfo.cs files than using the AssemblyInfo task. That task appears to just recreate a standard AssemblyInfo file from scratch, and loses any custom portions you may have added.
For that reason, I suggest you look into the FileUpdate task, from the MSBuild Community Tasks project. It can look for specific content in a file and replace it, like this:
<FileUpdate
Files="$(WebDir)\Properties\AssemblyInfo.cs"
Regex="(\d+)\.(\d+)\.(\d+)\.(\d+)"
ReplacementText="$(Major).$(ServicePack).$(Build).$(Revision)"
Condition="'$(Configuration)' == 'Release'"
/>
There are several ways you can control the incrementing of the build number. Because I only want the build number to increment if the build is completely successful, I use a 2-step method:
read a number from a text file (the only thing in the file is the number) and add 1 without changing the file;
as a final step in the build process, if everything succeeded, save the incremented number back to the text file.
There are tasks such as ReadLinesFromFile, that can help you with this, but I found it easiest to write a small custom task:
using System;
using System.IO;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace CredibleCustomBuildTasks
{
public class IncrementTask : Task
{
[Required]
public bool SaveChange { get; set; }
[Required]
public string IncrementFileName { get; set; }
[Output]
public int Increment { get; set; }
public override bool Execute()
{
if (File.Exists(IncrementFileName))
{
string lines = File.ReadAllText(IncrementFileName);
int result;
if(Int32.TryParse(lines, out result))
{
Increment = result + 1;
}
else
{
Log.LogError("Unable to parse integer in '{0}' (contents of {1})");
return false;
}
}
else
{
Increment = 1;
}
if (SaveChange)
{
File.Delete(IncrementFileName);
File.WriteAllText(IncrementFileName, Increment.ToString());
}
return true;
}
}
}
I use this before the FileUpdateTask to get the next build number:
<IncrementTask
IncrementFileName="$(BuildNumberFile)"
SaveChange="false">
<Output TaskParameter="Increment" PropertyName="Build" />
</IncrementTask>
and as my final step (before notifying others) in the build:
<IncrementTask
IncrementFileName="$(BuildNumberFile)"
SaveChange="true"
Condition="'$(Configuration)' == 'Release'" />
Your other question of how to update the version number only when source code has changed is highly dependent on your how your build process interacts with your source control. Normally, checking in source file changes should initiate a Continuous Integration build. That is the one to use to update the relevant version number.
I have written one custome task you can refer the code below. It will create an utility to which you can pass assemblyinfo path Major,minor and build number. you can modify it to get revision number. Since in my case this task was done by developer i used to search it and again replace whole string.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
namespace UpdateVersion
{
class SetVersion
{
static void Main(string[] args)
{
String FilePath = args[0];
String MajVersion=args[1];
String MinVersion = args[2];
String BuildNumber = args[3];
string RevisionNumber = null;
StreamReader Reader = File.OpenText(FilePath);
string contents = Reader.ReadToEnd();
Reader.Close();
MatchCollection match = Regex.Matches(contents, #"\[assembly: AssemblyVersion\("".*""\)\]", RegexOptions.IgnoreCase);
if (match[0].Value != null)
{
string strRevisionNumber = match[0].Value;
RevisionNumber = strRevisionNumber.Substring(strRevisionNumber.LastIndexOf(".") + 1, (strRevisionNumber.LastIndexOf("\"")-1) - strRevisionNumber.LastIndexOf("."));
String replaceWithText = String.Format("[assembly: AssemblyVersion(\"{0}.{1}.{2}.{3}\")]", MajVersion, MinVersion, BuildNumber, RevisionNumber);
string newText = Regex.Replace(contents, #"\[assembly: AssemblyVersion\("".*""\)\]", replaceWithText);
StreamWriter writer = new StreamWriter(FilePath, false);
writer.Write(newText);
writer.Close();
}
else
{
Console.WriteLine("No matching values found");
}
}
}
}
I hate to say this but it seems that you may be doing it wrongly. Is much easier if you do generate the assembly versions on the fly instead of trying to patch them.
Take a look at https://sbarnea.com/articles/easy-windows-build-versioning/
Why I do think you are doing it wrong?
* A build should not modify the version number
* if you build the same changeset twice you should get the same build numbers
* if you put build number inside what microsoft calls build number (proper naming would be PATCH level) you will eventually reach the 65535 limitation.