I am running code on Windows Server 2012 R2 where i have multiple sessions.
On each session there is few Notepad.exe opened with different window name.
How i can get a list of all Notepad.exe processes from all sessions so i can minimize window or close process for selected process from a list ?
I used this code, but it gives me only processes from current session where i am logged in.
Process[] processlist = Process.GetProcesses();
foreach (Process process in processlist)
{
if (!string.IsNullOrEmpty(process.MainWindowTitle))
{
if (process.ProcessName == "notepad")
{
Console.WriteLine("Process: {0} - ID: {1} - Window title: {2}", process.ProcessName, process.Id, process.MainWindowTitle);
}
}
}
I solved my issue thanks to #Lex Li, used library from nuget.
I used this line if (process.ProcessName == "notepad.exe" && session.SessionId == process.SessionId) to extract only process name i need and match it to session.
using Cassia;
// call all process from sessions
private void GetSessionsProcess()
{
ITerminalServicesManager manager = new TerminalServicesManager();
ITerminalServer server = manager.GetLocalServer(); // server name
server.Open();
WriteProcesses(server.GetProcesses(), manager);
}
// get all process that is running in all sessions
private void WriteProcesses(IEnumerable<ITerminalServicesProcess> processes, ITerminalServicesManager manager)
{
ITerminalServer server = manager.GetLocalServer();
foreach (ITerminalServicesProcess process in processes)
{
foreach (ITerminalServicesSession session in server.GetSessions())
{
if (process.ProcessName == "notepad.exe" && session.SessionId == process.SessionId)
{
PopulateTerminalsList(process.SessionId.ToString(), process.ProcessId.ToString(), process.ProcessName, session.UserAccount.ToString(), session.UserName);
}
}
}
}
Related
From a C# service, how I can check whether another app is dead or not?
I tried to use Process.Responding, it returns true but the app is died.
This is the code:
private List<string> getListStringGAppPath()
{
List<string> listGAppPaths = new List<string>();
Process[] processes = Process.GetProcessesByName("MyApp");
if (processes.Length > 0)
{
for (int i = 0; i < processes.Length; i++) {
listGAppPaths.Add(processes[i].Responding.ToString() + "######" + processes[i].MainModule.FileName);
//processes[i].Responding.ToString() always return True
}
return listGAppPaths;
}
else
{
return null;
}
}
When process dies, windows seems to toggles its state to Suspended, you can try checking its state first. Also here: Detecting process crash in .NET
You can check if the process is responding:
foreach (var process in System.Diagnostics.Process.GetProcesses())
{
Console.WriteLine("Process Name: {0}, Responding: {1}", process.ProcessName, process.Responding);
}
Similar to this answer:
Check status of process
You can use the methods in System.Diagnostics.Process to get process information.
GetProcessesByName(String)
Creates an array of new Process components and associates them with all the process resources on the local computer that share the specified process name.
GetProcessById(Int32)
Returns a new Process component, given the identifier of a process on the local computer.
GetProcesses()
Creates a new Process component for each process resource on the local computer.
If the process does not exist, then it must have died?
I made a program that opens COM6. The program starts when the user logs on.
If another user logs on, while the first user is still logged in, the program crazes because the COM is already open.
I found this code, which I thought could solve the problem. The code was meant to close all other application with the same name, but apparently, it does not work, when the other app is running under another user. Have anybody got any solution for this ?
void CloseAllButMe()
{
Process[] processes;
Process self = Process.GetCurrentProcess();
processes = Process.GetProcessesByName(self.ProcessName);
foreach (Process p in processes)
{
if (self.Id != p.Id) p.CloseMainWindow();
}
}
You can use the methods Process.Kill to stop a process. Calling Kill will immediately stop the process and could cause a loss of work.
Here is a code sample for killing Calculator:
public static void KillPaint()
{
System.Diagnostics.Process[] procs = null;
try
{
procs = Process.GetProcessesByName("calc");
Process mspaintProc = procs[0];
if (!mspaintProc.HasExited)
{
mspaintProc.Kill();
}
}
finally
{
if (procs != null)
{
foreach (Process p in procs)
{
p.Dispose();
}
}
}
}
How can I get a list of long running services on my current machine?
I can list all processes but how can I add to filter long running ones?
private void ListProcesses()
{
Process[] processCollection = Process.GetProcesses();
foreach (Process p in processCollection)
{
Console.WriteLine(p.ProcessName);
}
}
The Process class has a datetime property Process.StartTime that gets the time that the associated process was started.
You could use it to figure out which ones that run for longer.
I can list all processes but how can I add to filter long running ones?
Something like (assuming you are asking for wall time):
foreach (var p in processCollection.Where(n => (DateTime.Now - p.StartTime) > someThresholdInterval))
{
//...long running
}
There are other properties you could also use like TotalProcessorTime which would give you the total amount of time that the process has actually been using the processor (versus sleeping) which might be more interesting in some cases.
If you actually want services, rather than processes, then there is a different method to get those. To get services use ServiceController.GetServices however, I don't think there's a way to get when they started.
for running services only, we must use ServiceController and ManagementObject . here is my code for "long" running services :
static public void Main()
{
TimeSpan Interval = new TimeSpan(5,0,10); // as exemple
var scServices= ServiceController.GetServices();
foreach (ServiceController scTemp in scServices)
{
if (scTemp.Status == ServiceControllerStatus.Running)
{
ManagementObject wmiService;
wmiService = new ManagementObject("Win32_Service.Name='" + scTemp.ServiceName + "'");
wmiService.Get();
var id = Convert.ToInt32(wmiService.Properties["ProcessId"].Value);
Process p = Process.GetProcessById(id);
if ((DateTime.Now.Subtract(p.StartTime)) > Interval)
{
Console.WriteLine(" Service : {0}", scTemp.ServiceName);
Console.WriteLine(" Display name: {0}", scTemp.DisplayName);
Console.WriteLine(" StartTime: {0}", p.StartTime);
}
}
}
Console.ReadLine();
}
I want to troll my brother a Little bit ;) by writing a program, which I can put in his "StartUp"-Folder. This program should scan his default system tasks so that it doesn't destroy his computer so I wrote all currently open processes in a list. Now I want to check when he opens a program (Process) is it in the list("Taskmgr" is also in the list, so you can exit the troll anytime)? If the opened Process is not in the list, kill it. If you Need any further information, please ask...
My current code is this:
void CloseProcesses()
{
Process[] arrProcesses = Process.GetProcesses();
List<string> lststrProcessNames = new List<string>();
/*Writes current running processes(+ taskmanager process) in a list*/
foreach (Process CurrentProcess in arrProcesses)
{
lststrProcessNames.Add(CurrentProcess.ProcessName);
}
lststrProcessNames.Add("taskmgr");
try
{
Process[] arrNewProcesses = Process.GetProcesses();
foreach (Process NewCurrentProcess in arrNewProcesses)
{
if (lststrProcessNames.Contains(NewCurrentProcess.ProcessName))
{
CloseProcesses();
}
else
{
NewCurrentProcess.Kill();
}
}
}
catch
{
this.Close();
}
}
I am using Selenium WebDriver in an application and I have code to kill the webdrivers and browser instances. However, I am thinking that if the user had any IE browsers open before running the application that this code will kill not only the IE processes spawned by my application but also the IE instances that user had open prior to running the application.
Is there a way to track the processes started by my application so I can filter this method to kill only IE processes spawned by my application, or determine that IE driver and browser instance was spawned by my application, or perhaps both?
public void KillAllBrowsersAndWebDrivers()
{
var webDrivers = Process.GetProcessesByName("IEDriverServer").Select(p => p.Id);
var browsers = Process.GetProcessesByName("iexplore").Select(p => p.Id);
var processIds = webDrivers.Concat(browsers);
// do some stuff with PID, if you want to kill them, do the following
foreach (var pid in processIds)
{
try
{
Process.GetProcessById(pid).Kill();
Logger.Log(Loglevel.Debug, "Kill Process:{0}", pid);
}
catch (Exception)
{
Logger.Log(Loglevel.Error, "Error killing process: {0}", pid);
}
}
}
All you would have to do is keep a list of all the processes you've created.
this is a very simple process manager. This code is error prone, and there is no exception handling
private static List<Process> processes = new List<Process>();
static void Main(string[] args)
{
int PID = StoreProcess (yourProcess);
KillProcess(PID);
}
/// <summary>
/// Stores the process in a list
/// </summary>
/// <returns>The PID</returns>
/// <param name="prc">The process to be stored</param>
public static int StoreProcess(Process prc)
{
int PID = prc.Id; // Get the process PID and store it in an int called PID
processes.Add (prc); // Add this to our list of processes to be kept track of
return PID; // Return the PID so that the process can be killed/changed at a later time
}
/// <summary>
/// Kills a process
/// </summary>
/// <param name="PID">The PID of the process to be killed.</param>
public static void KillProcess(int PID)
{
// Search through the countless processes we have and try and find our process
for (int i = 0; i <= processes.Count; i++) {
if (processes [i] == null)
{
continue; // This segment of code prevents NullPointerExceptions by checking if the process is null before doing anything with it
}
if (processes [i].Id == PID) { // Is this our process?
processes [i].Kill (); // It is! Lets kill it
while (!processes [i].HasExited) { } // Wait until the process exits
processes [i] = null; // Mark this process to be skipped the next time around
return;
}
}
// Couldn't find our process!!!
throw new Exception ("Process not found!");
}
Advantages:
You can keep track of all the processes you've initialized, and terminate them one by one at any time
Drawbacks:
I don't believe there is any
Another possible solution is to get a list of the processes running BEFORE spawning any new processes. Then just kill the ones that are not in the list of previously running processes.
public void KillOnlyProcessesSpawnedBySelenium()
{
// get a list of the internet explorer processes running before spawning new processes
var pidsBefore = Process.GetProcessesByName("iexplore").Select(p => p.Id).ToList();
var driver = new Driver(Settings);
var driver1 = driver.InitiateDriver(); // this method creates new InternetExplorerDriver
var driver2 = driver.InitiateDriver();
var driver3 = driver.InitiateDriver();
driver1.Navigate().GoToUrl("http://google.com");
driver2.Navigate().GoToUrl("http://yahoo.com");
driver3.Navigate().GoToUrl("http://bing.com");
var pidsAfter = Process.GetProcessesByName("iexplore").Select(p => p.Id);
var newInternetExplorerPids = pidsAfter.Except(pidsBefore);
// do some stuff with PID, if you want to kill them, do the following
foreach (var pid in newInternetExplorerPids)
{
Debug.WriteLine("Killing pid: {0}", pid);
Process.GetProcessById(pid).Kill();
}
Assert.IsTrue(pidsBefore.Count > 0);
// determine if each process before the drivers spawned are running
foreach (var running in pidsBefore.Select(pid => Process.GetProcessById(pid).IsRunning()))
{
Assert.IsTrue(running);
}
}
Here is an extension method to use to determine if a process is still running or not...
public static bool IsRunning(this Process process)
{
if (process == null)
throw new ArgumentNullException("process");
try
{
Process.GetProcessById(process.Id);
}
catch (ArgumentException)
{
return false;
}
return true;
}