Getting CPU ID on virtual machine - c#

I am trying to use this code:
public string GetCPUId()
{
string cpuInfo = String.Empty;
string temp = String.Empty;
ManagementClass mc = new ManagementClass("Win32_Processor");
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject mo in moc)
{
if (cpuInfo == String.Empty)
{
cpuInfo = mo.Properties["ProcessorId"].Value.ToString();
}
}
return cpuInfo;
}
To get a hw uid on a XP virtual machine (virtualbox), but I am only getting a messagebox that says:
Object reference not set to an instance of an object.
Is it because it's a virtual machine or what?

Yes, it is because you are running a virtual machine. mo.Properties["ProcessorId"] will return null. See the answers here.

I've just found a faster solution here :
http://www.dotnetspark.com/kb/24-get-processor-id-using-c-sharp.aspx
it works faster than yours.and IT WORKS IN MY VIRTUAL WINDOWS(using VMware Workstation 7.0.0 with WINDOWS XP installed virtually) as both codes use the same library yours should work as well! try including dll file in project output it MIGHT Help.
UPDATE (2022): Since the linked page is not working any more I am pasting the code :
public static string GetProcessorID()
{
string sProcessorID = "";
string sQuery = "SELECT ProcessorId FROM Win32_Processor";
ManagementObjectSearcher oManagementObjectSearcher = new ManagementObjectSearcher(sQuery);
ManagementObjectCollection oCollection = oManagementObjectSearcher.Get();
foreach (ManagementObject oManagementObject in oCollection)
{
sProcessorID = (string)oManagementObject["ProcessorId"];
}
return (sProcessorID);
}

That should work just fine on a VM. The CPU ID presented by the virtual CPU may or may not match the physical CPU, though.

Related

C# WMI SetMTU System.ManagementException

