How do I retrieve the starting time of a process using c# code? I'd also like to know how to do it with the functionality built into Widows, if possible.
public DateTime GetProcessStartTime(string processName)
{
Process[] p = Process.GetProcessesByName(processName);
if (p.Length <= 0) throw new Exception("Process not found!");
return p[0].StartTime;
}
If you know the ID of the process, you can use Process.GetProcessById(int processId). Additionaly if the process is on a different machine on the network, for both GetProcessesByName() and GetProcessById() you can specify the machine name as the second paramter.
To get the process name, make sure the app is running. Then go to task manager on the Applications tab, right click on your app and select Go to process. In the processes tab you'll see your process name highlighted. Use the name before .exe in the c# code. For e.g. a windows forms app will be listed as "myform.vshost.exe". In the code you should say
Process.GetProcessesByName("myform.vshost");
Process has a property "StartTime":
http://msdn.microsoft.com/en-us/library/system.diagnostics.process.starttime.aspx
Do you want the start time of the "current" process? Process.GetCurrentProcess will give you that:
http://msdn.microsoft.com/en-us/library/system.diagnostics.process.getcurrentprocess.aspx
In Code
Suppose you want to find the start time of Notepad, currently running with PID 4548. You can find it, using the PID or the process name, and print it to the debug window like this:
//pick one of the following two declarations
var procStartTime = System.Diagnostics.Process.GetProcessById(4548).StartTime;
var procStartTime = System.Diagnostics.Process.GetProcessesByName("notepad").FirstOrDefault().StartTime;
System.Diagnostics.Debug.WriteLine(procStartTime.ToLongTimeString());
In Windows
You can use Process Explorer, which has an option to display the process start time, or you can list all the currently running processes, and their start times, from the command line with the following:
wmic process get caption,creationdate
You can get process metadata by inspecting the Process object returned by Process.GetProcessesByName().
System.Diagnostics.Process.GetProcessById(xxx).StartTime;//fails for certain processes with access denied
Related
For learning purposes and mere curiosity I have been trying somehow to kill a process with the characteristics explained above in the title:
1. The name of the file changes every time it is downloaded.
2. Window without a name.
(I can't use PID because I need something that doesn't change to make it automatic)
(The exe name always start with DaxSS-
Example names:
DaxSS-TSFGR
DaxSS-RFDUC
DaxSS-GFFRS
Is there a way to do that?
The downloaded exe name always start with DaxSS
That's your ticket right there!
string start = "DaxSS".ToUpper();
Process P = Process.GetProcesses().Where((p) => p.ProcessName.ToUpper().StartsWith(start)).FirstOrDefault();
if (P != null)
{
P.Kill();
}
In my C# WinForms app, users are allowed to create documents and show them in other programs (typically, Word or Excel) and once users close it (if modified), the file is saved by the app in a specific database.
I use the following code to open the file with the correct default program:
string tmpPath = "myTempDoc.xyz"; // extension might vary
FileInfo f = new FileInfo(tmpPath);
DateTime tmpStamp = f.LastWriteTimeUtc;
System.Diagnostics.Process p = System.Diagnostics.Process.Start(tmpPath);
p.WaitForExit();
f = new FileInfo(tmpPath);
if (f.LastWriteTimeUtc > tmpStamp.AddSeconds(1)) {
db_store_file(tmpPath); // stores the modified version of the file in a database
}
// ---- REMAINING CODE AFTER CLOSING ---
doSomeStuff();
I am a bit concerned with the WaitForExit() method. Users need to close the default program for the app to continue. This is ok, but is it really safe?
What if the user (or some process) kills the App during the WaitForExit? For sure, remaining code doSomeStuff() will NOT be executed so I need to make sure all is done BEFORE starting the process... But is there any additional risk?
I know about FileSystemWatcher could be an alternative... But this allows the user to continue in the app without saving changes, which is an additional risk I'd rather not take...
Is the above method safe? Or is there a standard method for letting users modify files in their default program and, once done, retrieve these changes in the database?
I'm trying to create a keylogger in C# that shows the text that is typed in a RichTextBox and show running apps that are opened in a period of time. E.g. An image in a ListView that contains the icons of apps that are opened in a time and the text typed in a RichTextBox. I've done the keylogging keystrokes recording, but this ListView problem is what I can't hack. Here is what I temporarily have:
private void button1_Click(object sender, EventArgs e)
{
string appName = Application.ProductName;
MessageBox.Show(appName);
//To find the name of the executable
appName = Path.GetFileName(Application.ExecutablePath);
MessageBox.Show(appName);
}
This would only show it in a MessageBox, and contains the name and path of the file running only. Not all applications that are running. Any suggestions?
You would need a Process array for this, I am not clear as how you want the details to be displayed Something like this would do, but be careful when using the methods in the process class as you can kill a lot of process with it and it may lead to system instability.
using System.Diagnostics;
Process[] processes = Process.GetProcesses();
List<string> namesOfRunningProcesses = new List<string>();
foreach(Process p in processes)
namesOfRunningProcesses.Add(p.ProcessName);
You can also access other properties of the process like start time, run time etc. A full list of the properties here on this MSDN Link. Then you can do whatever you want, add it to a list view or whatever.
I am working on renewing an application. The old code had a main method which went through the running processes on windows and checked to see if a certain required process which is a part of the application is running, and if not it starts it. This is how it looks:
Process[] localProcesses = Process.GetProcesses(Environment.MachineName);
bool isHostAlive = false;
foreach (Process localProc in localProcesses)
{
if (localProc.ProcessName == "processIneed")
{
isHostAlive = true;
}
}
if (!isHostAlive)
{
try
{
Process.Start(Application.StartupPath + #"\bin\processIneed.exe");
}
....
Now what I did was adding an installer class in which I override the Commit method and there I'm activating the process so it will automatically run after installing the application. It looks like this:
string path = Context.Parameters["targetdir"].Replace(#"\\", #"\");
path += #"bin\processIneed.exe";
Process.Start(path);
The problem is that in the old way without activating the process during installation everything worked fine. When I'm starting the process in the new way I've implemented, I see that the path is being built correctly and the process do run in the backgroung but the application just doesn't work as it should.. It kinda "half" works.. I'm not getting any errors or exceptions but it just doesn't work.
The only difference I did notice is that with the old code the process was started under the user name which logged in to windows (user name and password entered in the login screen), while in the new code, the process starts under the user SYSTEM.
Is there a way to start the process from the installer class with the correct credentials? I want to clarify that I don't want to somehow request the password from the user and I don't want to save it or something.. just start with the currently logged on credentials and not with the SYSTEM user.
I have a Problem, which is... i start a programm with right click -> run as administrator.
Which means the programm is running in an administrative context.
WindowsIdentity.GetCurrent().Name;
if i try to get the user name that way i will get the user that started the programm as admin.. for example "administrator", but what i need is the name of the current logged in user which is for example: bob
Can anybody help me out? :)
You could try using WMI (System.Management.dll) to get the owner of the explorer.exe process.
string GetExplorerUser()
{
var query = new ObjectQuery(
"SELECT * FROM Win32_Process WHERE Name = 'explorer.exe'");
var explorerProcesses = new ManagementObjectSearcher(query).Get();
foreach (ManagementObject mo in explorerProcesses)
{
string[] ownerInfo = new string[2];
mo.InvokeMethod("GetOwner", (object[])ownerInfo);
return String.Concat(ownerInfo[1], #"\", ownerInfo[0]);
}
return string.Empty;
}
This relies on the fact that the explorer process is single instance an so you don't end up with the possibility of having several explorer processes running with different user credentials.
You will probably need to use win32 API for that. Read about Window Station and Desktop functions here: http://msdn.microsoft.com/en-us/library/ms687107%28v=vs.85%29.aspx
Also see this question:
Get the logged in Windows user name associated with a desktop
Maybe you could start as normal user, save user name, then programmatically request elevation :
Windows 7 and Vista UAC - Programmatically requesting elevation in C#
All .NET libraries will give you the user from the current context ('Administrator' in your case).
If you are trying to secure your code, you might consider reading about: Security in the .NET framework
1) Cassia should be able to give you a list of currently logged in users including RDC.
foreach (ITerminalServicesSession sess in new TerminalServicesManager().GetSessions())
{
// sess.SessionId
// sess.UserName
}
2) WMI (SO answer)
Select * from Win32_LogonSession
3) PInvoke to WTSEnumerateSessions
4) Enumerate all instances of "explorer.exe" and get the owner using PInvoke (OpenProcessHandle).
Process[] processes = Process.GetProcessesByName("explorer");
This is a bit hacky. WMI can also be used for this.
It might be a good idea to set winmgmt as a dependency for your service if you decided to go with solution that uses WMI.