I'd like to Run Code on Application Exit. My Problem is that I have two Application. The First is running. My Second Application now is going to Close the First Application. But on Closing I'd like to run code in the First Application.
public class First
{
public static Main(string[] args)
{
Console.ReadLine();
}
public void DoSomethingOnExit()
{
Console.WriteLine("It Works");
Thread.Sleep(1000);
}
}
public class Second
{
public void method(int number)
{
var prozess = Process.GetProcessById(number);
prozess.Close();
}
}
Try this...
static void Main(string[] args)
{
_handler += new EventHandler(Handler);
SetConsoleCtrlHandler(_handler, true);
Console.WriteLine("Running");
Console.ReadLine();
}
[DllImport("Kernel32")]
private static extern bool SetConsoleCtrlHandler(EventHandler handler, bool add);
private delegate bool EventHandler(CtrlType sig);
static EventHandler _handler;
enum CtrlType
{
CTRL_C_EVENT = 0,
CTRL_BREAK_EVENT = 1,
CTRL_CLOSE_EVENT = 2,
CTRL_LOGOFF_EVENT = 5,
CTRL_SHUTDOWN_EVENT = 6
}
private static bool Handler(CtrlType sig)
{
switch (sig)
{
case CtrlType.CTRL_C_EVENT:
case CtrlType.CTRL_LOGOFF_EVENT:
case CtrlType.CTRL_SHUTDOWN_EVENT:
case CtrlType.CTRL_CLOSE_EVENT:
DoSomeShutdownStuff();
return true;
default:
return false;
}
}
Related
I tried to execute a function when closing the program it works when I do CTRL + C but when I close it with the "X" the function is not fully executed.
So I would like to know if you know why and if so how to fix the problem.
I tried to do what is mentioned on this page Capture console exit C#.
Thank you in advance for your answers.
static void Main(string[] args)
{
_handler += new EventHandler(Handler);
SetConsoleCtrlHandler(_handler, true);
}
enum CtrlType
{
CTRL_C_EVENT = 0,
CTRL_BREAK_EVENT = 1,
CTRL_CLOSE_EVENT = 2,
CTRL_LOGOFF_EVENT = 5,
CTRL_SHUTDOWN_EVENT = 6
}
private static bool Handler(CtrlType sig)
{
example();
exitSystem = true;
Environment.Exit(-1);
return true;
}
public static bool exitSystem = false;
[DllImport("Kernel32")]
private static extern bool SetConsoleCtrlHandler(EventHandler handler, bool add);
private delegate bool EventHandler(CtrlType sig);
static EventHandler _handler;
public static void example()
{
for (int i = 0; i < 250000; i++)
Console.WriteLine(i);
}
I don't know this is a bug or my mistake?, After Code Virtualization return the empty value.
[assembly: Obfuscation(Feature = "Apply to type *: apply to member * when method or constructor: virtualization", Exclude = false)]
namespace ConsoleApp17
{
class Program
{
private static bool valueWritten = false;
private static int sharedValue = 0;
private static void ThreadOneStart()
{
sharedValue = 1000;
valueWritten = true;
}
private static void ThreadTwoStart()
{
if (valueWritten) Console.Write(sharedValue == 1000 ? "Good" : "Bad");
}
static void Main(string[] args)
{
Thread threadOne = new Thread(ThreadOneStart);
Thread threadTwo = new Thread(ThreadTwoStart);
threadOne.Start();
threadTwo.Start();
threadOne.Join();
threadTwo.Join();
Console.ReadKey();
}
}
}
The given program has a race condition. This implies that the program behavior is undefined. It has nothing to do with Eazfuscator.NET.
Here is the right way do that:
[assembly: Obfuscation(Feature = "Apply to type *: apply to member * when method or constructor: virtualization", Exclude = false)]
class Program
{
private static bool valueWritten = false;
private static int sharedValue = 0;
private static ManualResetEvent ev = new ManualResetEvent(false);
private static void ThreadOneStart()
{
sharedValue = 1000;
valueWritten = true;
ev.Set();
}
private static void ThreadTwoStart()
{
ev.WaitOne();
if (valueWritten) Console.Write(sharedValue == 1000 ? "Good" : "Bad");
}
static void Main(string[] args)
{
Thread threadOne = new Thread(ThreadOneStart);
Thread threadTwo = new Thread(ThreadTwoStart);
threadOne.Start();
threadTwo.Start();
threadOne.Join();
threadTwo.Join();
Console.ReadKey();
}
}
I have a small function I want called when my process exits, however, upon closing (via the red exit button) the function will not execute.
My code is as follows:
namespace Client
{
class Program
{
static void Main(string[] args)
{
var callback = new InstanceContext(new ClientCallback());
var client = new MyServiceClient(callback);
client.Open();
client.Register();
AppDomain.CurrentDomain.ProcessExit += (sender, EventArgs) =>
{
client.checkOut();
};
Console.WriteLine("Press a key to exit");
Console.ReadKey();
client.checkOut();
client.Close();
}
}
}
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
HandlerRoutine hr = new HandlerRoutine(InspectControlType);
SetConsoleCtrlHandler(hr, true);
Console.WriteLine("Click on Windows Close Button");
Console.ReadLine();
}
[DllImport("Kernel32")]
public static extern bool SetConsoleCtrlHandler(HandlerRoutine Handler, bool Add);
public delegate bool HandlerRoutine(ControlTypes CtrlType);
public enum ControlTypes
{
CTRL_C_EVENT = 0,
CTRL_BREAK_EVENT,
CTRL_CLOSE_EVENT,
CTRL_LOGOFF_EVENT = 5,
CTRL_SHUTDOWN_EVENT
}
private static bool InspectControlType(ControlTypes ctrlType)
{
Console.WriteLine("Hello You choose to end this program.Do you really want to close? :" + ctrlType.ToString());
Console.ReadLine();
return true;
}
}
}
Source
I've created a console application that needs to run in the background of my client application and has to invoke a method after a certain period of time. So far I've tried the below with little success but it doesn't seem to be working.
Furthermore, in a situation where I wanted to use the same timer to invoke more than one method, then what would I do?
class Program
{
static void Main(string[] args)
{
Console.ReadLine();
const bool generate = true;
NewBookingTimer(generate);
}
public static void NewBookingTimer(bool generate)
{
if (!generate) return;
var newBookingTimer = new Timer();
newBookingTimer.Elapsed += (sender, e) => NewBooking();
var random = new Random();
int randomNumber = random.Next(0, 500);
newBookingTimer.Interval = randomNumber;
newBookingTimer.Enabled = true;
}
public static void NewBooking()
{
var dbObject = new DbConnect();
dbObject.OpenConnection();
var bookingObject = new GenerateBooking();
bookingObject.NewBooking();
}
}
He he ... Try this:
static void Main(string[] args)
{
const bool generate = true;
NewBookingTimer(generate);
Console.ReadLine();
}
The way you do it, it's waiting for you to enter a line , and then it closes ... so obviously, it won't do anything.
Turning them around, it'll fire your events, and run until you hit Enter :)
Regarding the multiple calls, Do you want it to call Method_A and Methdod_B every time it fires ? You can just have both of them in the event that you raise. Otherwise, do explain better what you want.
Here's your code slightly modified:
static void Main(string[] args)
{
const bool generate = true;
NewBookingTimer(generate);
Console.ReadLine();
}
public static void NewBookingTimer(bool generate)
{
if (!generate) return;
var newBookingTimer = new Timer();
newBookingTimer.Elapsed += (sender, e) => NewBooking();
newBookingTimer.Elapsed += (sender, e) => OldBooking();
var random = new Random();
int randomNumber = random.Next(0, 500);
Console.Out.WriteLine("Random = " + randomNumber);
newBookingTimer.Interval = randomNumber;
newBookingTimer.Enabled = true;
}
public static void NewBooking()
{
Console.Out.WriteLine("this is NEW booking");
}
public static void OldBooking()
{
Console.Out.WriteLine("this is OLD booking");
}
and here's the result:
This code executes the 2 methods on the same timer. The only trick was the multi-line lambda timer handler.
class Program
{
static void Main(string[] args)
{
Console.ReadLine();
const bool generate = true;
NewBookingTimer(generate);
Console.WriteLine("Running...");
Console.ReadLine();
}
public static void NewBookingTimer(bool generate)
{
if (!generate) return;
var newBookingTimer = new Timer();
newBookingTimer.Elapsed += (sender, e) =>
{
MethodA();
MethodB();
};
var random = new Random();
int randomNumber = random.Next(0, 500);
newBookingTimer.Interval = randomNumber;
newBookingTimer.Enabled = true;
}
public static void MethodA()
{
Console.WriteLine("in method A");
}
public static void MethodB()
{
Console.WriteLine("in method B");
}
}
I'm trying to display the console output (cout) of a method in a dll to a textbox in C# program. Every time I call the method, the console output will be displayed in the Output Pane of Visual Studio. Is there a way to redirect the content of the Output Pane to the textbox?
The dll was written by someone else in C++ and I have no control in changing it.
The dll is wrapped using SWIG so that it can be called by my C# code.
After following the link suggested by David, I decided to write a solution to your problem which is more specific to your case. This version allows you to receive the stdout in your GUI via a BackgroundWorker PropertyChangedEventHandler call back.
Here's the code for the ConsoleRedirector:
public class ConsoleRedirector : IDisposable
{
private static ConsoleRedirector _instance;
public static void attach(ProgressChangedEventHandler handler, bool forceConsoleRedirection)
{
Debug.Assert(null == _instance);
_instance = new ConsoleRedirector(handler, forceConsoleRedirection);
}
public static void detatch()
{
_instance.Dispose();
_instance = null;
}
public static bool isAttached
{
get
{
return null != _instance;
}
}
private static void ResetConsoleOutStream()
{
//Force console to recreate its output stream the next time Write/WriteLine is called
typeof(Console).GetField("_out", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).SetValue(null, null);
}
private const int PERIOD = 500;
private const int BUFFER_SIZE = 4096;
private volatile bool _isDisposed;
private BackgroundWorker _worker;
private readonly IntPtr _stdout;
private readonly Mutex _sync;
private readonly System.Threading.Timer _timer;
private readonly char[] _buffer;
private readonly AnonymousPipeServerStream _outServer;
private readonly TextReader _outClient;
private readonly bool _forceConsoleRedirection;
private StreamWriter _consoleStandardOut;
private ConsoleRedirector(ProgressChangedEventHandler handler, bool forceConsoleRedirection)
{
bool ret;
_forceConsoleRedirection = forceConsoleRedirection;
if (!_forceConsoleRedirection)
{
//Make sure Console._out is initialized before we redirect stdout, so the redirection won't affect it
TextWriter temp = Console.Out;
}
AnonymousPipeClientStream client;
_worker = new BackgroundWorker();
_worker.ProgressChanged += handler;
_worker.DoWork += _worker_DoWork;
_worker.WorkerReportsProgress = true;
_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
_sync = new Mutex();
_buffer = new char[BUFFER_SIZE];
_outServer = new AnonymousPipeServerStream(PipeDirection.Out);
client = new AnonymousPipeClientStream(PipeDirection.In, _outServer.ClientSafePipeHandle);
Debug.Assert(_outServer.IsConnected);
_outClient = new StreamReader(client, Encoding.Default);
ret = SetStdHandle(STD_OUTPUT_HANDLE, _outServer.SafePipeHandle.DangerousGetHandle());
Debug.Assert(ret);
if (_forceConsoleRedirection)
{
ResetConsoleOutStream(); //calls to Console.Write/WriteLine will now get made against the redirected stream
}
_worker.RunWorkerAsync(_outClient);
_timer = new System.Threading.Timer(flush, null, PERIOD, PERIOD);
}
void _worker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = (BackgroundWorker)sender;
TextReader client = (TextReader)e.Argument;
try
{
while (true)
{
int read = client.Read(_buffer, 0, BUFFER_SIZE);
if (read > 0)
worker.ReportProgress(0, new string(_buffer, 0, read));
}
}
catch (ObjectDisposedException)
{
// Pipe was closed... terminate
}
catch (Exception ex)
{
}
}
private void flush(object state)
{
_outServer.Flush();
}
public void Dispose()
{
Dispose(true);
}
~ConsoleRedirector()
{
Dispose(false);
}
private void Dispose(bool disposing)
{
if (!_isDisposed)
{
lock (_sync)
{
if (!_isDisposed)
{
_isDisposed = true;
_timer.Change(Timeout.Infinite, Timeout.Infinite);
_timer.Dispose();
flush(null);
try { SetStdHandle(STD_OUTPUT_HANDLE, _stdout);}
catch (Exception) { }
_outClient.Dispose();
_outServer.Dispose();
if (_forceConsoleRedirection)
{
ResetConsoleOutStream(); //Calls to Console.Write/WriteLine will now get redirected to the original stdout stream
}
}
}
}
}
private const int STD_OUTPUT_HANDLE = -11;
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetStdHandle(int nStdHandle, IntPtr hHandle);
[DllImport("kernel32.dll")]
private static extern IntPtr GetStdHandle(int nStdHandle);
}
Here's a link to a complete sample form which demonstrates how to use it: ConsoleRedirector Example Form