I am developing a C# program that is run from a server and monitors processes on another set of servers. The processes I am monitoring all have the same exe name, but different windows title names. I am looking for a way to pull the windows title names from these processes remotely.
Basically what i would like to do is the following;
Process[] processList = Process.GetProcesses("ServerName");
foreach (Process p in processList)
{
try
{
Console.WriteLine(p.MainWindowTitle);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
However this is not supported by .NET
Does anyone know of another way?
I won't tell you this is the best approach, but it's possible to use it. You could create a simple service (windows service) and install it on each server. You might want to implement auto update functionality and therefore after installation you don't have to reinstall this service app on every machine. And this service app gets processes and associated windows titles (it may be more than one window within single process) and returns it to the machine that queries that information. I think you could use WCF here. And other advantage is that you can add more other functionality more easier.
Related
when I run the following code, I expect to get the name of all processes running in the system, but in some other PCs than mine, there is a running process that is visible in the TaskManager but my app doesn't show it, I wanna know if I'm doing something wrong or there is any way to solve this, BTW my app is running as Administrator so that's not the problem. Thanks for your help.
foreach(Process Proc in Process.GetProcesses()) {
T += Proc.ProcessName + ", ";
}
Multiple OS services can be loaded within the same instance of the Service Host process (svchost.exe). GetProcesses does not identify those individual services; for that, use GetServices. Be sure to read the official docs.
Process.GetProcesses() does not return system processes. Services may also appear as svhost.exe.
I'm developing a very simple 3rd party anti-cheat app in C#. I've managed to create a code that will scan any .exe for forbidden strings like "aimbot" and "hack". But the way I did it is, you browse for a file to scan and click a button to scan it - and this works great. What I want now is that my tool will check the running user processes and scan them automatically. Is that even doable?
If you already know the process names you want to go for, you can go with this.
Process[] processMame = Process.GetProcessesByName("yourProcess");
if (processMame.Length > 0)
{
/// You got your process here
/// Do whatever you want
}
Process[] processlist = Process.GetProcesses();
foreach (Process process in processlist)
{
Console.WriteLine($"Process: {process.ProcessName} ID: {process.Id} Path: {process.MainModule.FileName}");
}
You might want to make sure your app runs on administrator mode to do so. If you want the executable path you'd find it here on process.MainModule.FileName
Update:
I tried out opening a running executable and I was right on the fact that I would end up in an access violation even if Im administrator as that file is being used by other process now.
My suggestion would be if you want to check out an existing process, kill/dispose it, open it and do whatever you're supposed to do and if you feel this is not harmless, you restore it back.
You might need to make sure that your app has administrator privileges through manifest defined here.
For going for processes in current session:
If you want to have the processes in current active session (current active user who is logged in), you might want to go for something like:
Process[] runningProcesses = Process.GetProcesses();
var sessionId = Process.GetCurrentProcess().SessionId;
var currentSessionProcesses = runningProcesses.Where(c => c.SessionId == sessionId).ToList();
foreach (var process in currentSessionProcesses)
{
Console.WriteLine($"Process: {process.ProcessName} ID: {process.Id} Path: {process.MainModule.FileName}");
}
I am writing a windows service that occasionaly has to renew IP address of the system and It would call ipconfig /renew to do it.
The code is going to look like this
Process ipconfigProcess = new Process();
ipconfigProcess.StartInfo.FileName = "ipconfig";
ipconfigProcess.StartInfo.Arguments = " /renew";
ipconfigProcess.StartInfo.UseShellExecute = false;
ipconfigProcess.StartInfo.RedirectStandardOutput = true;
ipconfigProcess.Start();
strOutput = compiler.StandardOutput.ReadToEnd();
ipconfigProcess.WaitForExit();
I suppose a windows service is not allowed to show windows/dialogs. So my question is whether renewing ip as above would be a problem in windows service because it may or may not show a console to run ipconfig ?
I think the only issue you're going to face is that of permissions - you should have no problem running a process like this (as long as you don't want to interact with any kind of UI), but your windows service needs to run as an account that will be able to spawn a process and execute ipconfig.
This does not require an instance of cmd.exe. Many command line applications are used in this manner.
A service can use GUI functions and/or create a console. Windows creates a dummy display surface to draw on as necessary. (Obviously, this dummy surface can't interact with the user.)
I am developing a C# windows service + UI application.
I have a problem that if during the uninstall process the user is trying to launch the UI then the uninstall gets corrupted and stuck (because the ui holds handles to some files and prevents them from getting deleted).
What is the best way to handle this situation? I thought that maybe I should strict the access to the .exe when I am starting the uninstall process, so the user won't be able to launch it.
But I was wondering if there is a BKM of how to do that
EDIT
The application is already installed on customers' machines, So I can't make any changes to the application itself.
I have an upgrade installer that can do stuff as part of the uninstallation process. The upgrade installer first uninstall the application and then reinstall it. I can add code only to the upgrade installer so I can't use a mutex for example.
Thanks!
You can use named mutex, it is windows core object and two processes can check if it is already registered or not.
While uninstalling just create a named mutex, and check if it exists on process start
Here is how to create named mutex
Here is how to check if it exists
How about killing the process in the Uninstall?
public static bool KillProcess(string yourProcessName)
{
foreach (Process clsProcess in Process.GetProcesses())
{
if (Process.GetCurrentProcess().Id == clsProcess.Id)
continue;
if (clsProcess.ProcessName.Contains(name))
{
clsProcess.Kill();
return true;
}
}
return false;
}
I have this code:
[PermissionSet(SecurityAction.Assert, Name = "FullTrust")]
public List<WinInfo> GetWindows()
{
try
{
var isFullTrust = Assembly.GetExecutingAssembly().IsFullyTrusted;
if (isFullTrust)
{
return Process.GetProcesses().Where(z => !string.IsNullOrEmpty(z.MainWindowTitle))
.Select(z => new WinInfo
{
ProcessID = z.Id,
ProcessName = z.ProcessName,
WinID = z.MainWindowHandle,
WindowTitle = z.MainWindowTitle
}).ToList();
}
else
return null;
}
catch (Exception ex)
{
Trace.Write(ex.Message);
return null;
}
}
When I test in on my local computer under my current user (with admin rights) it works ok, displaying all the processes, that have windows. But when I call this code from a windows service, run under "Local Service" account, then the list is empty. I attached to the process, and through debug I found that "Process.GetProcesses()" returns all the processes, but all of them have MainWindowHandle as 0 and MainWindowTitle as empty, even when they do have windows. So what is wrong with my code?
Edit I edited code, so that it checks the assembly for full trust and have PemmissionSet that should grant the code the neccessary rights. Still the result is the same. When I debug, I can see, that "isFullTrust" is "True" and code executes with no exceptions. Still the list is empty, because none of the processes contains not-empty MainWindowTitle
According to this thread :
The problem you're seeing is because by default service don't have access to any interactive desktops. I don't recommend interacting with the desktop from a service (#1, there may not be any desktop, #2 there may be multiple desktops, #3 interacting with the desktop from service in Vista is not implemented) but, you can check the "Interace with desktop" in your services properties.
maybe you can try to create an hidden form?
Surely you need to run that under the user account! Why would applications with open windows be running under the local system account? That's for windows services etc
It could also be related to your process requiring full trust
From MSDN: The Process class has a LinkDemand and an
InheritenceDemand for FullTrust on it. This means that if your
assembly is not fully trusted, it will be unable to kick off new
Processes or get information about running processes
Maybe this is a question of priviliges.
According to this link LocalService has minimum privileges on the local computer.
you should use Local system Account