Getting Data from WIN32_PnPDeviceProperty using C# - c#

I read data from class WIN32_PnPDeviceProperty using Powershell and command PS
C:> Get-PnpDeviceProperty -InstanceId ''.
Similarly I want to read data using C# framework, so I wrote sample code like follow
ObjectQuery query = new ObjectQuery("SELECT * FROM SWD\\PRINTENUM\\{E82E5EFD-6616-4E4F-9A96-7D94554A8BF0}");
ManagementObjectSearcher deviceSearch = new ManagementObjectSearcher(query);
foreach (ManagementObject device in deviceSearch.Get())
{
try
{
Console.WriteLine("Driver ----------------------------------------");
foreach (var item in device.Properties)
Console.WriteLine("{0} : {1}",item.Name,item.Value);
Console.WriteLine();
}
catch (Exception ex) { Console.WriteLine(ex.Message); }
}
But Query returns empty. I am not entirely sure the way to run query or get info using above method is correct or not.
Is there any other way to read data from the mentioned class ?

Related

WMI, Win32_Process

I want to find which processes are using a particular dll using C# and WMI. Tried 3 approaches...
Getting CIM_DataFile object for the file and then get related processes.. It works for system dlls but not for My application dll.. It wont show any process associated with that even though process explorer shows the same.
Enumerating through all the processes and then enumerating through the process modules to find the DLL is being used or not.. Here also same issue.. working for system dlls but not for my application dlls.
Getting CIM_ProcessExecutables objects and getting DLLS/EXE and its linked processes... here also same thing is happening...
Is there anything im missing?
enter code here
using System;
using System.Management;
// Search the processes which have a certain file open
class App
{
public static void Main()
{
WhoHasThisFileOpen("c:\\\\users\\\\pawarnit\\\\source\\\\repos\\\\myprogram\\\\myprogram\\\\bin\\\\debug\\\\differentDllFile.dll");
Console.ReadLine();
}
static void WhoHasThisFileOpen(string objectQry)
{
SelectQuery query = new SelectQuery("select name from cim_datafile where name = '" + objectQry +"'" );
using (ManagementObjectSearcher searcher = new
ManagementObjectSearcher(query))
{
foreach (ManagementObject mo in searcher.Get())
{
Console.WriteLine("File Name: {0} \nIs currently opened by:",
mo.Properties["Name"].Value);
// Get processes having this File open
foreach (ManagementBaseObject b in mo.GetRelated("Win32_Process"))
{
ShowProcessProperties(b.ToString());
b.Dispose();
}
}
}
}
static void ShowProcessProperties(string objectClass)
{
using (ManagementObject process = new ManagementObject(objectClass))
{
process.Get();
PropertyDataCollection processProperties = process.Properties;
Console.WriteLine("ProcessID: {0,6} \tCommandLine: {1}",
processProperties["ProcessID"].Value,
processProperties["CommandLine"].Value);
}
}
}

Simple C# WMI Get & Put

I am trying to Read & Put values from and to WMI using C#.
The current example uses ccm namespace, for configmgr client.
The read functions works correctly, able to read ADV_RepeatRunBehavior value.
Though the Put(); doesn't work as expected, the values are not stored back and Invalid Class exception is thrown.
Some advice would be nice as I am new to this, many thanks.
static void Main(string[] args)
{
try
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher(
"root\\ccm\\Policy\\Machine",
"SELECT * FROM CCM_SoftwareDistribution WHERE PKG_PackageID='XXXXXXXX'");
foreach (ManagementObject queryObj in searcher.Get())
{
//Read works
//Console.WriteLine(queryObj["ADV_RepeatRunBehavior"].ToString());
//Console.ReadLine();
//Put doesn't
queryObj["ADV_RepeatRunBehavior"] = "RerunNever";
queryObj.Put();
}
}
catch (ManagementException z)
{
Console.WriteLine("An error occurred: " + z.Message);
Console.ReadLine();
}
}
Found the resolution for this.
You have to run Visual Studio as Administrator if testing on localhost
The connection to WMI has to be \\root\\ccm\\Policy\\Machine\\ActualConfig then its possible to Put() values.

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?

WQL Like statement & syntax

