Find if particular thread is associated with windows process - c#

I have a java application which on execution runs different thread. I want to see if particular thread (By thread name) is running or not. I can check this manually using JConsole. It shows me whether that thread is running in associated process or not. By inspiring from that.
I am creating a C# program to get threads associated with particular process. I need to get name of threads in particular. I have tried toString method but it does not shows thread name.
Below is the code:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
try
{
Process localById = Process.GetProcessById(6440);
ProcessThreadCollection coll = localById.Threads;
foreach (ProcessThread t in coll)
{
Console.WriteLine(t.toString());
}
}
catch (Exception e) { }
}
}
Output is :
System.Diagnostics.ProcessThread
System.Diagnostics.ProcessThread
System.Diagnostics.ProcessThread
Can anyone help me with this? Need to get name of all threads running in process by process ID.

Related

Why doesn't my CriticalFinalizerObject get finalized when a new app domain spins up?

I have an .NET MVC site which spins up child processes for doing background work. I'd like to ensure that those processes are shut down when IIS spins up a new app domain (e. g. on deployment or any change to Web.config).
For this purpose, I've created a CriticalFinalizerObject as follows:
public class ProcessHandle : CriticalFinalizerObject, IDisposable
{
private readonly int _processId;
private int _disposed;
public ProcessHandle(int processId)
{
this._processId = processId;
}
// dispose is called if we shut down the process normally, so
// we don't need to kill it here
public void Dispose()
{
if (Interlocked.Exchange(ref this._disposed, 1) == 0)
{
GC.SuppressFinalize(this);
}
}
~ProcessHandle()
{
if (Interlocked.Exchange(ref this._disposed, 1) == 0)
{
try
{
using (var process = Process.GetProcessById(this._processId))
{
process.Kill();
}
}
catch
{
}
}
}
}
Whenever I create a process, I store a ProcessHandle alongside. The hope is that when a new app domain spins up, IIS will unload the old app domain (after some timeout). This will run the finalizers for my handles, which will kill any processes.
However, I'm observing that changing Web.config does not seem to reliably cause the finalizers to run. What am I doing wrong? Is there another way to achieve this?
Note: I'd love to have the child process watch for the parent process, but I don't control the child process code. I could create a wrapper process for this purpose, but I was hoping not to need that extra layer of complexity.

How to make my app singleton application? [duplicate]

This question already has answers here:
What is the correct way to create a single-instance WPF application?
(39 answers)
Closed 6 years ago.
I have a application but currently it is not a singleton application.
I like to make it singleton application so that its another instance does not exit at the run time .
If this can be done please reply with some sample codes .
I think the following codes will be helpful for you.
Here is the related link:
http://geekswithblogs.net/chrisfalter/archive/2008/06/06/how-to-create-a-windows-form-singleton.aspx
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
/*====================================================
*
* Add codes here to set the Winform as Singleton
*
* ==================================================*/
bool mutexIsAvailable = false;
Mutex mutex = null;
try
{
mutex = new Mutex(true, "SampleOfSingletonWinForm.Singleton");
mutexIsAvailable = mutex.WaitOne(1, false); // Wait only 1 ms
}
catch (AbandonedMutexException)
{
// don't worry about the abandonment;
// the mutex only guards app instantiation
mutexIsAvailable = true;
}
if (mutexIsAvailable)
{
try
{
Application.Run(new SampleOfSingletonWinForm());
}
finally
{
mutex.ReleaseMutex();
}
}
//Application.Run(new SampleOfSingletonWinForm());
}
}
Here are some good sample applications. Below is one possible way.
public static Process RunningInstance()
{
Process current = Process.GetCurrentProcess();
Process[] processes = Process.GetProcessesByName (current.ProcessName);
//Loop through the running processes in with the same name
foreach (Process process in processes)
{
//Ignore the current process
if (process.Id != current.Id)
{
//Make sure that the process is running from the exe file.
if (Assembly.GetExecutingAssembly().Location.
Replace("/", "\\") == current.MainModule.FileName)
{
//Return the other process instance.
return process;
}
}
}
//No other instance was found, return null.
return null;
}
if (MainForm.RunningInstance() != null)
{
MessageBox.Show("Duplicate Instance");
//TODO:
//Your application logic for duplicate
//instances would go here.
}
Many other possible ways. See the examples for alternatives.
First one.
Second One.
Third One.
The approach I know of is the following. The program must attempt to open a named mutex. If that mutex existed, then exit, otherwise, create the mutex. But this seems to contradict your condition that "its another instance does not exit at the run time". Anyway, maybe this too was helpful

