This question already has answers here:
How do I properly exit a C# application?
(4 answers)
Closed 5 years ago.
New to the threading and its concepts. I have following code where I am using Windows.Forms in console app to print a webpage.
My Code looks like below:
My Application does print the page but it never exists . its stuck at Application.Run();
How do I make my application exit?
Thanks for helping out.
( if I use Application.DoEvents(); wb.print(); does not print. )
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace WebBrowserWithoutAForm
{
class Program
{
private static bool completed = false;
private static WebBrowser wb;
[STAThread]
static void Main(string[] args)
{
wb = new WebBrowser();
wb.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(wb_DocumentCompleted);
wb.Navigate("http://www.google.com");
while (!completed)
{
//Application.DoEvents();
Application.Run();
}
Console.Write("\n\nDone with it!\n\n");
Console.ReadLine();
}
static void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
Console.WriteLine(wb.Document.Body.InnerHtml);
wb.Print();
completed = true;
}
}
}
MSDN for Application.Run says:
In a Win32-based or Windows Forms application, a message loop is a
routine in code that processes user events, such as mouse clicks and
keyboard strokes. Every running Windows-based application requires an
active message loop, called the main message loop. When the main
message loop is closed, the application exits. In Windows Forms, this
loop is closed when the Exit method is called, or when the
ExitThread method is called on the thread that is running the main
message loop.
The Exit method this talks about is Application.Exit.
Related
This question already has answers here:
Run a console application from a windows Form
(3 answers)
Closed 1 year ago.
I made a Console Application with C# in VS.
I want to make a button, which runs some code. In this case, what I wrote in the Console Application. How would one go about that?
Basically I want to create a set of buttons, where each executes a specific task.
How would I do this? How can I take that code I created earlier and have a button execute it?
I can mention two options of many:
Deal with your Console app as a DLL and reference it in your WinForm Runner App.
Deal with your Console app as an EXE file and run it using Process.Start.
The first option will give you the ability to reach the methods while the second one will deal with it as a totally separate app with all its functionalities as a single application.
Example of the Second Option:
Create a Solution with three projects as in the screenshot below.
Suppose your Console App 1 code is
using System;
namespace SOC.ConsoleApp01
{
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Written from Console App 1");
Console.ReadLine();
}
}
}
While the second is
using System;
namespace SOC.ConsoleApp02
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Written from Console App 2");
Console.ReadLine();
}
}
}
Now build the Console App1 and Console App 2 by right click on each of them in the solution explorer and click Build or ReBuild.
This will result in execution files generated like in the following screenshots:
In your WinForm Project write the code of Subject buttons like this
using System;
using System.Diagnostics;
using System.Windows.Forms;
namespace SO.Console.Apps.Runner
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Process.Start(#"C:\REPOS\SO.Console.Apps.Runner\SOC.ConsoleApp01\bin\Debug\SOC.ConsoleApp01.exe");
}
private void button2_Click(object sender, EventArgs e)
{
Process.Start(#"C:\REPOS\SO.Console.Apps.Runner\SOC.ConsoleApp02\bin\Debug\SOC.ConsoleApp02.exe");
}
}
}
the result is
This question already has answers here:
How can I execute code after my form starts?
(5 answers)
Closed 5 years ago.
I am fairly new to C# but I feel like this should output "hi":
using System;
using System.Windows.Forms;
using System.Diagnostics;
namespace PathMet_Controller
{
class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
Debug.WriteLine("hi");
}
}
}
My output window gives me this:
In playing around, it did output "hi" once, but it would only output after I stop running the file.
Because Application.Run will start special loop which will end when you exit your win forms application.
If you want to print something at start, use events provided by Form class.
So i was searching a way to set a hotkey to be able to exit a console application.
On my way i found this thread: Global hotkey in console application
which helped me a lot.
So basically i am setting a hotkey to exit my application. My code looks like this:
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
namespace ConsoleHotKey
{
class Program
{
static void Main(string[] args)
{
HotKeyManager.RegisterHotKey(Keys.A, KeyModifiers.Alt);
HotKeyManager.HotKeyPressed += new EventHandler<HotKeyEventArgs>(HotKeyManager_HotKeyPressed);
Console.ReadLine();
}
static void HotKeyManager_HotKeyPressed(object sender, HotKeyEventArgs e)
{
Environment.Exit(1);
}
}
}
and my question is: Is it a good way to exit a console application like this?
I found some poeple saying that it is not such a good way but i couldn't understand why.
Can someone give me some clarifications please?
This question already has answers here:
Capture console exit C#
(10 answers)
Closed 8 years ago.
I am looking for a way to trigger a piece of code when a console application is manually closed (users closes window). Been trying with:
AppDomain.CurrentDomain.ProcessExit +=
new EventHandler(CurrentDomain_ProcessExit);
but the above doesn't work if manually closed.
Is there any ways to use a .Net call for this or do I need to import the Kernel dll and do it that way?
This code works to catch the user closing the console window:
using System;
using System.Runtime.InteropServices;
class Program {
static void Main(string[] args) {
handler = new ConsoleEventDelegate(ConsoleEventCallback);
SetConsoleCtrlHandler(handler, true);
Console.ReadLine();
}
static bool ConsoleEventCallback(int eventType) {
if (eventType == 2) {
Console.WriteLine("Console window closing, death imminent");
}
return false;
}
static ConsoleEventDelegate handler; // Keeps it from getting garbage collected
// Pinvoke
private delegate bool ConsoleEventDelegate(int eventType);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool SetConsoleCtrlHandler(ConsoleEventDelegate callback, bool add);
}
Beware of the restrictions. You have to respond quickly to this notification, you've got 5 seconds to complete the task. Take longer and Windows will kill your code unceremoniously. And your method is called asynchronously on a worker thread, the state of the program is entirely unpredictable so locking is likely to be required. Do make absolutely sure that an abort cannot cause trouble. For example, when saving state into a file, do make sure you save to a temporary file first and use File.Replace().
You need to hook to console exit event and not your process.
http://geekswithblogs.net/mrnat/archive/2004/09/23/11594.aspx
Capture console exit C#
In a C# .NET GUI Application. I also need the console in the background for some tasks. Basically, I'm using a Thrid Party library for some processing (takes lot of time) which writes its intermediate results to console. This processing is a computationally time taking task. So, I'm assigning this task to backgroundworker. I mean background worker calls these library functions. But problem is there is no way for me to show the user status of computation, because I don't have source of the library. I was hoping Console will be shown. But surprisingly Console.WriteLine doesn't seem to work. I mean, there isn't any console window shown. How come?
EDIT:
I tried setting application type = console. But there seems to be a problem. Only, main thread is able to access the console. Only Console.WriteLines executed by main (Application) thread are displayed on console. Console.WriteLines executed by other (BackgroundWorker)threads of the GUI, the output is not shown. I need console only for Background workers. I mean, When background worker starts, console starts & when it ends console will be off.
Create your own console window and use the Console.SetOut(myTextWriter); method to read anything written to the console.
Set your application type to "Console Application". Console applications can also create GUI windows with no problem, and write to the console at the same time.
If you don't have control of the main application, and you want to make sure that a console is shown, you can p/invoke AllocConsole (signature here).
This isn't the same as being a console application though, your application will always get a separate console window, which might be surprising to someone who launched it from a command prompt window. You can work around that with AttachConsole (signature and example here) but shell redirection of the output still won't work. That's why I suggest setting the application subsystem to console if you can.
Followed by #jgauffin, here is the implementation of Console.SetOut method.
Create a TextWriter inherited class.
using System;
using System.Text;
using System.IO;
using System.Windows.Forms;
namespace ConsoleRedirection
{
public class TextBoxStreamWriter : TextWriter
{
TextBox _output = null;
public TextBoxStreamWriter(TextBox output)
{
_output = output;
}
public override void Write(char value)
{
base.Write(value);
_output.AppendText(value.ToString()); // When character data is written, append it to the text box.
}
public override Encoding Encoding
{
get { return System.Text.Encoding.UTF8; }
}
}
}
And in the Form, code as below.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace ConsoleRedirection
{
public partial class FormConsole : Form
{
// That's our custom TextWriter class
TextWriter _writer = null;
public FormConsole()
{
InitializeComponent();
}
private void FormConsole_Load(object sender, EventArgs e)
{
// Instantiate the writer
_writer = new TextBoxStreamWriter(txtConsole);
// Redirect the out Console stream
Console.SetOut(_writer);
Console.WriteLine("Now redirecting output to the text box");
}
// This is called when the "Say Hello" button is clicked
private void txtSayHello_Click(object sender, EventArgs e)
{
// Writing to the Console now causes the text to be displayed in the text box.
Console.WriteLine("Hello world");
}
}
}
Original code is from https://saezndaree.wordpress.com/2009/03/29/how-to-redirect-the-consoles-output-to-a-textbox-in-c/
You can check the link for cross-thread calls and advanced implementations at comments.