I use AllocConsole() to open a Console in a winform application.
How can I prevent the application from exiting when the Console is closed?
EDIT
The update of completionpercentage from time to time is what I want to show in console
void bkpDBFull_PercentComplete(object sender, PercentCompleteEventArgs e)
{
AllocConsole();
Console.Clear();
Console.WriteLine("Percent completed: {0}%.", e.Percent);
}
I tried the richtextBox as the alternative
s =(e.Percent.ToString());
richTextBox1.Clear();
richTextBox1.AppendText("Percent completed: " +s +"%");
But I can't see the completionpercentage update time to time. It only appears when it is 100% complete.
Any alternative?
I know this is a task that seldom pops up but I had something similar and decided to go with a couple hacks.
http://social.msdn.microsoft.com/Forums/vstudio/en-US/545f1768-8038-4f7a-9177-060913d6872f/disable-close-button-in-console-application-in-c
-Disable the "Close" button on a custom console application.
You're textbox solution should work as well. It sounds a lot like your calling a function from the main thread that is tying up the form which is also on the main thread and is causing you grief when updating your textbox. Consider creating a new thread and either an event handler to update your textbox or use the invoke methodinvoker from the new thread to update the textbox. Link below from an already answered question on how to complete this.
How to update textboxes in main thread from another thread?
public class MainForm : Form {
public MainForm() {
Test t = new Test();
Thread testThread = new Thread((ThreadStart)delegate { t.HelloWorld(this); });
testThread.IsBackground = true;
testThread.Start();
}
public void UpdateTextBox(string text) {
Invoke((MethodInvoker)delegate {
textBox1.AppendText(text + "\r\n");
});
}
}
public class Test {
public void HelloWorld(MainForm form) {
form.UpdateTextBox("Hello World");
}
}
Refer to the answers over here. As mentioned in the answers, there is no way to stop the application from getting closed.
But as a workaround, you can have your own text output solution described in one of the answers.
You can build first the console application that recieves arguments and writes it to the console. Place it, where the main application starts.
From main application you can first kill process and then reopen it with a new argument.
It's the altarnative way.
Related
This question already has answers here:
Run one instance of program
(2 answers)
Closed 9 years ago.
There is an option in my application to hide the window - form.hide(), and to put an notifyicon in the system tray, and when you click the notifyicon there will be a form.show().
If someone will try to run two instances of the app, I want
a. not to run the new instance
b. to show the window of the first instance
I already have a loop to check if a process with the same name exists.
and I can tell the new app not to run ( return in the program.cs before Application.run(new form()))
but I yet have to tell the first app to show its main window.
I have the process (of the first instance) , i can get its handle its id etc.
the question
How to show the window using it's process?
For the first part of the question, here is what you can do. Add this in the Main before you show your form. The benefit of this is that you don't check by process name (which might not be unique), but you create a mutex which is somehow "global".
using (Mutex applicationMutex = new Mutex(true, "SomeRandomTextHere", out mutexCreated))
{
if (!mutexCreated)
{
// Application is already running. Aborting..
return;
}
// Application.Run(..) goes here, plus other interesting stuff
}
For the second part of your question I would suggest the following:
Create a named event and set it initially to false. Then create a worker thread in your application that monitors this event. When it is signaled, Invoke your Show method from your main form.
Another approach is to search for the window handle of the main process and bring it to front. This article can give you ideas.
Bear in mind that doing a loop through all processes is not as efficient as using a mutex. If you don't care about speed, clean code and you just want this app to work then use this loop.. To me code is poetry.
Rewrote the code just for you this will give you exactly what you want. It will check for duplicates and focus the screen when a duplicate is opened.
EventWaitHandle ProgramOpen = new EventWaitHandle(false, EventResetMode.ManualReset, "ProgramOpen198472");
EventWaitHandle FocusProgram = new EventWaitHandle(false, EventResetMode.ManualReset, "FocusMyProgram198472");
private delegate void focusConfirmed(); Thread FocusCheck;
private void focus() { FocusProgram.WaitOne(); this.Invoke(new focusConfirmed(()=>{this.Show(); this.BringToFront();}));}
private void Form1_Load(object sender, EventArgs e)
{
if (ProgramOpen.WaitOne(0))
{
FocusProgram.Set();
this.Close();
}
ProgramOpen.Set();
}
private void HideButton_Click(object sender, EventArgs e)
{
this.Hide();
FocusProgram.Reset();
FocusCheck = new Thread(focus);
FocusCheck.Start();
}
private void showToolStripMenuItem_Click(object sender, EventArgs e)
{
FocusProgram.Set();
}
I'm currently writing an IRC bot/client and I have stumbled upon a small problem. Every channel is to be displayed in a separate window with its own set of controls. I have created an appropriate window class ChanWindow:
public partial class ChanWindow : Form
{
string Chan;
string Username;
IRCBot Caller;
public ChanWindow(string channame, string uname, IRCBot caller)
{
Caller = caller;
Caller.Join(channame);
InitializeComponent();
Chan = channame;
Name = Chan;
Username = uname;
}
//various functionalities required for window use
}
I'm storing the window objects in a ConcurrentDictionary<string, ChanWindow>, because there is (supposed to be) a separate thread sending appropriately edited messages to windows. They are all initialized in a loop:
foreach (string chan in Chanlist)
{
Chans[chan] = new ChanWindow(chan, Name, this);
Chans[chan].Show();
}
Where Chanlist is a List<string> of channels to join.
Having witnessed the windows die shortly after the program starts, I put a breakpoint in the line Username = uname; of ChanWindow constructor and noticed it being tripped immediately before the window's death.
My main question is: what is the cause and how can I avoid it? Is using a Dictionary a good idea? Should I build some sort of wrapper/container class which would handle the window's functionality?
I suspect you don't have
Application.Run(new ChanWindow());
in your main entry point (Program.Main() by default).
If you don't make the main GUI thread Show the form, and wait for it to close, nothing will stop the thread from completeing and your application closing.
If you want to start the message loop independently you will still need to call Application.Run() so the main thread will start handling events. If you call it without a parameter the message loop won't stop automatically so you'll have to call Application.Exit() explicitly when you want the message loop to stop. Then the main thread will then continue to the end of the program and end.
You could just do this to your code,
foreach (string chan in Chanlist)
{
Chans[chan] = new ChanWindow(chan, Name, this);
Chans[chan].Show();
}
Application.Run();
but, if you want to automatically exit the application you could inherit your own ApplicationContext, as outlined in the already linked MSDN documentation, and pass that to Application.Run(), that is what its for after all.
I've got a form called MyForm, and I want to edit it's properties in the middle of the program's execution, from outside of the class itself.
Here's what I got:
static void Main()
{
MyForm main = new MyForm();
main.ShowDialog();
main.Text = "Hello";
}
However, it seems like ShowDialog() just freezes the program until I close the form, so main.Text = "Hello"; won't be executed until I close the form.
I've also tried using main.Show() but it just closes the form after I've executed all the code in my Main() function, so the text "Hello" will only flash quickly.
I would need it so that I can have the form open at all times and change it's controls in the middle of the program's execution, from outside of the class itself.
How can I achieve this? Should I run the form in a different thread or something?
There are multiple questions here, you should try to focus on one at a time, so let me highlight the questions.
Why does my program close when Main exits?
How can I avoid "freezing" the program when showing a form?
How can I access the contents of a form from elsewhere?
Answers:
That's the design of how the lifetime of a program is. When the main thread (running the Main method) terminates, the program closes. Any open forms are closed in the process. Solution is to not allow Main to exit, typically by using Application.Run(main); in your case, showing the form and waiting for it to close.
You use Show and not ShowDialog, but since you have no other form keeping the program open, your program closes. Show returns after showing the form, returning to whatever the program was doing. In your case, the program has nothing left to do, so it terminates.
You need to store a reference to your form somewhere the rest of your program can access it, you can use a static field/property somewhere, or you can pass the form around to the various parts that need it.
First of all, I don't know what is your specific scenario. Perhaps my solution is good for you, but if it isn't, please, try to tell us what exactly are you trying to achieve.
static void Main()
{
var main = new MyForm();
//Initialize a new thread with the `DoSomething()` method
//and pass the form as a parameter
var thread = new Thread(() => DoSomething(main)) {IsBackground = true};
thread.Start();
main.ShowDialog();
}
static void DoSomething(MyForm main) {
//Update the form title
main.Text = "Hello";
//Wait one second
Thread.Sleep(1000);
//Update the form title again
main.Text = "World";
}
I have written an application in C#. But even after closing the form, the application will be running. That is .exe and .vshost files will be still running. So i have used the following Code to terminate the application. But it is not terminating.
public void Form1_Closing(object sender, FormClosingEventArgs e)
{
Process[] pArry = new Process[500];
pArry = Process.GetProcesses();
foreach (Process p in pArry)
{
string s1 = p.ProcessName;
s1 = s1.ToLower();
if ((s1.Equals("new_prj.vshost")))
{
p.Kill();
}
}
}
My project name is new_prj. And if i write the same code snippet in Button_Click function, it works properly. But not working in form closing function. Has anybody come across the same problem?
Can you use this ?
Application.Exit();
There can be several reasons for this.
If it's a multithreaded application then you might have another thread running preventing the process from terminating.
Please provide some more details.
EDIT
I posted a similar question and and got some input about how to use threads. See this post.
Here is a some usefull code from an answer to the post:
public void Start()
{
workerThread = new Thread(() => DoWork());
doWork = true;
workerThread.IsBackground = true;
workerThread.Start();
}
Notice the IsBackground = true;.
If you really want to quit your application from anywhere you can use Environment.Exit() but I would suggest to solve the problem with your form. If you post more of your code we might be able to find the problem.
You can try Application.Exit too, but as Carsten said, you are trying to treat the symptom rather than the cause.
Have you tried simply using Application.Exit()?
I'm creating an application that uses .Net and Mono, it uses cross-threaded forms as I was having bad response from the child windows.
I created a test program with 2 forms: the first (form1) has a single button (button1) and the second (form2) is blank, code snippet below.
void openForm()
{
Form2 form2 = new Form2();
form2.ShowDialog();
}
private void button1_Click(object sender, EventArgs e)
{
Thread x = new Thread(openForm);
x.IsBackground = true;
x.Start();
}
This works fine in .Net, but with Mono, the first window will not gain focus when you click it (standard .ShowDialog() behaviour) rather than .Show() behaviour as .Net uses.
When I use .Show(), on .Net and Mono the window just flashes then disappears. If I put a 'MessageBox.Show()' after 'form2.Show()' it will stay open until you click OK.
Am I missing something in that code or does Mono just not support that? (I'm using Mono 2.8.1)
Thanks in advance, Adrian
EDIT: I realised I forgot 'x.IsBackground = true;' in the code above so child windows will close with the main window.
It's almost never the right thing to do in a Windows app to have more than one thread talk to one window or multiple windows which share the same message pump.
And it's rarely necessary to have more than one message pump.
The right way to do this is either to manually marshal everything back from your worker threads to your Window, using the 'Invoke' method, or use something like BackgroundWorker, which hides the details for you.
In summary:
Don't block the UI thread for time-consuming computation or I/O
Don't talk to the UI from more than one thread.
If you use Winforms controls, you shold "touch" the object always in main UI thread.
And at least - calling new Form.ShowDialog() in new thread does not make sense.
EDIT:
If you want easy work with Invoke/BeginInvoke you can use extension methods:
public static class ThreadingExtensions {
public static void SyncWithUI(this Control ctl, Action action) {
ctl.Invoke(action);
}
}
// usage:
void DoSomething( Form2 frm ) {
frm.SyncWithUI(()=>frm.Text = "Loading records ...");
// some time-consuming method
var records = GetDatabaseRecords();
frm.SyncWithUI(()=> {
foreach(var record in records) {
frm.AddRecord(record);
}
});
frm.SyncWithUI(()=>frm.Text = "Loading files ...");
// some other time-consuming method
var files = GetSomeFiles();
frm.SyncWithUI(()=>{
foreach(var file in files) {
frm.AddFile(file);
}
});
frm.SyncWithUI(()=>frm.Text = "Loading is complete.");
}