Execute a method in an Application in an AppPool, using DirectoryEntry and Reflection?

Good Day
I am running a small web garden with StateSession cache. The obvious problem is that when you want to clear the cache, the cache is only cleared on the workerprocess that is handling the call.
In a specific AppPool there will be at least one User Interface Application and one Web Service Application. The Web Services do the majority of the caching, so they have methods to clear their cache.
What I would like to do is create a method that will get input (the AppPool Name) and then it will iterate through the current w3wp processes and get the required pools back. That can be done and I have methods of getting that information.
Where I am getting stuck is I have the AppPool Name as well as the Applications that are running in that Worker Process, but I am lost as to how to use that information to execute the "ClearCache()" method in a specific Web Service application.
I am sure that it can be done with Reflection, but I think I am missing something obvious.
Currently I am just using a console application to get something that works. This can then be moved to a better solution in due time.
Please advise if there is a way to use to current information to execute the required method.
Below is the test application as it stands at the moment.
Thank you.
Jaco
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Management;
using System.DirectoryServices;
using System.Collections;
namespace CacheCleaner
{
class Program
{
const string defaultAppPoolMetabasePath = "IIS://localhost/W3SVC/AppPools/DefaultAppPool";
static void Main(string[] args)
{
//show a list of all the processes.
//GetListOfProcesses();
//Kill all the worker processes
//KillW3WP();
//Refresh the application pool
//RefreshAppPool(defaultAppPoolMetabasePath);
//get a list of all the Applications in the DefaultAppPool
//GetApplicationPoolInformation(defaultAppPoolMetabasePath);
//get the apps in the apppool
EnumerateApplicationsInPool(defaultAppPoolMetabasePath);
Console.WriteLine("\n\nEnd of process. Press Enter.");
Console.ReadLine();
}
/// <summary>
/// Show all the processes that are currently running on the system
/// </summary>
static void GetListOfProcesses()
{
foreach (Process p in Process.GetProcesses())
{
Console.WriteLine("{0} {1}", p.Id, p.ProcessName);
}
}
/// <summary>
/// This will kill ALL the worker processes.
/// Pretty much an iisreset call.
/// Not good for Production sites :)
/// </summary>
static void KillW3WP()
{
foreach (Process p in Process.GetProcessesByName("w3wp"))
{
Console.WriteLine("Closing " + p.ProcessName);
p.Kill();
p.WaitForExit();
if (p.HasExited)
{
Console.WriteLine("Closed");
}
else
{
Console.WriteLine("NOT Terminated");
}
}
}
/// <summary>
/// Refresh a specific application pool
/// </summary>
/// <param name="metabasePath"></param>
static void RefreshAppPool(string metabasePath)
{
using (DirectoryEntry applicationPool = new DirectoryEntry(metabasePath))
{
applicationPool.Invoke("Recycle");
}
}
/// <summary>
/// Get the Name of the worker process (AppPool Name)
/// </summary>
/// <param name="metabasePath"></param>
static void GetApplicationPoolInformation(string metabasePath)
{
var scope = new ManagementScope(String.Format(#"\\{0}\root\cimv2", Environment.MachineName));
var query = new SelectQuery("SELECT * FROM Win32_Process where Name = 'w3wp.exe'");
using (var searcher = new ManagementObjectSearcher(scope, query))
{
foreach (ManagementObject process in searcher.Get())
{
//get just the name of the application
var startIndex = process["CommandLine"].ToString().IndexOf("-ap ") + 5; //remove the -ap as well as the space and the "
var endIndex = process["CommandLine"].ToString().IndexOf("-", startIndex) - 2; //remove the closing "
var appPoolName = process["CommandLine"].ToString().Substring(startIndex, endIndex - startIndex);
var pid = process["ProcessId"].ToString();
Console.WriteLine("{0} - {1}", pid, appPoolName);
}
}
}
/// <summary>
/// Get the applications in the pool
/// From http://msdn.microsoft.com/en-us/library/ms524452%28v=vs.90%29.aspx
/// </summary>
/// <param name="metabasePath"></param>
static void EnumerateApplicationsInPool(string metabasePath)
{
Console.WriteLine("\nEnumerating applications for the {0} pool:", metabasePath);
try
{
DirectoryEntry entry = new DirectoryEntry(metabasePath);
if (entry.SchemaClassName == "IIsApplicationPool")
{
object[] param;
param = (object[])entry.Invoke("EnumAppsInPool", null);
foreach (string s in param)
{
Console.WriteLine("{0}", s);
//I am sure that I should be able to use this application name
//with Reflection to be able to execute a method...
}
Console.WriteLine("Done.");
}
else
Console.WriteLine("Failed in EnumerateApplicationsInPool; {0} is not an app pool", metabasePath);
}
catch (Exception ex)
{
Console.WriteLine("Failed in EnumerateApplicationsInPool with the following exception: \n{0}", ex);
}
}
}
}
There's a few ways to approach this, some bad, some good.
Bounce each worker process. This is pretty effective and will force a cache reload but will result in a very poor experience for end users because existing requests will be stopped in their tracks (if you're updating a database without any transaction protection then you could see your data go inconsistent). You'll also see a loss of session state if you're using InProc state management.
Recycle each pool - better than bouncing the pool because existing requests will still be permitted to complete. However you'll still see a loss of session state if you're using InProc state management.
Use a Cache Dependency - many caches are populated from a SQL Database. ASP.NET supports a feature called SqlCacheDependency. You can use this to refresh your cached data should the source data in the database change.
Use a file-based Cache Dependency - if your cache data is sourced from (for example) an XML data file then you can cache that data and create a cache dependency on this file. When the file is updated the cache is invalidated and you reload the data. You could automate this with a FileSystemWatcher because the CacheDependency class itself doesn't provide any change notification events and you'd need to check CacheDependency.HasChanged on every request.
With regard to calling ClearCache() directly on the cache object in each worker process, there is no direct way to do that using reflection. You might be able to do this using the .NET Debugging API's and inject some code to clear the cache but you're talking about walking up to a process, attaching to it and pretending to be a debugger. I wouldn't really fancy writing that myself when there are other mechanisms such as Cache Dependencies available.

Running windows service to watch service running grow memory (leak)

I have checked all posts here, but can't find a solution for me so far.
I did setup a small service that should only watch if my other services I want to monitor runs, and if not, start it again and place a message in the application eventlog.
The service itself works great, well nothing special :), but when I start the service it use around 1.6MB of RAM, and every 10 seconds it grow like 60-70k which is way to much to live with it.
I tried dispose and clear all resources. Tried work with the System.Timers instead of the actual solution, but nothing really works as I want it, memory still grows.
No difference in debug or release version and I am using it on .Net 2, don't know if it make a difference to you 3,3.5 or 4.
Any hint?!
using System;
using System.IO;
using System.Diagnostics;
using System.ServiceProcess;
using System.Threading;
using System.Timers;
namespace Watchguard
{
class WindowsService : ServiceBase
{
Thread mWorker;
AutoResetEvent mStop = new AutoResetEvent(false);
/// <summary>
/// Public Constructor for WindowsService.
/// - Put all of your Initialization code here.
/// </summary>
public WindowsService()
{
this.ServiceName = "Informer Watchguard";
this.EventLog.Source = "Informer Watchguard";
this.EventLog.Log = "Application";
// These Flags set whether or not to handle that specific
// type of event. Set to true if you need it, false otherwise.
this.CanHandlePowerEvent = false;
this.CanHandleSessionChangeEvent = false;
this.CanPauseAndContinue = false;
this.CanShutdown = false;
this.CanStop = true;
if (!EventLog.SourceExists("Informer Watchguard"))
EventLog.CreateEventSource("Informer Watchguard", "Application");
}
/// <summary>
/// The Main Thread: This is where your Service is Run.
/// </summary>
static void Main()
{
ServiceBase.Run(new WindowsService());
}
/// <summary>
/// Dispose of objects that need it here.
/// </summary>
/// <param name="disposing">Whether or not disposing is going on.</param>
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
}
/// <summary>
/// OnStart: Put startup code here
/// - Start threads, get inital data, etc.
/// </summary>
/// <param name="args"></param>
protected override void OnStart(string[] args)
{
base.OnStart(args);
MyLogEvent("Init");
mWorker = new Thread(WatchServices);
mWorker.Start();
}
/// <summary>
/// OnStop: Put your stop code here
/// - Stop threads, set final data, etc.
/// </summary>
protected override void OnStop()
{
mStop.Set();
mWorker.Join();
base.OnStop();
}
/// <summary>
/// OnSessionChange(): To handle a change event from a Terminal Server session.
/// Useful if you need to determine when a user logs in remotely or logs off,
/// or when someone logs into the console.
/// </summary>
/// <param name="changeDescription"></param>
protected override void OnSessionChange(SessionChangeDescription changeDescription)
{
base.OnSessionChange(changeDescription);
}
private void WatchServices()
{
string scName = "";
ServiceController[] scServices;
scServices = ServiceController.GetServices();
for (; ; )
{
// Run this code once every 10 seconds or stop right away if the service is stopped
if (mStop.WaitOne(10000)) return;
// Do work...
foreach (ServiceController scTemp in scServices)
{
scName = scTemp.ServiceName.ToString().ToLower();
if (scName == "InformerWatchguard") scName = ""; // don't do it for yourself
if (scName.Length > 8) scName = scName.Substring(0, 8);
if (scName == "informer")
{
ServiceController sc = new ServiceController(scTemp.ServiceName.ToString());
if (sc.Status == ServiceControllerStatus.Stopped)
{
sc.Start();
MyLogEvent("Found service " + scTemp.ServiceName.ToString() + " which has status: " + sc.Status + "\nRestarting Service...");
}
sc.Dispose();
sc = null;
}
}
}
}
private static void MyLogEvent(String Message)
{
// Create an eEventLog instance and assign its source.
EventLog myLog = new EventLog();
myLog.Source = "Informer Watchguard";
// Write an informational entry to the event log.
myLog.WriteEntry(Message);
}
}
}
Your code may throw an exceptions inside loop, but these exception are not catched. So, change the code as follows to catch exceptions:
if (scName == "informer")
{
try {
using(ServiceController sc = new ServiceController(scTemp.ServiceName.ToString())) {
if (sc.Status == ServiceControllerStatus.Stopped)
{
sc.Start();
MyLogEvent("Found service " + scTemp.ServiceName.ToString() + " which has status: " + sc.Status + "\nRestarting Service...");
}
}
} catch {
// Write debug log here
}
}
You can remove outer try/catch after investigating, leaving using statement to make sure Dispose called even if exception thrown inside.
At a minimum, you need to do this in your logging code since EventLog needs to be Dispose()d. Seems like this resource could be reused rather than new-ed on every call. You could also consider using in your main loop for the ServiceController objects, to make your code more exception-safe.
private static void MyLogEvent(String Message)
{
// Create an eEventLog instance and assign its source.
using (EventLog myLog = new EventLog())
{
myLog.Source = "Informer Watchguard";
// Write an informational entry to the event log.
myLog.WriteEntry(Message);
}
}
This should be moved into the loop, since you don't want to keep a reference to old service handles for the life of your service:
ServiceController[] scServices = ServiceController.GetServices();
You also want to dispose of your reference to EventLog and to the ServiceController instances. As Artem points out, watch out for exceptions that are preventing you from doing this.
Since memory is going up every 10 seconds, it has to be something in your loop.
If memory goes up whether or not you write to the EventLog, then that is not the main problem.
Does memory used ever come down? Ie does the garbage collector kick in after awhile? You could test the GC's effect by doing a GC.Collect() before going back to sleep (though I'd be careful of using it in production).
I am not sure I understand the problem exactly. Is the service you are going to be monitoring always the same. It would appear from your code that the answer is yes, and if that is the case then you can simply create the ServiceController class instance passing the name of the service to the constructor.
In your thread routine you want to continue looping until a stop is issued, and the WaitOne method call returns a Boolean, so a while loop seems to be appropriate. Within the while loop you can call the Refresh method on the ServiceController class instance to get the current state of the service.
The event logging should simple require a call one of the static method EventLog.WriteEntry methods, at minimum passing your message and the source 'Informer Watchguard'
The ServiceController instance can be disposed when you exit from the loop in the thread routine
All this would mean you are creating fewer objects that need to be disposed, and therefore less likely that some resource leak will exist.
Thanks to all suggestions.
Finally the service is stable now with some modifications.
#Steve: I watch many services all beginning with the same name "Informer ..." but I don't know exactly full names, that's why I go this way.

