How restart the Console app? - c#

I need to restart the app Console when the user press "R".
I have this
Console.WriteLine(message, "Rebuild Log Files"
+ " Press Enter to finish, or R to restar the program...");
string restar = Console.ReadLine();
if(restar.ToUpper() == "R")
{
//here the code to restart the console...
}
thanks

// Starts a new instance of the program itself
System.Diagnostics.Process.Start(Application.ExecutablePath);
// Closes the current process
Environment.Exit(0);

static void Main(string[] args)
{
var info = Console.ReadKey();
if (info.Key == ConsoleKey.R)
{
var fileName = Assembly.GetExecutingAssembly().Location;
System.Diagnostics.Process.Start(fileName);
}
}

I don't think you really need restart whole app. Just run required method(s) after pressing R. No need to restart.

Another simple way
//Start process, friendly name is something like MyApp.exe (from current bin directory)
System.Diagnostics.Process.Start(System.AppDomain.CurrentDomain.FriendlyName);
//Close the current process
Environment.Exit(0);

I realize that this is 7 years old, but I just came across this. I think actually calling the executable and closing the current program is a bit of a cluge. As stated before, this is being over thought. I think that the cleanest and most modular way is to take everything that is in the Main method and make a different method, let's say Run() that contains everything that was in the Main method and then call the new Run() method from the Main method or wherever in the code it is desired to re-start the program.
So if the Main method looked like this:
static void Main(string[] args)
{
/*
Main Method Variable declarations;
Main Method Method calls;
Whatever else in the Main Method;
*/
int SomeNumber = 0;
string SomeString = default(string);
SomeMethodCall();
//etc.
}
Then just create a Run() method and put everything from Main into it, like so:
public static void Run()
{
//Everything that was in the Main method previously
/*
Main Method Variable declarations;
Main Method Method calls;
Whatever else in the Main Method;
*/
int SomeNumber = 0;
string SomeString = default(string);
SomeMethodCall();
//etc.
}
Now that the Run() method is created and it has all the stuff that was in the Main method before, just make your main method like so:
static void Main(string[] args)
{
Run();
}
Now, wherever in the code you want to "re-start" the program, just call the Run() method like so:
if(/*whatever condition is met*/)
{
//do something first
//then "re-start" the program by calling Run();
Run();
}
So this is a look at the whole program simplified:
EDIT: When I posted this originally I didn't take into consideration any arguments that might have been passed to the program. To account for this four things need to be changed in my original answer.
declare a global List<string> like this:
public static List<string> MainMethodArgs = new List<string>();.
In the Main method set the value of the MainMethodArgs list equal to the
values passed into the Main method via args like this:
MainMethodArgs = args.ToList();
When creating the Run() method change the signature so that it expects a
string[] called args to be passed to it like this:
public static void Run(string[] args)
{
....
}
Wherever in the program the Run() method is called, pass MainMethodArgs
to Run() like this:
Run(MainMethodArgs.ToArray());
I changed the example below to reflect these changes.
using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ExampleConsole
{
class Program
{
public static List<string> MainMethodArgs = new List<string>();
static void Main(string[] args)
{
MainMethodArgs = args.ToList();
Run(MainMethodArgs.ToArray());
}
public static void Run(string[] args)
{
Console.WriteLine("Run() is starting");
Console.ReadLine();
//stuff that used to be in the public method
int MainMethodSomeNumber = 0;
string MainMethodSomeString = default(string);
SomeMethod();
//etc.
}
public static void SomeMethod()
{
Console.WriteLine("Rebuild Log Files"
+ " Press Enter to finish, or R to restar the program...");
string restar = Console.ReadLine();
if (restar.ToUpper() == "R")
{
//here the code to restart the console...
Run(MainMethodArgs.ToArray());
}
}
}
}
In effect the program is "re-started" without having to re-run the executable and close the existing instance of the program. This seems a lot more "programmer like" to me.
Enjoy.

try like this:
// start new process
System.Diagnostics.Process.Start(
Environment.GetCommandLineArgs()[0],
Environment.GetCommandLineArgs()[1]);
// close current process
Environment.Exit(0);

Ended up with something like this.
#if DEBUG
Process.Start("dotnet", Environment.GetCommandLineArgs().Prepend("run").Take(2));
#else
Process.Start(Environment.CommandLine);
#endif
Quit.ConsoleShutdown(null, null);
I'm sure this specific line: Process.Start("dotnet", Environment.GetCommandLineArgs().Prepend("run").Take(2)); can be improved on though, since it looks a bit confusing at first glance.

