I launch some batch file from my C# app via Process class. This file started java app. I cant recognize which process called java.exe must be kill to stop this application. Is there some more elegant way than kill them all, hope that i end the right one and dont kill some other important java app? Thanks for any help I really stuck there.
Cheers,
Andrew
EDIT: I missed the batch file part. This answer will only be useful if you can launch the process directly from C#...
When you start the process you can store the process Id so you can get the process back later and kill it.
Process p = new Process();
//set all the process start Info...
p.Start();
someVariableICanGetToLater = p.Id
//Later when you need to kill the process...
Process pToKill = Process.GetProcessById(someVariableICanGetToLater);
pToKill.Kill();
I assume that, since the batch file launches the Java app, knowing the id of the batch file process won't help.
Process.GetProcessesByName("java") gives you a list of all the java.exe instances.
pseudo code . Fill in OS specific calls here:
int cs_pid=getProcessByName("CSharpAppName");
int javaPid[]= getProcessByName("JavaAppName");
bool javaToCSharpRelationship[]=new bool[javaPid.size];
int loopCounter=0;
forEach int in javaPid
begin
if(isChildOf(cs_pid,java_pid))
begin
// OS call or Wrapper to determine relationship between c# pid
// and Java app PID
javaToCSharpRelationShip[loopCounter]=true;
//can call kill here if you like
end
else
javaToCSharpRelationShip[loopCounter]=false;
loopCounter++;
end
At the end of this code you should have an array of PID's which are children of the C# app.
Unless the batch file does lots of things, hard to accomplish using only .NET's Process and ProcessStartInfo classes, another option would be to start directly java.exe and control the arguments and environment variables via ProcessStartInfo's Arguments and EnvironmentVariables properties.
Then you could use Jason's approach to store java.exe process' id in order to kill it later.
Related
I'm trying to detect if a process I'm launching via my C# program still answers or not.
I've tryed the following :
Process *notepads[];
notepads = Process::GetProcessesByName("Notepad.exe");
// Test to see if the process is responding.
if (notepads[0]->Responding())
notepads[0]->CloseMainWindow();
else
notepads[0]->Kill();
However, I would like to find a Qt equivalent for ANY process (not only MMI processes).
Do you know how I could do that ?
Getting process list is OS-dependent. so you have to do it by yourself on each platform.
on Windows, you can use Windows API EnumProcesses
on Linux, you can search /proc folder.
See QProcess documentation for details.
Qt does not provide any method to obtain information or control overs process that you don't explicitely start from a QProcess instance.
I have a question that I believe that is complex. I have an application that I execute under my Windows and it takes a long time to finish. I want to keep it running (normally), however I want to kill the file on disk - but obviously it's not possible because it's locked / in-use. I need a way to disassociate it from the running process to kill it and at the same time keep the file running. Any example of code or tool is very welcome.
Well, workarounds are welcome, for example, if there is a way to spawn it from a process, key the master and migrate the child to kill the app, or any other idea that works is welcome - even the ugly ones. :)
Thanks.
A couple of suggestions (completely stolen) from this questions answers:
You could use the MoveFileEx api function to mark the file for deletion upon next reboot.
You can inject a dll to close the handle yourself:
The typical method is as follows. You've said you want to do this in C# so here goes...
If you don't know which process has the file locked, you'll need to examine each process's handle list, and query each handle to determine if it identifies the locked file. Doing this in C# will likely require P/Invoke or an intermediary C++/CLI to call the native APIs you'll need.
Once you've figured out which process(es) have the file locked, you'll need to safely inject a small native DLL into the process (you can also inject a managed DLL, but this is messier, as you then have to start or attach to the .NET runtime).
That bootstrap DLL then closes the handle using CloseHandle etc.
Essentially: the way to unlock a "locked" file is to inject a DLL into the offending process's address space and close it yourself. You can do this using native or managed code. No matter what, you're going to need a small amount of native code or at least P/Invoke into the same.
Helpful links:
http://www.codeproject.com/KB/threads/winspy.aspx
http://damianblog.com/2008/07/02/net-code-injection/
That is a matter the application you want to kill has to handle. It shouldn't keep files open during a long running process. If the application doesn't close the file, killing it will lead to exception in that application.
Not sure if this will work on every Windows version, but here it is:
Rename process executable "foo.exe" to "foo.old"
Put new "foo.exe" to correct place
Send message to process, so it will execute new "foo.exe" image and terminate himself.
On start, remove "foo.old" file in program directory.
Update: oops, looks like you do not want to put new image, just remove old one. Then MoveFileEx is only "legal" option.
Suppose there is a exe or process which finds process id of newly start process i have to use that pid in some other program but the main problem is that the process that finds pid has while(true ) loop. i.e infinite loop so i cant return any value from it. is there any solution .if yes then please help me.
How about writing the PID that you find to some common external storage like a
File in a common location accessible by both programs
Database table accessible by both programs.
How do I programmatically self delete?
C# / .NET Compact Framework 2 / Windows Mobile 6
Please, I don't want to discuss WHY to do it, I just need to know HOW to do it!
Important:
The "second application" approach is NOT an option. (Unless that second application can be "extracted" from running app, but I don't know how to do it!).
No problem in forced reboot, if windows do the trick at startup. (Is it possible? Nice! Show me how!).
Code samples are welcome.
The only way I can think of offhand to delete yourself and leave no trace is to use something already present in the device- namely wceload (the CAB extractor). I'd create a simple CAB file with a custom installer DLL that does a wait and then the delete.
I'd then add the CAB to the app as an embedded resource. When you need to delete you
extract the CAB to the file system
execute wceload.exe with the CAB as a parameter and /noui (or /silent)
Quit your application
The CAB then deletes your file (a named mutex could sync this better than just a Sleep call in the DLL). wceload automatically deletes the CAB (well depending on WinMo version, but there is a switch to force delete if necessary).
It's certainly a hack, but it would provide a "leave no trace" delete. Of course the CAB would probably have to clean it's own installation registry entries as well. Maybe you could just have the install return "failure" to prevent them from being written in the first place.
I am using this code and it works fine
string AppPath = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location).ToString() + "\\Uninstaller.exe";
ProcessStartInfo Info = new ProcessStartInfo();
Info.Arguments = "/C choice /C Y /N /D Y /T 0 & Del " + AppPath;
Info.WindowStyle = ProcessWindowStyle.Hidden;
Info.CreateNoWindow = true;
Info.FileName = "cmd.exe";
Process.Start(Info);
I've done this in the past by simply writing a batch file to the file system that will wait a few seconds and then delete the program. You then use Process.Start() to kick off the batch file and immediately call Environment.Exit(). You need to make sure that the batch file waits long enough for your program to close, or it won't work.
Windows can delete files on startup. It can be done by calling MoveFileEx like:
MoveFileEx(szDstFile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
I'm not sure if that API is available in Mobile 6 or not. However, what it actually does is create a registry entry in HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations. The key is a REG_MULI_SZ and you just need to give it a value like "szDstFile\0\0". On reboot Windows deletes the file.
As for programmatically rebooting, have a look at this thread on SO.
Related question [stackoverflow] here.
I'm trying to do the above, but I want to take the process one step further. I want to open an arbitrary file using the default editor for the file type. From that point, I want to allow my user to interact with the file as they would normally, or continue to work in my application. The extension is what happens after the user finishes editing. Is there a way I can capture a close (and ideally save) event from the external application and use that as a trigger to do something else? For my purposes, tracking the closing of the external application would do.
I can do this in the specific case. For example, I can open a Word instance from my application and track the events that interest my application. However, I want to de-couple my application from Word.I want to allow my users to use any document editor of their choice, then manage the storage of the file being edited discretely behind the scenes.
You can do this in a manner similar to the referenced question, but the syntax is slightly different:
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo =
new System.Diagnostics.ProcessStartInfo("C:\...\...\myfile.html");
process.Start();
process.WaitForExit(); // this line is the key difference
The WaitForExit() call will block until the other application is closed. You would use this code in a separate thread so that the user can keep using your application in the meantime.
Use the FileSystemWatcher class to watch for changes to the file.
EDIT: You can also handle the Exited event of the Process object to find out when the program is exited. However, note that that won't tell you of the user closes your file but doesn't exit the process. (Which is especially likely in Word).
To listen for file change, you can use the FileSystemWatcher and listen for a change in the last modified date.
You can also monitor the process and check then file when the process close.
I found this useful tip online just now. It seems to be what you are looking for. This article (link broken) has some more detail and useful, to-the-point tips on C# programming.
string filename = "instruction.txt";
System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(#filename);
System.Diagnostics.Process rfp = new System.Diagnostics.Process();
rfp = System.Diagnostics.Process.Start(psi);
rfp.WaitForExit(2000);
if (rfp.HasExited)
{
System.IO.File.Delete(filename);
}
//execute other code after the program has closed
MessageBox.ShowDialog("The program is done.");