I am trying to launch a process within an application. The code below simply starts notepad on clicking the button of the main GUI. Now when the notepad is launched the button is disabled. I have subscribed to the Process.Exited even to receive notification when the notepad application closes. Once the notification is received I would like to re-enable the button again.
However, code crashed when I call the button1.IsEnabled = true; It seems to that Process.Exit is not a part of the main GUI thread and hence when i try to update GUI within that it crashed. Also when i am debugging I dont receive any exception saying I am trying to access main thread from outside or something.
Is there a way to notify GUI when the child process exits?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Diagnostics;
namespace ProcessWatch
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
Process pp = null;
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
pp = new Process();
pp.EnableRaisingEvents = true;
pp.Exited += new EventHandler(pp_Exited);
ProcessStartInfo oStartInfo = new ProcessStartInfo();
oStartInfo.FileName = "Notepad.exe";
oStartInfo.UseShellExecute = false;
pp.StartInfo = oStartInfo;
pp.Start();
button1.IsEnabled = false;
}
void pp_Exited(object sender, EventArgs e)
{
Process p = sender as Process;
button1.IsEnabled = true;
}
}
}
Try the following:
void pp_Exited(object sender, EventArgs e){
Dispatcher.BeginInvoke(new Action(delegate {
button1.IsEnabled = true;
}), System.Windows.Threading.DispatcherPriority.ApplicationIdle, null);
}
Related
This question already has an answer here:
How to run code before program exit? [duplicate]
(1 answer)
Closed 4 years ago.
When a WinFromApp.exe written in C# is closing,
it finally should start another Prog.exe.
Important, the WinFromApp.exe shouldn't wait for a result of Prog.exe.
The WinFromApp.exe should completly close while Prog.exe runs.
[This is my 2nd using of this forum for place a Question.]
I still have programmed many with Dreamweaver MS-Office-VBA...
Visual Studio (2017) programming is new for me. Because of this, I need also to know where to place the code/code-part(s).
I have as From "Welcome.cs"
["++...++" in Code marks the done including from Anu Viswan.]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using Microsoft.VisualBasic;
using Microsoft.Win32;
using HardwareHelperLib;
namespace Welcome
{
public partial class Welcome : Form
{
public Welcome()
{
InitializeComponent();
+Application.ApplicationExit += Application_ApplicationExit;+
}
private void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
...;
}
private void wb_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
...;
}
private void Welcome_Load(object sender, EventArgs e)
{
...;
}
private void button1_Click(object sender, EventArgs e)
{
...;
}
++private void Application_ApplicationExit(object sender, EventArgs e)
{
var process = new ProcessStartInfo("notepad.exe");
Process.Start(process);
}
private void Welcome_FormClosing(object sender, FormClosingEventArgs e)
{
var process = new ProcessStartInfo("notepad.exe");
Process.Start(process);
}++
}
}
And Program.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Win32;
namespace Welcome
{
static class Program
{
/// <summary>
/// Der Haupteinstiegspunkt für die Anwendung.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Welcome());
}
}
}
I have to place this:
Application.ApplicationExit += Application_ApplicationExit;
by here [+...+], and it is working = THANK YOU VERY MUCH !!!
This question already has an answer here:
How to run code before program exit? [duplicate]
I have looked at this link, but not found the answer of my Question...
Because as I has written in my Question:
Visual Studio (2017) programming is new for me. Because of this, I need also to know where to place the code/code-part(s).
Sorry, until yesterday the last years I used stackoverflow only as a Reader.
So I am also new at stackoverflow doing Questions.
Assuming your application is WinForm app, you can do this with ApplicationExit event.
First you need to subscribe for application exit and FormClosing event.
Application.ApplicationExit += Application_ApplicationExit;
and then, in the event, you can use Process.Start to invoke the second exe.
private void Application_ApplicationExit(object sender, EventArgs e)
{
var process = new ProcessStartInfo("notepad.exe");
Process.Start(process);
}
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
var process = new ProcessStartInfo("notepad.exe");
Process.Start(process);
}
I am currently trying to make my mp3 player for a project.
I have written this code by following a guide:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
string[] files, path;
[STAThread]
private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
files = openFileDialog1.SafeFileNames;
path = openFileDialog1.FileNames;
for (int i = 0; i < files.Length; i++)
{
listBox1.Items.Add(files[i]);
}
}
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
axWindowsMediaPlayer1.URL = path[listBox1.SelectedIndex];
}
}
}
And heres a screen of my form:
For some reason when I click the OPEN button, nothing happens. First when I used this code I got an error about "Form1_load", but since I wasn't using this, I just deleted the error line and then there was no errors found.
I am very clueless, so anyone with ANY idea what is wrong?
I followed this guide completely:
http://www.c-sharpcorner.com/UploadFile/8ea152/mp3-media-player-in-C-Sharp-4-0/
Thanks
First of all make sure that you have assigned click event for your button for that just double click on your button from design window if it redirects you to the buttonclick method then everything is fine and if it does not then assign it first. For that
public Form1()
{
InitializeComponent();
button1.Click += button1_Click;
}
And
Why do you require [STAThread] here? I mean just remove the attribute and try again because [STAThread] is used for below reson:-
The STAThreadAttribute marks a thread to use the Single-Threaded COM
Apartment if COM is needed. By default, .NET won't initialize COM at
all. It's only when COM is needed, like when a COM object or COM
Control is created or when drag 'n' drop is needed, that COM is
initialized. When that happens, .NET calls the underlying
CoInitializeEx function, which takes a flag indicating whether to join
the thread to a multi-threaded or single-threaded apartment.
For more information :-
http://blogs.msdn.com/b/jfoscoding/archive/2005/04/07/406341.aspx
Recently I had an idea for a simple auto restarter for my server exe.
Basically all it does is
Checks if there is a process named WerFault running
If there is that means the server has crashed, so it closes both the server and WerFault
After that opens the server again.
The second thing it checks for is if the wServer is even running, if not it starts it up.
This all is within a timer with a delay of 10 seconds.
However I am very sure that there is a much more efficient way of doing this. I learned C# on my own (have not read a single book, all I know was acquired thru self learning + Google).
Also the reason why I want the server to be open 24/7 is because it will run on a vps.
Note: This is a windows forms application.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Diagnostics;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void timer1_Tick(object sender, EventArgs e)
{
Process[] prs = Process.GetProcesses();
foreach (Process pr in prs)
{
if (pr.ProcessName == "WerFault")
{
pr.Kill();
if (pr.ProcessName == "wServer")
{
pr.Kill();
Process.Start(#"C:\Users\Arturs\Dropbox\ROTMGServer-master\bin\Debug\wServer\wServer.exe");
}
return;
}
}
if (pr.ProcessName == "wServer")
{
return;
}
Process.Start(#"C:\Users\Arturs\Dropbox\ROTMGServer-master\bin\Debug\wServer\wServer.exe");
return;
}
private void button1_Click(object sender, EventArgs e)
{
timer1.Start();
}
private void timer2_Tick(object sender, EventArgs e)
{
}
}
}
}
You've written:
if (pr.ProcessName == "WerFault")
{
pr.Kill();
{
if (pr.ProcessName == "wServer")
{
// ...
It is unlikely that there will ever be a process pr whose ProcessName is both the string "WerFault" and the string "wServer".
Perhaps you want to move the second if outside of the first one.
I need to cancel the device back button event. I have tried the solution posted in Control press "back button" and disable close the application using a dialog for confirm - wp7, but it is not working for me. Am I doing something wrong? The application always exits whether ok or cancel is selected from the dialog box.
Here is my code...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.IO;
using System.Windows.Media.Imaging;
using System.Windows.Resources;
namespace GodTools
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
this.CordovaView.Loaded += CordovaView_Loaded;
BackKeyPress += OnBackKeyPressed;
}
private void CordovaView_Loaded(object sender, RoutedEventArgs e)
{
this.CordovaView.Loaded -= CordovaView_Loaded;
// first time load will have an animation
Storyboard _storyBoard = new Storyboard();
DoubleAnimation animation = new DoubleAnimation()
{
From = 0,
Duration = TimeSpan.FromSeconds(0.6),
To = 90
};
Storyboard.SetTarget(animation, SplashProjector);
Storyboard.SetTargetProperty(animation, new PropertyPath("RotationY"));
_storyBoard.Children.Add(animation);
_storyBoard.Begin();
_storyBoard.Completed += Splash_Completed;
}
void Splash_Completed(object sender, EventArgs e)
{
(sender as Storyboard).Completed -= Splash_Completed;
LayoutRoot.Children.Remove(SplashImage);
}
void OnBackKeyPressed(object sender, System.ComponentModel.CancelEventArgs e)
{
var result = MessageBox.Show("Do you want to exit?", "Attention!",
MessageBoxButton.OKCancel);
if (result == MessageBoxResult.OK)
{
// Do not cancel navigation
return;
}
e.Cancel = true;
}
}
}
see also, same problem from the Cordova side
"backbutton" event won't fire
For your information: If you write an application (not an XNA game) you shoul avoid canceling back button. Otherwise your app will be canceled on passing Marketplace sertification.
Also you can override OnBackKeyPress method with the same code;
protected override void OnBackKeyPress(CancelEventArgs e)
{
var result = MessageBox.Show("Do you want to exit?", "Attention!",
MessageBoxButton.OKCancel);
if (result == MessageBoxResult.OK)
{
base.OnBackKeyPress(e);
return;
}
e.Cancel = true;
}
update
I've just created a new 'Silverlight for windows phone" solution. Opened MainPage.xaml.cs file and added this code to it:
// Constructor
public MainPage()
{
InitializeComponent();
BackKeyPress += OnBackKeyPressed;
}
void OnBackKeyPressed(object sender, System.ComponentModel.CancelEventArgs e)
{
var result = MessageBox.Show("Do you want to exit?", "Attention!",
MessageBoxButton.OKCancel);
if (result == MessageBoxResult.OK)
{
// Do not cancel navigation
return;
}
e.Cancel = true;
}
so there is only one page in this project. And it works. The target platform is Windows Phone OS 7.1, I've checked it on Mango device and on the standard emulator. I think the problem is somewhere else. Maybe some code crashes you application while you are trying to cancel back event?
Please, try to check it on new simple project.
I've tried this for one whole day and kinda gave up researching
What i basically need to do is to update the info on the first page after selecting this button on form2
What i did was this :
private void btnContinue_Click(object sender, System.Windows.RoutedEventArgs e)
{
// TODO: Add event handler implementation here.
Screen_1 S1 = new Screen_1();
S1.CO2.Text = "TEXT";
S1.CO3.Visibility = Visibility.Visible;
//NavigationService.Source=new Uri("/Screen_1.xaml", UriKind.Relative);
//NavigationService.Navigate(new Uri("/Screen_1.xaml", UriKind.Relative));
}
For some reason its not updating and navigation on expression blend doesnt work if i have code behind the button :(
Update:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Expression.Prototyping.WindowsPhone.Mockups;
using System.Windows.Navigation;
namespace Analyser2_v1Screens
{
public partial class Select : WindowsPhoneChrome
{
Screen_1 formOne = null;
public Select()
{
// Required to initialize variables
InitializeComponent();
}
public Select(Screen_1 formOneInstance)
{
// Required to initialize variables
InitializeComponent();
formOne = formOneInstance;
}
private void clickedC(object sender, System.Windows.RoutedEventArgs e)
{
// TODO: Add event handler implementation here.
//Screen_1 S1 = new Screen_1();
// S1.CO2.Content = "This is string content of a Button";
// S1.CO3.Visibility = Visibility.Visible;
// S1.test1.Text = "Tet";
//NavigationService.Source=new Uri("/Screen_1.xaml", UriKind.Relative);
//NavigationService.Navigate(new Uri("/Screen_1.xaml", UriKind.Relative));
formOne.test1.Text ="test";
}
}
}
STill not perfect enough
Please share a snippet of your code. From I understand from your question, you can pass form 1's instance to form 2's constructor and alter elements of form1 from there.
// form 1 var
FormOne formOne = null;
// form 2's constructor
public FormTwo(FormOne formOneInstance)
{
/*initialization etc*/
formOne = formOneInstance;
}
// some method to alter an element in form 1
private void AlterSomthingInFormOne()
{
formOne.SomeString = "Whatever value you'll need";
}