Launch a second exe that ends the console program, starts a new instance, and ends itself?
be explicit, how is it in code?
This namespace should have everything you need, if that is a solution you want to pursue.
http://msdn.microsoft.com/en-us/library/system.diagnostics.process.aspx

//here the code to restart the console...
System.Diagnostics.Process.Start(Environment.GetCommandLineArgs()[0], Environment.GetCommandLineArgs().Length > 1 ? string.Join(" ", Environment.GetCommandLineArgs().Skip(1)) : null);

Everybody is over-thinking this. Try something like this:
class Program : IDisposable
{
class RestartException : Exception
{
public RestartException() : base()
{
}
public RestartException( string message ) : base(message)
{
}
public RestartException( string message , Exception innerException) : base( message , innerException )
{
}
protected RestartException( SerializationInfo info , StreamingContext context ) : base( info , context )
{
}
}
static int Main( string[] argv )
{
int rc ;
bool restartExceptionThrown ;
do
{
restartExceptionThrown = false ;
try
{
using ( Program appInstance = new Program( argv ) )
{
rc = appInstance.Execute() ;
}
}
catch ( RestartException )
{
restartExceptionThrown = true ;
}
} while ( restartExceptionThrown ) ;
return rc ;
}
public Program( string[] argv )
{
// initialization logic here
}
public int Execute()
{
// core of your program here
DoSomething() ;
if ( restartNeeded )
{
throw new RestartException() ;
}
DoSomethingMore() ;
return applicationStatus ;
}
public void Dispose()
{
// dispose of any resources used by this instance
}
}

Related

Pointing a function to another