We are working on a programm to configure some NICs.
We have to change IP Adresses, Subnetmask and the MTU.
Everything went well except the MTU Statement:
public void SetMTU()
{
ManagementClass objMC = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection objMOC = objMC.GetInstances();
foreach (ManagementObject objMO in objMOC)
{
if (networkadapterID == (String)objMO["SettingID"])
{
ManagementBaseObject setMTU;
ManagementBaseObject newMTU = objMO.GetMethodParameters("SetMTU");
Int32 test = 9216;
newMTU["MTU"] = test;
setMTU = objMO.InvokeMethod("SetMTU", newMTU, null);
}
}
}
The correct NIC ID is given. Other WMI Operations succeed but we stuck on that one with error Message:
System.Management.ManagementException: "Die Methode ist ungültig. "
(System.Management.ManagementException: "The Method is invalid.")
We have also tried to use "test" as string or uint32 (because the microsoft docs says it's an uint32),also:
newMTU["MTU"] = new (u)int[] { MTU };
but it doesnt work either.
Meanwhile we don't have any ideas how to fix the problem.
I am grateful for every idea.
Thanks for your help and have a good day,
Alex
Edit:
Code to read the MTU should be (you have to tell this part a NetworkID so you don't read the Value of every NIC, you find this in your registry, but you should be able to delete the if part):
ManagementClass objMC = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection objMOC = objMC.GetInstances();
foreach (ManagementObject objMO in objMOC)
{
if (networkadapterID == (String)objMO["SettingID"])
{
MessageBox.Show(Convert.ToString(objMO["MTU"]) + ": " + Convert.ToString(objMO["SettingID"]));
}
}
So far we didn't get the problem solved but we now check if the OS is Windows 10 and we will start a PowerShell task with this command:
Get-NetAdapterAdvancedProperty -Name 'NICName' -DisplayName 'Jumbo-Rahmen' | Set-NetAdapterAdvancedProperty -RegistryValue 'MTUsize';
Jumbo-Rahmen should be JumboPacket on an English OS
If the OS is not Windows 10 the User will be asked to change the MTU manually

The best way get unique identification number from virtual machines, which will be the same on the main machine

I try to find a unique ID, which will be the same as the virtual machine and the main machine.
I tried using a monitor ID, bios number, but they can repeat for different end users.
using (ManagementObjectSearcher monitorSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_DesktopMonitor"))
{
foreach (ManagementObject monitor in monitorSearcher.Get())
{
String MonitorName = monitor["Name"].ToString();
String MonitorId = monitor["DeviceId"].ToString();
Console.WriteLine("Monitor name: {0}", MonitorName);
Console.WriteLine("Monitor id: {0}", MonitorId);
}
}
ManagementClass managementClass = new ManagementClass("Win32_BIOS");
ManagementObjectCollection instances = managementClass.GetInstances();
foreach (ManagementBaseObject instance in instances)
{
string version = instance.Properties["SMBIOSBIOSVersion"].Value.ToString();
Console.WriteLine("The version is :" + version.ToString());
}
I read a lot and browsed various topics and forums, but nowhere can I find information or is it possible at all? Maybe there is at least one serial number which will be repeated on the main machine as well as on the virtual one?

C# Update Network Adapter Name partially working (WinReg good, ipconfig bad)

Given the following function:
private void UpdateNetworkAdapterName(string pnpDevID, string oldAdpterName, string newAdapterName)
{
string guid = "";
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_NetworkAdapter");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
ManagementObjectCollection queryCollection = searcher.Get();
foreach (ManagementObject m in queryCollection)
{
if (string.Equals(m["PNPDeviceID"].ToString(), pnpDevID))
{
guid = m["GUID"].ToString();
break;
}
}
RegistryKey regKey = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, Environment.MachineName, RegistryView.Registry64);
regKey = regKey.OpenSubKey("SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\" + guid + "\\Connection", true);
regKey.SetValue("Name", newAdapterName);
bool successful = false;
foreach (NetworkInterface netAd in NetworkInterface.GetAllNetworkInterfaces())
{
if (netAd.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
{
if (string.Equals(netAd.Name, newAdapterName))
{
Console.WriteLine($"Successfully updated network adapter from {oldAdpterName} to {newAdapterName}");
successful = true;
break;
}
}
}
if (!successful)
{
Console.WriteLine($"Failed to updated network adapter from {oldAdpterName} to {newAdapterName}");
}
}
This successfully updated the correct adapter 'Name' data within Windows Registry and the correct adapter name in the Network and Sharing Centre.
However, I get the failed message internally from the code (no exceptions thrown though (have removed exception handling code for readability)) and doing an ipconfig shows that the adpater name has not been updated.
Environment is Windows10 (needs to also work on Windows7), both 64bit architectures, application built as a 32bit application.
Any ideas what is going on? I am at a total loss at this point.
Thanks in advance.
Just realised that I have all the information to just do a netsh command:
netsh interface set interface name="" newname=""

How to get process owner name in 64 bit OS in C#

How do I determine the owner of a process in C#?
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";
}
I detailed studied and implemented the code as given above. This code works fine but only gets the owner names of those processes which are 32 bits. The method return "no owner" for 64 bits processes.
Please help me, how I can get the processes owner names for both 32 bit processes and 64 bit processes.
No, that code works "fine". It also works when your code is 32bit but the target process is 64bit, so no issue here as well.
Possible reasons why you could get "NO OWNER":
You are trying to get the owner for which you have no permission (e.g. you are running as non-privileged user, but trying to get the owner of a privileged one).
You are trying to get the owner of a pseudo process (e.g. "System", with PID 4, or "System Idle Process" with PID 0).
BTW, also services have owners (regarding #weismat comment).

Enumerating list of applications installed using .NET

I use the following code to enumerate applications installed in my system:
ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_Product");
ManagementObjectCollection collection = mos.Get();
List<string> appList = new List<string>();
foreach (ManagementObject mo in collection)
{
try
{
string appName = mo["Name"].ToString();
appList.Add(appName);
}
catch (Exception ex)
{
}
}
When I use this code in console or a WPF application, I get the exact list of apps. But when I use it in a windows service, I'm not getting the entire list. In my case its 1 application less. Is there a limitation to use this in Windows Service?

Categories