I am trying to create an app that will perform actions on specific times (much like the Windows Task Scheduler). I am currently using Process.Start() to launch the file (or exe) required by the task.
I am initiating a process by calling a file (an .mp3) and the process starts WMP (since it is the default application). So far so good. Now I want to kill that process. I know that it is normal behavior for the Process.Start(string, string) to return nothing (null in C#) in this case.
So I am asking how can I close WMP when I called it through Process.Start(string, string)??
Edit:
Please note that I am not opening WMP directly with Process.Start() and this is the line with which I run the process:
VB: Me._procs.Add(Process.Start(Me._procInfo))
C#: this._procs.Add(Process.Start(this._procInfo))
_procInfo is a ProcessStartInfo instance. _procInfo.FileName is "C:\route\myFile.mp3". That is why WMP opens. In any case, all of the Start() methods, except for the instance-one which returns a boolean, return nothing (null in C#), because WMP is not the process that was directly created (please note that WMP is run and the song does play).
Process.Start(string,string) returns you a Process resource that you can use to further control the new process.
Process newProcess = Process.Start("param1", "param2");
if (newProcess != null && !newProcess.HasExited)
newProcess.Kill();
The same structure works if you use Process.Start(string), or any other static Process.Start overload.
Process.Start() is a member function and associates a new or reused Process with the Process component identified by this. Behaviour of this method depends on the properties of the Process identified by this.
Don't do it this way.
It's not clear whether the intent of your program is 'Always launch with Windows Media Player' or 'Launch with the registered MP3 player', which might be, say, iTunes.
If you need WMP, use Process.Start with the full path to windows media player.
If you need the registed MP3 player, you can find out the correct exe using the code shown here. Again, start the process with this exe path, passing the MP3 as a parameter.
Two ways:
1-
Process customProc = Process.Start("ExecutablePath", "Argument(s)");
customProc.Kill()
2-
Dim pProcess() As Process = System.Diagnostics.Process.GetProcessesByName("ProcessName")
For Each p As Process In pProcess
p.Kill()
Next
If you are letting the registered windows program to open the file, rather than picking the program you want. Then I advise you do not kill the process.
The reason for this is what say your program does use the default application, but that application is already in use, and contains unsaved data. A user would not be happy for your program to overtake there application with the new file and then kill off the process that was already in use by the user for another purpose. Sure, it might not be in use but you must consider the worst case.
As such, I recommend what has been suggested. use Process.Start() with the full path to the program to be used and the file to be opened.
I tried to open .txt file and the process of my text editor was returned, also I tried .mp3 by WMP and it returned null. So it depends on the application. Do you need to run you mp3 only with WMP? If not, you definitely can create the application which will return the Process object.
proc = Process.Start(filename) should work, but like you say, it returns null instead of a process.
That seems to be inherent to Windows Media Player. Other applications return the process. You can get Windows Media Player's process by specifying the application in the start method.
proc = Process.Start("C:\Program Files\Windows Media Player\wmplayer.exe", filename)
Then you can kill it normally.
proc.Kill()
You will probably need to get the location of the application assiciated with .mp3 files from the registry.
Related
Based on this https://msdn.microsoft.com/en-us/library/53ezey2s(v=vs.110).aspx
Process.Start() is not useful.
Start may return a non-null Process with its HasExited property
already set to true. In this case, the started process may have
activated an existing instance of itself and then exited.
In my case, I want to launch a default editor for a xml in new instance so that i can use Process.HasExited property to take action on my WPF app. All i see is native samples or way complicated than thought. What is the best solution ?
Process process = Process.Start(MyFileXMlPath);
//Wait for the Editor to be closed.
if (process != null)
while (!process.HasExited) ;
This is what i have now. So that i uses the user's preferred editor.
What's going on is expected behavior- the editor is being asked to open a file, and it is opening that file in an existing running process. One solution might be to use Process.GetProcesses to get all of the running processes on the box and iterate over them to find the new one, but that's likely problematic, because there is really no good way to tell which one opened the file.
What you probably want to do is to set UseShellExecute to false, run the editor you want explicitly (e.g. #"c:\Windows\notepad.exe") and pass the file name as a parameter, which is usually the convention to open a file. Obviously you'd want to pick an editor that doesn't invoke an existing instance.
If I connect to a running process by extracting it using Process.GetProcessesByName("Notepad");, is it possible to reconstruct that processĀ“s ProcessStartInfo?
I would for example want to be able to attach to Notepad, Kill it and Start it again. Without a valid ProcessStartInfo the Start call will fail.
There is no direct support for this.
You can go over each property of the running process and initialize a ProcessStartInfo object with the corresponding values.
No, there are cases where that's not possible. A simple example is:
Process.Start("example.lnk");
No way to find out later that a .lnk file was used to get the process started.
The WorkingDirectory is a tricky one, a process often requires it to be set correctly but might change it later. A process that got started with a different user account is insurmountable, no way you can provide the correct account password. A custom environment is yet another one.
If I try to open an image file, or video, or website by calling Process.Start(filepath) directly, then it will typically succeed. However, the return value of Process.Start will sometimes be null. (As discussed here)
I need to know the associated process's id so that I can retrieve it later and close it if necessary. (Use case: User opens an image file using my program, and would like to close it using my program) However, it's kind of hard to retrieve the process id of a process that returns null :P
Any suggestions on how I should go about this, other than maybe specifying directly which program to use for each type of file we may encounter?
You have to specify directly which program to use to get the id of the process. I can imagine you can ask the os what program to use for each extensions as the os has a list of those.
I want to restart some process. Lets call it someApp.exe.
How can I restart that process? It's not my application. It's some external program.
What you want to do is:
Kill the process
Start it again
There are some ways of obtaining a Process instance in C#. Let's suppose you know the name of the process:
var process = Process.GetProcessesByName("notepad++")[0];
Then you can do:
process.Kill();
But to start it again, you need to know the path of the process, so before killing it, save the path of the executable:
var path = process.MainModule.FileName;
And then you can do:
Process.Start(path);
You should check if GetProcessesByName returns elements before taking the first element, but I just wanted to focus on the important thing here.
You can use the Process.Start.
http://msdn.microsoft.com/en-us/library/53ezey2s.aspx#Y1400
I'm creating a (C#) program that downloads binaries using NZB files, there may only be one instance of my application running at any time.
So when a user doubleclicks an .nzb-file and my program is not running, it should start and process it (easy, file registration).
Now if my program is already running, I do NOT want to launch a second instance - I want the already-running instance to pick up the specified file.
Making my app single-instance can be done using the Visual Basic DLL with the .IsSingleInstance trick, but I don't want to go there.
The right way seems to be to use a mutex to ensure my app is single-instance,
but now I'm stuck on how to pass the specified parameter (the .nzb file) to the already-running instance.
Help would be appreciated ! :-)
Try this: Your main program creates a named pipe or other interprocess communication facility and listens on it. You create a separate small program that, when run with an NZB file as a parameter, opens the pipe, feeds the file info into it, and exits. Your main program then processes the new file and downloads it.
Why not have one program that adds the file to a queue, and then kicks off the downloading program if it is not already running. That downloading program watches the queue, which is just a file that you append download file names to.
Look at the InitialInstanceActivator at the Genghis project
Use an IPC (inter process communication) mechanism such as .net remoting