C# WMI SetMTU System.ManagementException - c#

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

Related

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=""

Renaming Printer using C# and WMI

I have created a C# application to rename printers on a Citrix server (Server 2008 R2).
The reason for this is because every time a user logs on the printer gets forwarded to the server and gets a unique name(For example Microsoft XPS Document Writer (from WI_UFivcBY4-wgoYOdlQ) in session 3) and from within some applications thats an issue since the printer is pointed to the name and by that you need to change the printer setting everytime you logon a session.
The program itself works like a charm and the printer gets the names I desire.
However the issue is after that the printers have been renamed Windows does not seem to be able to identify them anymore. For example if I try to change default printer i get an error saying "Error 0x00000709 Double check the printer name and make sure that the printer is connected to the network."
var query = new ManagementObjectSearcher("SELECT * FROM Win32_Printer where name like '%(%'");
ManagementObjectCollection result = query.Get();
foreach (ManagementObject printer in result)
{
string printerName = printer["name"].ToString();
if (printerName.IndexOf('(') > 0)
{
printer.InvokeMethod("RenamePrinter", new object[] { printerName.Substring(0, printerName.IndexOf('(')).Trim() + " " + userName }); //userName is provided as an inputparameter when running the application
}
}
Am I missing anything? Are there anything else i need to do when renaming?
I cant seem to find any info regarding this case at all.
i thing this codeproject is what your looking for. But after some own experiences with the printers in C# i can only say it does not make fun and it can be really frustrating
Code with small modifications:
//Renames the printer
public static void RenamePrinter(string sPrinterName, string newName)
{
ManagementScope oManagementScope = new ManagementScope(ManagementPath.DefaultPath);
oManagementScope.Connect();
SelectQuery oSelectQuery = new SelectQuery();
oSelectQuery.QueryString = #"SELECT * FROM Win32_Printer WHERE Name = '" + sPrinterName.Replace("\\", "\\\\") + "'";
ManagementObjectSearcher oObjectSearcher =
new ManagementObjectSearcher(oManagementScope, oSelectQuery);
ManagementObjectCollection oObjectCollection = oObjectSearcher.Get();
if (oObjectCollection.Count == 0)
return;
foreach (ManagementObject oItem in oObjectCollection)
{
int state = (int)oItem.InvokeMethod("RenamePrinter", new object[] { newName });
switch (state)
{
case 0:
//Success do noting else
return;
case 1:
throw new AccessViolationException("Access Denied");
case 1801:
throw new ArgumentException("Invalid Printer Name");
default:
break;
}
}
}
Still works great in 2022, thank you. Just had to change type
int
to
UInt32
to avoid new Exception:
UInt32 state = (UInt32)oItem.InvokeMethod("RenamePrinter", new object[] { newName });
switch (state)
{...

Change ip address used by application (application layer)

We have a windows server with 20 ip's bound to the nic. At the moment we are successfully performing (web)requests by (automaticaly) changing the IP's once in a while (request.ServicePoint.BindIPEndPointDelegate = new BindIPEndPoint(connectionInfo.BindIPEndPointCallback);). Since a couple of days we have decided to use a test environment where we use the WebBrowser control of .NET to make the web request.
Here the problem starts, because we cant't give an endpoint like solution to change the ip the webcontrol is using. This is why we've decided to change the IP programmaticaly but whenever we change the IP via WMI, we are getting identified with a single ip adress (all the time).
This is the wmi code:
public static void setIP(string IpAddresses, string SubnetMask, string Gateway)
{
ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject mo in moc)
{
if ((bool)mo["IPEnabled"]==true)
{
ManagementBaseObject newIP = mo.GetMethodParameters("EnableStatic");
ManagementBaseObject newGate = mo.GetMethodParameters("SetGateways");
ManagementBaseObject newDNS = mo.GetMethodParameters("SetDNSServerSearchOrder");
newGate["DefaultIPGateway"] = new string[] { Gateway };
newGate["GatewayCostMetric"] = new int[] { 1 };
newIP["IPAddress"] = IpAddresses.Split(',');
newIP["SubnetMask"] = new string[] { SubnetMask };
ManagementBaseObject setIP = mo.InvokeMethod("EnableStatic", newIP, null);
ManagementBaseObject setGateways = mo.InvokeMethod("SetGateways", newGate, null);
}
}
}
The server runs on VM Ware but I dont think this can be the problem.
What are we doing wrong?
Not really sure, but you pass multiple ip addresses to EnableStatic, but only a single subnet mask, which might cause the problem.
Try to pass a subnet mask for every ip address, i.e. change the assignment of newIP["SubnetMask"] to:
newIP["SubnetMask"] = Enumerable.Repeat(SubnetMask, newIP["IPAddress"].Length).ToArray();
And make sure you do not have any spaces in the IpAddresses argument

Getting CPU ID on virtual machine

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.

Categories