I've seen atleast two other questions regarding WMI but none had an answer to my question, so here it is;
I was experimenting with the WMI interface in my code. Basically this is what i have right now and it works. But it seems to me i could write it more efficiently:
public bool GetUsbStateById(string id)
{
bool returnValue = false;
try
{
ObjectQuery query = new ObjectQuery();
query.QueryString = string.Format("Select * From Win32_PnPDevice");
ManagementObjectSearcher mySearcher = new ManagementObjectSearcher(query);
List<ManagementObject> results = (from ManagementObject mo in mySearcher.Get().AsParallel()
where mo["SystemElement"].ToString().ToUpper().Contains(id.ToUpper())
select mo).ToList();
if (results.Count > 0)
returnValue = true;
}
catch (Exception ex)
{
// TODO: implement logging
}
return returnValue;
}
So what happens here is that i get a list of ManagementObjects from the ManagementObjectSearcher. This works fine and also returns the exact results as i expect it to work.
But it seems redundant to me. Because, first i get the whole list, and then filter it. But because it uses WQL to fill the list, i assumed that i could implement something like this:
query.QueryString = string.Format("Select * From Win32_PnPDevice where SystemElement Like '%{0}%'",id);
this keeps throwing an exception that the query is not correct.
so i tried this instead:
query.QueryString = string.Format("Select SystemElement From Win32_PnPDevice);
This works as well, so next i tried Win32_PnPDevice.SystemElement, but this didn't work either.
any examples i looked at on the internet showed something like this
Select * From Win32_Service
Where Name Like "%SQL%"
but c# can't parse the double quotes that surround the %SQL% statement there, using an the \ escape character yielded no results either.
To test my code and the code posted below i used the WMI Code Creator from Microsoft
if you want to run like query in WMI then you can use below example:
using System;
using System.Management;
using System.Windows.Forms;
namespace WMISample
{
public class MyWMIQuery
{
public static void Main()
{
try
{
string strSearchText="win";
string strSearchQuery=string.Format("SELECT * FROM Win32_Service where Name like '%{0}%'",strSearchText);
ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2",strSearchQuery );
foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine("-----------------------------------");
Console.WriteLine("Win32_Service instance");
Console.WriteLine("-----------------------------------");
Console.WriteLine("Name: {0}", queryObj["Name"]);
}
}
catch (ManagementException e)
{
MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
}
}
}
}
But you can not apply like query on Win32_PNPDevice as discussed

How to get network adapter index?

From code I want to force a Windows machine to use a specific network adapter for all connections to a specific IP address.
I plan to do so by using the ROUTE ADD command line tool, but this requires that I know in advance the network adapters' index number (as it must be given to the ROUTE ADD command).
QUESTION: How can I programmatically retrieve a network adapter's index, given I know its name?
I'm aware that ROUTE PRINT shows me the information I need (the index numbers of all network adapters present), but there must be a way to get that information programmatically too (C#)?
Note, that I don't like parsing the text output from ROUTE PRINT, as the text format may change with different Windows versions.
You can obtain the interface index of your network adapter
by using the .Net NetworkInterface (and related) classes.
Here is a code example:
static void PrintInterfaceIndex(string adapterName)
{
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
IPGlobalProperties properties = IPGlobalProperties.GetIPGlobalProperties();
Console.WriteLine("IPv4 interface information for {0}.{1}",
properties.HostName, properties.DomainName);
foreach (NetworkInterface adapter in nics)
{
if (adapter.Supports(NetworkInterfaceComponent.IPv4) == false)
{
continue;
}
if (!adapter.Description.Equals(adapterName, StringComparison.OrdinalIgnoreCase))
{
continue;
}
Console.WriteLine(adapter.Description);
IPInterfaceProperties adapterProperties = adapter.GetIPProperties();
IPv4InterfaceProperties p = adapterProperties.GetIPv4Properties();
if (p == null)
{
Console.WriteLine("No information is available for this interface.");
continue;
}
Console.WriteLine(" Index : {0}", p.Index);
}
}
Then just call this function with the name of your network adapter:
PrintInterfaceIndex("your network adapter name");
You can also obtain the InterfaceIndex of your network adapter
by using the Win32_NetworkAdapter WMI class. The Win32_NetworkAdapter class
contains a property called InterfaceIndex.
So, to retrieve the InterfaceIndex for a network adapter with a given
name, use the following code:
ManagementScope scope = new ManagementScope("\\\\.\\ROOT\\cimv2");
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_NetworkAdapter WHERE Description='<Your Network Adapter name goes here>'");
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query))
{
using (ManagementObjectCollection queryCollection = searcher.Get())
{
foreach (ManagementObject mo in queryCollection)
{
Console.WriteLine("InterfaceIndex : {0}, name {1}", mo["InterfaceIndex"], mo["Description"]);
}
}
}
If you do not want to use WMI you could also use the Win32 API function
GetAdaptersInfo in combination with the IP_ADAPTER_INFO struct.
You will find an example here pinvoke.net.
have you looked into using C#'s system.net.networkinformation interface?
http://msdn.microsoft.com/en-us/library/system.net.networkinformation.networkinterface.getallnetworkinterfaces.aspx
I'm not familiar with ROUTE ADD, but you can theoretically marry up information from one with the other.

Categories