Suppose I have two functions:
void DoesNothing(){}
void OnlyCalledOnce(){
//lines of code
}
Is it possible to call OnlyCalledOnce and it actually run DoesNothing ? I imagine something like this:
void DoesNothing(){}
void OnlyCalledOnce(){
//lines of code
OnlyCalledOnce = DoesNothing;
}
and after that last line, whenever I called OnlyCalledOnce it would run DoesNothing.
Is it possible?
You can simply return early in OnlyCalledOnce like this: (assuming your DoesNothing example literally does nothing - it isn't needed)
bool initialized = false;
void OnlyCalledOnce()
{
if (initialized) return;
// firsttimecode
initialized = true;
}
The initialized variable will be true after first run.
Did you try to use delegate?
class Program
{
private static Action Call = OnlyCalledOnce;
public static void Main(string[] args)
{
Call();
Call();
Call();
Console.ReadKey();
}
static void DoesNothing()
{
Console.WriteLine("DoesNothing");
}
static void OnlyCalledOnce()
{
Console.WriteLine("OnlyCalledOnce");
Call = DoesNothing;
}
}
Another way you could solve this is to maintain a list of strings that represent the methods that have been called. The strings don't even have to be the method name, they just need to be unique to each method.
Then you can have a helper method called ShouldIRun that takes in the function's unique string and checks to see if it exists in the list. If it does, then the method returns false, and if it doesn't, then the method adds the string to the list and returns true.
The nice thing here is that you don't have to maintain a bunch of state variables, you can use this with as many methods as you want, and the methods themselves don't need any complicated logic - they just ask the helper if they should run or not!
public class Program
{
private static List<string> CalledMethods = new List<string>();
static bool ShouldIRun(string methodName)
{
if (CalledMethods.Contains(methodName)) return false;
CalledMethods.Add(methodName);
return true;
}
// Now this method can use method above to return early (do nothing) if it's already ran
static void OnlyCalledOnce()
{
if (!ShouldIRun("OnlyCalledOnce")) return;
Console.WriteLine("You should only see this once.");
}
// Let's test it out
private static void Main()
{
OnlyCalledOnce();
OnlyCalledOnce();
OnlyCalledOnce();
GetKeyFromUser("\nDone! Press any key to exit...");
}
}
Output
As already stated, you can use this:
private bool isExecuted = false;
void DoesNothing(){}
void OnlyCalledOnce(){
if (!isExecuted)
{
isExecuted = true;
//lines of code
DoesNothing();
}
}
If you have multiple threads etc, you can do a lock(object) ..
What's your problem with this?
void DoesNothing()
{
}
void OnlyCalledOnce()
{
DoesNothing();
}
It will run DoesNothing() once you run OnlyCalledOnce()

Resharper test runner not outputting Console.WriteLine()?

Why is it that Console.Writeline() will work when executing from a console app main() method; but when I execute the same using resharpers test runner I do not see the Console.Writeline() in the test runner output window?
The best way to explain this is with an example.
I am using: Resharper Ultimate 2017.1.3, Visual Studio 2017 Community, and .Net 4.6.1 framework. Language is C#. I also installed (via nuget) nunit framework 2.6.4.
First create a class library and copy paste the following in to a .cs file.
using System;
using System.Collections;
using System.Threading;
using NUnit.Framework;
namespace ObserverPatternExample
{
[TestFixture]
internal class ObserverTestFixture
{
[Test]
public void DemonstrateObserverPattern()
{
var subject = new Subject();
var a = new Observer(subject, "a");
var b = new Observer(subject, "b"); // etc. as many observers as you want.
subject.Go();
}
}
// "subject" is observer pattern lingo. The "subject" will do the broadcasting to the observers.
public class Subject
{
public delegate void CallbackHandler(string s);
public event CallbackHandler NotifyEvent;
private const int waitTimeInMilliseconds = 200;
private readonly Simulator simulator = new Simulator();
public string FakeSimulatorState { get; set; }
public void Go()
{
new Thread(Run).Start(); // a good thing to notice: events cross thread boundaries!!!
}
private void Run()
{
foreach (string s in simulator)
{
Console.WriteLine("Subject: " + s);
FakeSimulatorState = s;
NotifyEvent?.Invoke(s);
Thread.Sleep(
waitTimeInMilliseconds); // we do this to "pretend" that the simulator is actually doing someting.
}
}
}
public class Observer : IObserverPattern // the "observer" will subscribe to the event being broadcast by the "subject"
{
private readonly string _name;
public Observer(Subject subject, string name)
{
_name = name;
subject.NotifyEvent += Update;
}
public void Update(string state)
{
Console.WriteLine("Observer {0}: {1}", _name, state);
}
}
internal interface IObserverPattern
{
void Update(string state);
}
public class Simulator : IEnumerable
{
private readonly string[] _stateSequence = { "BEGIN", "CRAWL", "WALK", "JUMP", "END" };
public IEnumerator GetEnumerator()
{
foreach (var s in _stateSequence)
yield return s;
}
}
}
And now execute the test. I expect to see the Console.WriteLine() calls display strings in the Resharper test runner output window. But I don't. For example here is a screenshot:
Now let's perform the exact same sequence, but this time we'll call the client code from a new console project main() method. To set this up copy paste the following code and reference the class library you created in the steps above.
using ObserverPatternExample;
namespace ConsoleApp1
{
internal class Program
{
private static void Main(string[] args)
{
var subject = new Subject();
var a = new Observer(subject, "a");
var b = new Observer(subject, "b"); // etc. as many observers as you want.
subject.Go();
}
}
}
Next execute the console app. You should see the following displayed:
Can anyone please explain how I can configure either my code or the test runner to display the output in the test runner output window?
* UPDATE *
I made partial success. InBetween's suggestion to use a TraceListener made me realize I should be using a ConsoleTraceListener. To faciliate this I modified the unit test to appear like this:
using System.Threading;
using NUnit.Framework;
namespace ObserverPatternExample.DontUse
{
[TestFixture]
internal class ObserverTestFixture
{
[SetUp]
public void Setup()
{
Trace.Listeners.Add(new ConsoleTraceListener());
}
[TearDown]
public void TearDown()
{
Trace.Flush();
}
[Test]
public void DemonstrateObserverPattern()
{
var subject = new Subject();
var a = new Observer(subject, "a");
var b = new Observer(subject, "b"); // etc. as many observers as you want.
subject.Go();
}
}
And the results are surprising: I do get SOME output; but only the initial BEGIN state. Which appears like this:
Short story: I'm still looking for a solution.
*** SOLUTION ****
[Test]
public void DemonstrateObserverPattern()
{
var subject = new Subject();
var a = new Observer(subject, "a");
var b = new Observer(subject, "b"); // etc. as many observers as you want.
subject.Go();
Thread.Sleep(1000); // <--- add this to force test runner to wait for other thread to complete.
}
It looks like Resharper is finishing before your thread completes. Your call to
Thread(Run).Start();
is non-blocking. This means the test thread will complete before the Go thread does, hence you get no results.
See https://msdn.microsoft.com/en-us/library/6x4c42hc(v=vs.110).aspx where is states "Note that the call to Start does not block the calling thread."

Access statusbar on form from cplex callback function c#

I'm working with an C# .Net application that uses Cplex DLL's for an optimization operation, and during that operation I want to write status progress to a statusbar on the that initiated the operation.
This is the general layout of the specific form;
namespace ActResMain
{
public class FormOptimize : System.Windows.Forms.Form
{
private callCplex()
{
//...
cplex.Use(new Cplex_ContinuousCallback());
cplex.Solve()
}
public void Update_OptimizeStatusbarPanel(String strText)
{
statusBarPanel_1.Text = strText;
statusBar1.Refresh();
}
internal class Cplex_ContinuousCallback : Cplex.ContinuousCallback
{
FormOptimize formOpt = new FormOptimize();
public override void Main()
{
//From here I want to edit the statusbar at FormOptimize. I can write progress to console without any problems, but cannot reach function "Update_OptimizeStatusbarPanel".
//If I include "FormOptimize formOpt = new FormOptimize" here, i get Visual studio exception on illegal window reference.
}
}
}
}
I have also tried invoking the Update_OptimizeStatusbarPanel function like this:
internal class Cplex_ContinuousCallback : Cplex.ContinuousCallback
{
FormOptimize formOpt = new FormOptimize();
public override void Main()
{
FormCollection fc = Application.OpenForms;
var mpc = fc[1];
Type type = mpc.GetType();
MethodInfo dynMethod = type.GetMethod("Update_OptimizeStatusbarPanel");
dynMethod.Invoke(mpc, new object[] { String.Format("Running Optimization: {0} iterations ", Niterations)});
}
}
But then I get an exception from visual studio stating that an object created by one thread cannot be modified from another thread.
Maybe this is something stupid that I have missed, but help is greatly appriciated
EDIT: I edited the code as per Mohammad Dehghans suggestion,
public class FormOptimize : System.Windows.Forms.Form
{
private callCplex()
{
cplex.Use(new Cplex_ContinuousCallback(this));
cplex.Solve()
}
internal class Cplex_ContinuousCallback : Cplex.ContinuousCallback
{
FormOptimize _formOptimize;
public Cplex_ContinuousCallback(FormOptimize formOptimize)
{
this._formOptimize = formOptimize;
}
public override void Main()
{
if (Niterations % 10 == 0)
{
_formOptimize.Update_OptimizeStatusbarPanel(0, String.Format("Running Optimization: {0} iterations ", Niterations), 0);
}
}
}
public void Update_OptimizeStatusbarPanel(short panelIndex, String strText, short severity)
{
if (statusBar1.InvokeRequired)
statusBar1.Invoke(new Action<short, string, short>(Update_OptimizeStatusbarPanel), panelIndex, strText, severity);
else
{
if (panelIndex == 0)
{
//...
statusBarPanel_0.Text = strText;
}
else if (panelIndex == 1)
{
//...
statusBarPanel_1.Text = strText;
}
statusBar1.Refresh();
}
}
}
But by doing that I apparently broke something, as the application just ..stops after statusBar1.Invoke() is called the first time. If I pause the debugger it says that cplex.Solve() is executing, but then nothing more happens.
First of all, you need to pass the instance of your form to the implemented callback class, so when the Main method is called, you have access to the exact instance that is being shown on the screen.
Secondly, you need to use Invoke method to update the UI controls from anther thread (I've not worked with CPLEX so far, but I guess the callback is invoked from another thread. That's usual).
Read this for more information.
The complete code could be:
public class FormOptimize : System.Windows.Forms.Form
{
private callCplex()
{
//Misc code
cplex.Use(new Cplex_ContinuousCallback(this)); // <-- passing `this`
cplex.Solve()
//Misc code
}
public void Update_OptimizeStatusbarPanel(String strText)
{
if (statusBarPanel_1.InvokeRequired)
statusBarPanel_1.Invoke(Action<string>(Update_OptimizeStatusbarPanel), strText);
else
{
statusBarPanel_1.Text = strText;
statusBar1.Refresh();
}
}
internal class Cplex_ContinuousCallback : Cplex.ContinuousCallback
{
FormOptimize _formOptimize;
public Cplex_ContinuousCallback(FormOptimize formOptimize)
{
this._formOptimize = formOptimize;
}
public override void Main()
{
//...
_formOptimize.Update_OptimizeStatusbarPanel(String.Format("Running Optimization: {0} iterations ", Niterations));
}
}
}

C# Calling a Method Inside another Method

public static void Main2(string[] args)
{
WebRequest_BeginGetRequeststream.RequestCheck();
WebRequest_BeginGetRequeststream.ReadCallback(IAsyncResult asynchronousResult);
}
This is the Method I want to call.
static void OnMsg(SteamFriends.FriendMsgCallback callback)
{
string msg = callback.Message;
//Announcement Related Messages
if (msg == "RequestCheck")
{
Main2 (string[] args);
Console.WriteLine("Starting Operation Line for Announcement Creation.");
Console.WriteLine("Version 1.08 of Announcement Code Initiated.");
}
}
This is where I want to call the method, I had everything else set but I wanted to make it so that inside the...
if (msg == "RequestCheck")
{
Main2 (string[] args);
Console.WriteLine("Starting Operation Line for Announcement Creation.");
Console.WriteLine("Version 1.08 of Announcement Code Initiated.");
}
It can call Main2 which will run the WebRequests, It tells me that I need to make a return type and when I do that, I get a whole bunch of errors.
How can I call inside Method OnMsg and call Main2 without disrupting the Method.
by the way, to get to where I am now. I had been following this code.
public class AllMethods
{
public static void Method2()
{
// code here
}
}
class Caller
{
public static void Main(string[] args)
{
AllMethods.Method2();
}
}
I had seen that this method had works and tried to try it our but I still have problems calling inside OnMsg.
Write Main2 (args); instead, where args is a string[], for example new string[]{"foo", "bar"} or null. Alternativly, you can implicitly pass specified arguments to the call as an array if you add params to the main methods argument args: public static void Main2(params string[] args) { ... }
you need to pass the parameters to the Main2 function, in this case an array of strings.

C# Making a delegate available to a class

I would like to make a delegate available to an entire class. The point of this is to allow a called method from an external class' backgroundWorker to continually report back through all of it's methods (ExternalClass.Run(); calls ExternalClass.Method2(); ExternalClass.Method3(); etc and they all need to send several progress reports. It seems inefficient to have to continually pass the delegate.
I've tried initializing an instance of the delegate globally and setting it to equal the passed instance in Run(); for each method to then have available to it but I am given an error that a null object cannot be implicitly converted.
thanks!
I cannot show the code I am working with as I do not currently have it with me (it's on my laptop) but I will try to better explain now. PSEUDO-CODE:
class form1 : form {
backgroundWorker_doWork()
{
Class2.Run();
}
backgroundWorker_OnProgressChange()
{
// do this
}
}
class class2{
Run(){
OtherMethod();ThirdMethod();
}
OtherMethod(){ //need to call backgroundWorker.ReportProcess(int, string)}
ThirdMethod(){ //need to call backgroundWorker.ReportProcess(int, string)}
}
I really don't want to have to pass it every time is the point, i'd like to somehow pass it to class2
You should show your code that isn't working and the exact error message. It should be fine - here's an example:
using System;
class Demo
{
private readonly Action action;
public Demo(Action action)
{
this.action = action;
}
public void FirstMethod()
{
Console.WriteLine("In first method");
action();
}
public void SecondMethod()
{
Console.WriteLine("In second method");
action();
}
}
class Test
{
static void Main()
{
Demo demo = new Demo(() => Console.WriteLine("Action called"));
demo.FirstMethod();
demo.SecondMethod();
}
}
You can use the InvokeMethod function from a backgroundWorker to allow the worker to execute any delegate, example below (also waits for the invoke to finish, which you may not need):
BackgroundWorker Function (C++.net)
BackgroundWorkerFunction()
{
::IAsyncResult ^ThreadResult;
SetTileCount_Delegate ^SetCountDel = gcnew SetTileCount_Delegate(this, &PartDetail::SetTileCount_Function);
//RecordingContainer is the class I am invoking into
ThreadResult = this->RecordingContainer->BeginInvoke(
SetCountDel, ThisTest->RecordingsCache->Count);
WaitForInvokeTimeOutOrCompletion(ThreadResult);
}
System::Void WaitForInvokeTimeOutOrCompletion(IAsyncResult ^ThreadResult)
{
if(ThreadResult == nullptr) return;
long SleepTotal = 0;
long SleepInterval = 100;
while ((SleepTotal <= 2000) && !ThreadResult->IsCompleted)
{
ThreadResult->AsyncWaitHandle->WaitOne(SleepInterval, false);
SleepTotal += SleepInterval;
}
}

Categories

Resources