I have been trying to implement something like this, but it will time out on the wait for exit?
My objective is to open the file on the client's machine in notepad. The below code is what i originally had, but just learned taht this will only work on the server ,not the client.
public JsonResult Index()
{
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.EnableRaisingEvents = false;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.FileName = "notepad";
proc.StartInfo.Arguments = #"\\share\test.XML";
proc.Start();
proc.WaitForExit();
}
Is there a way to do this?
All i am trying to do is open the test.xml file on a client's machine.
The code you have there will execute on the server side; not on the client-side. You can't open a file (or execute a program for that matter) on the client machine, from a browser. That would be a major security issue if a browser could do that.
Best thing you can do is either create a hyperlink to the file in the format file:///drive:/file.xml
Your code will start the notepad application and open the test.xml file in correctly
The notepad application will left open till it is close because you are using the WaitForExit method.
The WaitForExit method instructs the Process component to wait indefinitely for the associated process to exit.
Do you really want to use the WaitForExit in your MVC action
Please read the Remarks taken from MSDN for WaitForExit
The WaitForExit() overload is used to make the current thread wait
until the associated process terminates. This method instructs the
Process component to wait an infinite amount of time for the process
and event handlers to exit. This can cause an application to stop
responding. For example, if you call CloseMainWindow for a process
that has a user interface, the request to the operating system to
terminate the associated process might not be handled if the process
is written to never enter its message loop.
Note: In the .NET Framework version 3.5 and earlier versions, the WaitForExit() overload waited for MaxValue milliseconds (approximately
24 days), not indefinitely. Also, previous versions did not wait for
the event handlers to exit if the full MaxValue time was reached.
my weight the same and so I resolved using this
using System.Xml;
XmlTextReader reader = new XmlTextReader(
Server.MapPath("mycompany.xml"));
reader.WhitespaceHandling = WhitespaceHandling.None;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(reader);
reader.Close();
lbNodes.Items.Add("XML Document");
XmlNode xnod = xmlDoc.DocumentElement;
AddWithChildren(xnod, 1);
the complete example you can see here
http://www.codeproject.com/Articles/4902/Reading-an-XML-file-using-NET
Related
I am executing one .net console from another console App.
Eg MyTool.exe < input.txt
Where Input.txt will have all the input required by tool.
The input in the input file should be dyanmic, so to achive this.
I created another wrapper console App MyWrapper.exe.
This is first crating the input.txt file and then calling the MyTool.exe using .Net Process().
Content of batch file
MyTool.exe < input.txt
var proc = new Process();
proc.StartInfo.FileName = "MyBatchFIle.bat";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.Start();
Now here is the question.
Say in case of error or incorrect input, there is possibility that MyTool.exe can go to infinite loop.
So I want to detect this kind of error and stop the execution.
My plan is to execute the MyWrapper.exe from Windows scheduler.
Thanks,
Siraj
You could wait for the process to finish + Timeout. If the process did not finished within the timeout, you can kill it:
if(!proc.WaitForExit(timeout))
{
proc.Kill();
}
Another option is to communicate with the process via IPC (e.g. named pipes). But that requires the extension of both tools and increases complexity.
A third option is to communicate via files. For instance: having a status file that can be written by 'MyTool.exe' in format similar to "[process_ID] status". Then the wrapper could read that infomation periodically and kill the process, restart it or whatever is needed.
I am getting an exception on my server side code, which is serving up a silverlight app,
Win32Exception - No such interface supported
Our server side C# code starts up a separate process for a short task because of a third party dll not being thread safe. So the error above occurs in part of the code like this,
Process process = new Process();
ProcessStartInfo processStartInfo = new ProcessStartInfo();
processStartInfo.CreateNoWindow = true;
processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
processStartInfo.FileName =
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin", "PreviewGenerator.exe");
process.StartInfo = processStartInfo;
process.Start(); // THIS IS WHERE THE EXCEPTION OCCURS
process.WaitForExit();
The PreviewGenerator.exe process does not start when it is not working, the exception occurs where the comment is above.
UPDATE:
I have run process monitor on the IIS server when the issue occurs. This shows that the w3wp process does this,
Thread Create
Access the file PreviewGenerator.exe
Hive unloaded (this is the registry)
Thread Exit
And it does this before calling the other process. If I compare this with a the process monitor log when it is working it does this,
Thread Create
Access the file PreviewGenerator.exe
Process Start
Does heaps of stuff with PreviewGenerator.exe including reading / writing / registry, etc.
Process Exit
Hive unloaded
Thread Exit
But process monitor does not show any information as to why the first case doesn't work.
Is there a way I can see why the thread exits prematurely?
Also I think this problem relates to when my server is being loaded up more, and much more memory is being used. How can I prove this?
I had a similar issue, I used
processStartInfo.UseShellExecute = false;
and that fixed it for me.
http://www.progtown.com/topic31343-process-start-processstartinfo-startinfo.html
I found the best thing to do was to create a separate app pool for my application in IIS and set an upper limit for the amount of RAM it could use. Also I found it useful to turn on the 'Generate Recycle Event Log Entry' items under the app pool settings.
You can then go to the system event log and filter out the items with a source of 'WAS' to understand what is going on in the app pools, when they are restarting and when they stop from being idle etc.
I think the main problem in our case is that the IIS box was running out of memory. Tuning the app pools and adding some extra RAM seems to have solved it.
I would like to be able to watch a process until it is terminated, and once non existent display a message, how could this be achieved?
Create/Attach to the process and then either use WaitForExit() to block until it has exited, or use the OnExited Event if you don't wish your application to block while it's waiting for the app to exit.
I heartily recommend reviewing the documentation for Process - right here
The .NET Framework has built in support for this. You need to use the Process.Start method to start the process, and then call the WaitForExit method, which will block execution of your application until the process you started has finished and closed.
Sample code:
// Start the process.
Process proc = Process.Start("notepad.exe"); // TODO: NEVER hard-code strings!!!
// Wait for the process to end.
proc.WaitForExit();
// Show your message box.
MessageBox.Show("Process finished.");
Related knowledge base article: How to wait for a shelled application to finish using Visual C#
I think this is what you want to do:
System.Diagnostics.Process process=new System.Diagnostics.Process();
process.StartInfo.FileName = "process.exe";
process.Start();
process.WaitForExit();
//process ended
MessageBox.Show("Process terminated");
In my current project, i need to call a Unix shell script from the C# application. I also need to get the response back whether the script has been execute successfully or any error has occurred.
The C# program is running on a Windows machine. I need to connect to a Unix machine and execute the script.
Can anyone let me know how this can be done using C#?
Will this solve your problem?
sharpSsh - A Secure Shell (SSH) library for .NET
Update
Refer to the developer's site for SharpSSH for more information on how to use the tool.
Update 2
change link of developer site to archived link.
A straight forward way of preforming this using System.Diagnostics.Process
// Start the child process.
Process p = new Process();
// Redirect the error stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.FileName = "Write500Lines.exe";
p.Start();
// Do not wait for the child process to exit before
// reading to the end of its redirected error stream.
// p.WaitForExit();
// Read the error stream first and then wait.
string error = p.StandardError.ReadToEnd();
p.WaitForExit();
Even i had the same problem, i have googled for solution for around 1 month.
Finally, i have decided to use plink.exe (command line version of putty.exe) to connect to unix box and execute a script there.
You have to use plink through c# process, i have tried it and this works amazingly.
But rite now the problem i am facing is when i am running a script from c# process i am unable to pass arguments to that script. Probably it would be rite to say that i do not know how to do that.
Regards
-Aakash
I have an application that runs on my computer and the computers of my colleagues at work. I sometimes push out updates for this application and want the application to detect this automatically (perhaps via database) and shut down and re-open to install the new updates.
I know how I can close an application, but don't know how I can re-open it because when it's not running, I don't know how to execute any code...
ClickOnce handles updating an application very well. I don't see a problem here, if the user finds that the application is not working (because you have made a change server-side, that warrants them to update the client), they will restart the application and be prompted by the ClickOnce update mechanism to say an update is available (if this has been set up), once the application starts again.
The only way you could tell whether the application was due for an update, whilst the application in question is still running, is to poll the ClickOnce deployment file on the server and compare the version number against the current deployment. Not advisable.
Edit:
Another way to ensure that your users always have the most up-to-date version, is to not include a persistent deployment file and make the user always run from the launch page on your website. This would only dish out the latest and greatest version.
How about creating a small update app. When your application detects an update it launches the update app and closes itself. The update app downloads and installs the update and then relaunches the main app and closes itself.
Alternatively if the application can update itself when it opens, why does it need to shutdown? Can't it just release any resources it's using etc and perform the update.
The process you really need to have is something like this:
Application detects an update is required and executes an Update Application and then exits itself
Update application downloads and installs the update
Update application restarts the "main" application
The "Update application" may need administrative privileges to run if you're updating files on a Vista/Windows7 machine due to UAC, so you'd probably want to embed a manifest to help solve that.
To start another process, the code you'll want to execute is System.Diagnostics.Process.Start(), for example:
Process p = new Process();
p.StartInfo.FileName = "C:\\Windows\\System32\cmd.exe";
p.Start();
If you are using ClickOnce (and your tag suggests you are?) then you can configure it so your application checks for updates on start-up.
I had a similar problem, but mine was related to unmanageable memory leak that I couldn't find on an app that has to run 24/7. With the customer I agreed that safe time to restart the app was 03:00AM if the memory consumption was over the defined value.
I tried Application.Restart, but since it seems to use some mechanism that starts new instance while it is already running, I went for another scheme. I used the trick that file system handles persist until process that created them dies. So, from The Application, i dropped the file to the disk, and didn't Dispose() the handle. I used the file to send 'myself' executable and starting directory also (to add flexibility).
Code:
_restartInProgress = true;
string dropFilename = Path.Combine(Application.StartupPath, "restart.dat");
StreamWriter sw = new StreamWriter(new FileStream(dropFilename, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite));
sw.WriteLine(Application.ExecutablePath);
sw.WriteLine(Application.StartupPath);
sw.Flush();
Process.Start(new ProcessStartInfo
{
FileName = Path.Combine(Application.StartupPath, "VideoPhill.Restarter.exe"),
WorkingDirectory = Application.StartupPath,
Arguments = string.Format("\"{0}\"", dropFilename)
});
Close();
Close() at the end would initiate app shutdown, and file handle I used for StreamWriter here would be held open until process really dies. Then...
Restarter.exe comes into action. It TRIES to read the file in exclusive mode, preventing it to gain access until main app wasn't dead, then starts main app, deletes the file and exists. I guess that it can't be simpler:
static void Main(string[] args)
{
string filename = args[0];
DateTime start = DateTime.Now;
bool done = false;
while ((DateTime.Now - start).TotalSeconds < 30 && !done)
{
try
{
StreamReader sr = new StreamReader(new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite));
string[] runData = new string[2];
runData[0] = sr.ReadLine();
runData[1] = sr.ReadLine();
Thread.Sleep(1000);
Process.Start(new ProcessStartInfo { FileName = runData[0], WorkingDirectory = runData[1] });
sr.Dispose();
File.Delete(filename);
done = true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Thread.Sleep(1000);
}
}