How can I check for a running process per user session?

I have a .NET application that I only allow to run a single process at a time of, however that app is used on Citrix boxes from time to time, and as such, can be run by multiple users on the same machine.
I want to check and make sure that the application is only running once per user session, because right now if user A is running the app, then user B gets the "App already in use" message, and should not.
This is what I have now that checks for the running process:
Process[] p = Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName);
if (p.Length > 1)
{
#if !DEBUG
allowedToOpen &= false;
errorMessage +=
string.Format("{0} is already running.{1}", Constants.AssemblyTitle, Environment.NewLine);
#endif
}
EDIT: Improved the answer according to this cw question ...
You can use a mutex for checking wether the app already runs:
using( var mutex = new Mutex( false, AppGuid ) )
{
try
{
try
{
if( !mutex.WaitOne( 0, false ) )
{
MessageBox.Show( "Another instance is already running." );
return;
}
}
catch( AbandonedMutexException )
{
// Log the fact the mutex was abandoned in another process,
// it will still get aquired
}
Application.Run(new Form1());
}
finally
{
mutex.ReleaseMutex();
}
}
Important is the AppGuid - you could make it depend on the user.
Maybe you like to read this article: the misunderstood mutex
As tanascius already say, you can use the Mutex.
On a server that is running Terminal Services, a named system mutex can have two levels of visibility. If its name begins with the prefix "Global\", the mutex is visible in all terminal server sessions. If its name begins with the prefix "Local\", the mutex is visible only in the terminal server session where it was created.
Source: msdn, Mutex Class
Just stating the obvious - although Mutex is usually considered better solution, you can still solve the single-instance-per-session issue without Mutex - just test the SessionId as well.
private static bool ApplicationIsAlreadyRunning()
{
var currentProcess = Process.GetCurrentProcess();
var processes = Process.GetProcessesByName(currentProcess.ProcessName);
// test if there's another process running in current session.
var intTotalRunningInCurrentSession = processes.Count(prc => prc.SessionId == currentProcess.SessionId);
return intTotalRunningInCurrentSession > 1;
}
Source (no Linq)
If Form1 launches non-background threads, and that Form1 exits, you've got a problem: the mutex is released but the process is still there. Something along the lines below is better IMHO:
static class Program {
private static Mutex mutex;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main() {
bool createdNew = true;
mutex = new Mutex(true, #"Global\Test", out createdNew);
if (createdNew) {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
else {
MessageBox.Show(
"Application is already running",
"Error",
MessageBoxButtons.OK,
MessageBoxIcon.Error
);
}
}
}
The mutex won't be released as long as the primary application domain is still up. And that will be around as long as the application is running.

Categories