I found the following method to get a process's owner:
public string GetProcessOwner(int processId)
{
string query = "Select * From Win32_Process Where ProcessID = " + processId;
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
ManagementObjectCollection processList = searcher.Get();
foreach (ManagementObject obj in processList)
{
string[] argList = new string[] { string.Empty, string.Empty };
int returnVal = Convert.ToInt32(obj.InvokeMethod("GetOwner", argList));
if (returnVal == 0)
{
return argList[1] + "\\" + argList[0];
}
}
return "";
}
This works fine, however it is very slow. I use it in conjunction with Process.GetProcesses() and it takes circa 20 seconds in total to get every process owner. Is there any way to speed this up?
Related
i am working on a project that requires a folder to be accessed by only w3wp.exe process.
no other user can access this folder on the machine
i am working on a console project my implementation so far is
public static void SetFolderPermission(string folderPath){
bool exists = Directory.Exists(folderPath);
if (!exists)
{
DirectoryInfo di = System.IO.Directory.CreateDirectory(folderPath);
Console.WriteLine("The Folder is created Sucessfully");
}
else
{
Console.WriteLine("The Folder already exists");
}
var directoryInfo = new DirectoryInfo(folderPath);
var directorySecurity = directoryInfo.GetAccessControl();
var currentUserIdentity = GetIISProcessID("w3wp");
//WindowsIdentity.GetCurrent();
var fileSystemRule = new FileSystemAccessRule(currentUserIdentity,
FileSystemRights.FullControl,
InheritanceFlags.ObjectInherit |
InheritanceFlags.ContainerInherit,
PropagationFlags.None,
AccessControlType.Allow);
directorySecurity.AddAccessRule(fileSystemRule);
directoryInfo.SetAccessControl(directorySecurity);
}
and getting the process is
public static int GetIISProcessID(string appPoolName)
{
//return 0;
string commandLine = String.Empty;
Process[] pCollection = Process.GetProcessesByName(appPoolName);
//Process.GetProcessById(7684, "w3wp.exe");
//Process.GetProcessesByName("w3wp.exe");
foreach (Process pInstance in pCollection)
{
ObjectQuery sq = new ObjectQuery
("Select CommandLine from Win32_Process Where ProcessID = '" + pInstance.Id + "'");
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(sq))
{
ManagementObjectCollection objectCollection = searcher.Get();
foreach (ManagementObject oReturn in objectCollection)
{
commandLine = oReturn["CommandLine"].ToString(); break;
}
Console.WriteLine(commandLine);
}
}
return 0;
}
can someone help me figuring out this how can i make a process access a folder.
This is my code, and i am getting problem with mos.Query and Get().Even after adding System.Management Namespace.
string processName = Process.GetCurrentProcess().MainModule.ModuleName;
ManagementObjectSearcher mos = new ManagementObjectSearcher();
mos.Query.QueryString = #"SELECT * FROM Win32_Process WHERE Name = '" + processName + #"'";
if (mos.Get().Count > 1)
{
return true;
}
else
{
return false;
}
When I restructure your code, I only ever receive one result, so your code would always return false, unless you have multiple instances of the same app with the same image name running.
var processName = Process.GetCurrentProcess().MainModule.ModuleName;
var mos = new ManagementObjectSearcher();
mos.Query.QueryString = #"SELECT * FROM Win32_Process WHERE Name = '" + processName + #"'";
var collection = mos.Get();
var count = collection.Count;
// If count == 1, the process is already running. If it's 0, it's not running. If it's > 1, then multiple copies are running.
return count == 1;
You may also want to do some reading on Mutex and Single Instance applications. There are many good tutorials here and elsewhere on the subject.
Current I am able to get all the Drives and their labels in c# by using the DriveInfo.GetDrives(). Then I am able to get the Disk Index / Index of the Partition by this methodology.
var searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_DiskPartition");
foreach (var queryObj in searcher.Get())
{
Console.WriteLine("-----------------------------------");
Console.WriteLine("Win32_DiskPartition instance");
Console.WriteLine("Name:{0}", (string)queryObj["Name"]);
Console.WriteLine("Index:{0}", (uint)queryObj["Index"]);
Console.WriteLine("DiskIndex:{0}", (uint)queryObj["DiskIndex"]);
Console.WriteLine("BootPartition:{0}", (bool)queryObj["BootPartition"]);
}
The problem with this is that the DiskIndex, Name, and Index are basically just numbers and not the Volume Label i.e. C:\, D:\, etc...
So bottom line how can I make the Volume Label which is the Name Proprty on the DriveInfo to the DiskIndex? Either using this methodology or a better way will work.
(This is a follow to: Tell if a Drive is a partition or a separate HDD)
EDIT:
I did find for the Management Query of the Win32_LogicalDisk and then the Win32_LogicalDiskToPartition. the LogicalDisk has the volume and the LogicalDisktoParition provides the mapping. However, I cannot seem to figure out how to get the map. I tried looking for a JOIN and selecting the values but couldn't find anything on how do this join without extensive looping in the c# code.
some time ago i had same problem and i do it with these code :
ListViewGroup hddgrp;
lstHDD.Columns.Add("Disk");
lstHDD.Columns.Add("Patition");
lstHDD.Columns.Add("Free Space");
lstHDD.Columns.Add("Total Space");
lstHDD.View = View.Details;
String DiskName = "";
String PartState = "";
String PartName = "";
String PartFree = "";
ManagementObjectSearcher hdd = new ManagementObjectSearcher("Select * from Win32_DiskDrive");
foreach (ManagementObject objhdd in hdd.Get())
{
PartState = "";
DiskName = "Disk " + objhdd["Index"].ToString() + " : " + objhdd["Caption"].ToString().Replace(" ATA Device", "") +
" (" + Math.Round( Convert.ToDouble(objhdd["Size"]) / 1073741824,1) + " GB)";
hddgrp = lstHDD.Groups.Add(DiskName, DiskName);
ObjCount = Convert.ToInt16(objhdd["Partitions"]);
ManagementObjectSearcher partitions = new ManagementObjectSearcher(
"Select * From Win32_DiskPartition Where DiskIndex='" + objhdd["Index"].ToString() + "'");
foreach(ManagementObject part in partitions.Get())
{
PartName = part["DeviceID"].ToString();
if (part["Bootable"].ToString() == "True" && part["BootPartition"].ToString() == "True")
PartState = "Recovery";
else
{
ManagementObjectSearcher getdisks = new ManagementObjectSearcher
("Select * From Win32_LogicalDiskToPartition Where ");
PartState = GetPartName(PartName);
PartFree = GetFreeSpace(PartState);
PartState = "Local Disk (" + PartState + ")";
}
lstHDD.Items.Add(new ListViewItem(new String[] { "Partition " + part["Index"].ToString(),
PartState,PartFree ,Math.Round( Convert.ToDouble(part["Size"].ToString()) / 1073741824,1) + " GB"}, hddgrp));
}
}
lstHDD.Columns[0].Width = 80;
lstHDD.Columns[1].Width = 120;
lstHDD.Columns[2].Width = 100;
lstHDD.Columns[3].Width = 100;
and two sub method :
private String GetFreeSpace(String inp)
{
String totalspace = "", freespace = "", freepercent = "";
Double sFree = 0, sTotal = 0, sEq = 0;
ManagementObjectSearcher getspace = new ManagementObjectSearcher("Select * from Win32_LogicalDisk Where DeviceID='" + inp +"'");
foreach (ManagementObject drive in getspace.Get())
{
if (drive["DeviceID"].ToString() == inp)
{
freespace = drive["FreeSpace"].ToString();
totalspace = drive["Size"].ToString();
sFree = Convert.ToDouble(freespace);
sTotal = Convert.ToDouble(totalspace);
sEq = sFree * 100 / sTotal;
freepercent = (Math.Round((sTotal - sFree) / 1073741824, 2)).ToString() + " (" + Math.Round(sEq,0).ToString() + " %)";
return freepercent;
}
}
return "";
}
private String GetPartName(String inp)
{
//MessageBox.Show(inp);
String Dependent = "", ret = "";
ManagementObjectSearcher LogicalDisk = new ManagementObjectSearcher("Select * from Win32_LogicalDiskToPartition");
foreach (ManagementObject drive in LogicalDisk.Get())
{
if (drive["Antecedent"].ToString().Contains(inp))
{
Dependent = drive["Dependent"].ToString();
ret = Dependent.Substring(Dependent.Length - 3, 2);
break;
}
}
return ret;
}
I hope this solution be useful.
for me this result is as below picture
You need to use the Win32_LogicalDisk class.
Edit: You are correct Win32_LogicalDiskToPartition. Is the link between Win32_LogicalDisk and Win32_DiskPartition. On Win32_LogicalDiskToPartition class, these two properties show the links,
PS> Get-WmiObject -Class Win32_LogicalDiskToPartition
Antecedent : \\computer\root\cimv2:Win32_DiskPartition.DeviceID="Disk #0, Partition #1"
Dependent : \\computer\root\cimv2:Win32_LogicalDisk.DeviceID="D:"
Just parse these two properties and filter the the other classes appropriately.
Is there a way to determine what all users are logged into remote machine, using WMI and C#
After little research I was able to figure it out, although not sure if this is the best way
public void GetCompDet(string ComputerName)
{
CurrentSystem = ComputerName;
ConnectionOptions options = new ConnectionOptions();
ManagementScope moScope = new ManagementScope(#"\\" + ComputerName + #"\root\cimv2");
try
{
moScope.Connect();
}
catch
{
return;
}
ObjectQuery query = new ObjectQuery("select * from Win32_Process where name='explorer.exe'");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(moScope, query);
ManagementObjectCollection queryCollection = searcher.Get();
foreach (ManagementObject m in queryCollection)
{
ManagementOperationObserver mo = new ManagementOperationObserver();
mo.ObjectReady += new ObjectReadyEventHandler(mo_ObjectReady);
m.InvokeMethod(mo, "GetOwner", null);
}
}
void mo_ObjectReady(object sender, ObjectReadyEventArgs e)
{
ManagementObject m = sender as ManagementObject;
LoggedinUser.Enqueue(CurrentSystem + " - >" + e.NewObject.Properties["user"].Value.ToString());
Console.WriteLine(CurrentSystem + " - >" + e.NewObject.Properties["user"].Value.ToString());
}
I want to know the user that created each process.
How do I get the usernames of all the processes running in task manager using c#?
Look into Win32_Process Class, and GetOwner Method
Sample Code
Sample code
public string GetProcessOwner(int processId)
{
string query = "Select * From Win32_Process Where ProcessID = " + processId;
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
ManagementObjectCollection processList = searcher.Get();
foreach (ManagementObject obj in processList)
{
string[] argList = new string[] { string.Empty, string.Empty };
int returnVal = Convert.ToInt32(obj.InvokeMethod("GetOwner", argList));
if (returnVal == 0)
{
// return DOMAIN\user
return argList[1] + "\\" + argList[0];
}
}
return "NO OWNER";
}