I'm developing a C# solution and I want to get the COM Ports, the description and the friendlyName (if they are bluetooth).
After investigating a bit, I've found that I can get the COM Ports using WMI/CIMV2/Win32_PnPEntity by searching the Name and Description values.
To find the friendly name I need to search on Win32_PnPSignedDriver and take the value of FriendlyName
Is there a way to match them to get a list like this?
COM56 - Bluetooth device - MyBTHDeviceName1
COM76 - Bluetooth device - MyBTHDeviceName2
COM5 - Serial device -
I attach the code that I have right now to get the first two fields.
// Method to retrieve the list of all COM ports.
public static List<PortInfo> FindComPorts()
{
List<PortInfo> portList = new List<PortInfo>();
ConnectionOptions options = PrepareOptions();
ManagementScope scope = PrepareScope(Environment.MachineName, options, #"\root\CIMV2");
// Prepare the query and searcher objects.
ObjectQuery objectQuery = new ObjectQuery("SELECT * FROM Win32_PnPEntity WHERE ConfigManagerErrorCode = 0");
ManagementObjectSearcher portSearcher = new ManagementObjectSearcher(scope, objectQuery);
using (portSearcher)
{
string caption = null;
// Invoke the searcher and search through each management object for a COM port.
foreach (ManagementObject currentObject in portSearcher.Get())
{
if (currentObject != null)
{
object currentObjectCaption = currentObject["Caption"];
if (currentObjectCaption != null)
{
caption = currentObjectCaption.ToString();
if (caption.Contains("(COM"))
{
PortInfo portInfo = new PortInfo();
portInfo.Name = caption.Substring(caption.LastIndexOf("(COM")).Replace("(", string.Empty).Replace(")", string.Empty);
portInfo.Description = caption;
portList.Add(portInfo);
}
}
}
}
}
return portList;
}
Thanks by advance.
The "friendly name" you are looking for is only suitable when COM Ports are virtual (as I assume they are on your example). I think that you can just get the information you need looking for the name property on Win32_PnPEntity class. There is no need to search for aditional information on COM ports as you will get all information already on Win32_PnPEntity class.
You can also try using ORMi and using strong typed objects for that.
Related
VLC GUI shows the list of available webcams, like v4l2:///dev/video0 and v4l2:///dev/video1, I am wondering is there a way to get a list of available webcams? what about their default resolution?
I tried this but md.MediaList is empty.
var mds = libVlc.MediaDiscoverers(MediaDiscovererCategory.Devices);
if (mds.Any(x => x.LongName == "Video capture"))
{
var devices = mds.First(x => x.LongName == "Video capture");
var md = new MediaDiscoverer(libVlc, devices.Name);
foreach (var media1 in md.MediaList)
{
// Nothing ...
}
}
Your MediaDiscoverer is empty because you never call md.Start().
For more info, I found this really helpful: /LibVLCSharp/MediaDiscoverer.cs
That being said, I had no success using MediaDiscoverer to look for webcams myself.
If you don't insist on using LibVLC, you can list all camera devices without any third party software: How can I get a list of camera devices from my PC C#
from Francesco Bonizzi:
public static List<string> GetAllConnectedCameras()
{
var cameraNames = new List<string>();
using (var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity WHERE (PNPClass = 'Image' OR PNPClass = 'Camera')"))
{
foreach (var device in searcher.Get())
{
cameraNames.Add(device["Caption"].ToString());
}
}
return cameraNames;
}
I've been trying to figure out how to do this but I'm always met with a bump on the road. What I'm trying to do is to get the reporting people under my manager's direct reports list; so for example, "Alex" is a direct report under my manager, however, when you go into his organization you see that he also has direct reports that report directly to him - I am trying to get "those" reports not only from his side but from anyone else in the list that has direct reports as well. What is needed for me to effectively execute that idea? Many thanks!
This is my code to only get Direct Reports under my manager tree:
public void GetManagerDirectReports()
{
Application App = new Application();
AddressEntry currentUser = App.Session.CurrentUser.AddressEntry;
if (currentUser.Type == "EX")
{
ExchangeUser manager = currentUser.GetExchangeUser().GetExchangeUserManager();
if (manager != null)
{
AddressEntries addrEntries = manager.GetDirectReports();
if (addrEntries != null)
{
foreach (AddressEntry addrEntry in addrEntries)
{
ExchangeUser exchUser = addrEntry.GetExchangeUser();
StringBuilder sb = new StringBuilder();
sb.AppendLine("Name: "
+ exchUser.Name);
sb.AppendLine("Title: "
+ exchUser.JobTitle);
sb.AppendLine("Department: "
+ exchUser.Department);
sb.AppendLine("Email: "
+ exchUser.PrimarySmtpAddress);
Debug.WriteLine(sb.ToString());
Console.WriteLine(sb.ToString());
Console.ReadLine();
}
}
}
}
}
I opted to go ahead and use LDAP instead of Microsoft's EWS because I saw it uses _ComObject and I don't believe that will work with what I need it to work for. Essentially, I created a master load class and then a sub-class to handle LDAP syntax which would give me the emails of all managers who have direct reports. Something I found useful while doing my research is this filter string which came in quite handy in my time of need (where "cn" is the manager's name):
searcher = new DirectorySearcher
{
Filter = "(&(objectClass=user)(objectCategory=person)(manager=" + cn + ",OU=Unit,OU=People,DC=my,DC=domain,DC=com))"
};
searcher.PropertiesToLoad.Add("DirectReports");
searcher.PropertiesToLoad.Add("mail");
Hope this can serve of some use to coming questions related to this in the future.
I am quite novice in c# but unfortunately have to discover usb ports VIDs and PIDs.
ObjectQuery objectQuery = new ObjectQuery("SELECT * FROM Win32_PnPEntity WHERE ConfigManagerErrorCode = 0");
ManagementObjectSearcher comPortSearcher = new ManagementObjectSearcher(connectionScope, objectQuery);
using (comPortSearcher)
{
string caption = null;
foreach (ManagementObject obj in comPortSearcher.Get())
{
if (obj != null)
{
object captionObj = obj["Caption"];
// Rest of code
}
}
}
I actually can't understand whre this key "Caption" comes from. How can I know what else keys are hidden in this object? It is very unclear for me.
How can I get the list of other of such a "Keys"
This code accesses by WMI different properties. Specifically Win32_PnPEntity class represents the properties of a Plug and Play device.
See more on MSDN about Win32_PnPEntity class and it's properties:
[Dynamic, Provider("CIMWin32"), UUID("{FE28FD98-C875-11d2-B352-00104BC97924}"), AMENDMENT]
class Win32_PnPEntity : CIM_LogicalDevice
{
uint16 Availability;
string Caption;
string ClassGuid;
string CompatibleID[];
uint32 ConfigManagerErrorCode;
/* Rest of properties... */
};
The ManagementObjectSearcher is one way to retrieve information of a WMI Class
I programming in WPF C# and trying to get the ProcessorID (or other system identifier). I have read through MSDN - System.Management Namespace. I add the namespace, but it does not provide ManagementBaseObject Class.
using System.Management;
/* code */
System.Management.(there is no ManagementBaseObject)
Is System.Management only used in WinForms, and not WPF?
The following code will give you the processor id, given that you have added a reference to System.Management:
public static string GetProcessorID()
{
var processorID = "";
var query = "SELECT ProcessorId FROM Win32_Processor";
var oManagementObjectSearcher = new ManagementObjectSearcher(query);
foreach (var oManagementObject in oManagementObjectSearcher.Get())
{
processorID = (string)oManagementObject["ProcessorId"];
break;
}
return processorID;
}
You need to add a reference to System.Management.dll
(Per the "Assembly" in the documentation for that class)
There are some existing types with the System.Management namespace within System.Core, this is why you are seeing some types.
For ManagementBaseObject, however, you will also need to add a reference to System.Management.dll to your project.
The code of Dirk might return a null object.
Please correct it in this way:
public static string GetProcessorID()
{
string cpuid = "";
ManagementObjectSearcher mbs = new ManagementObjectSearcher("Select ProcessorID From Win32_processor");
foreach (ManagementObject mo in mbs.Get())
{
var processorId = mo["ProcessorID"];
if (processorId != null)
{
cpuid = processorId.ToString();
break;
}
}
return cpuid;
}
Im wondering how to get a list of all computers / machines / pc from active directory?
(Trying to make this page a search engine bait, will reply myself. If someone has a better reply il accept that )
If you have a very big domain, or your domain has limits configured on how how many items can be returned per search, you might have to use paging.
using System.DirectoryServices; //add to references
public static List<string> GetComputers()
{
List<string> ComputerNames = new List<string>();
DirectoryEntry entry = new DirectoryEntry("LDAP://YourActiveDirectoryDomain.no");
DirectorySearcher mySearcher = new DirectorySearcher(entry);
mySearcher.Filter = ("(objectClass=computer)");
mySearcher.SizeLimit = int.MaxValue;
mySearcher.PageSize = int.MaxValue;
foreach(SearchResult resEnt in mySearcher.FindAll())
{
//"CN=SGSVG007DC"
string ComputerName = resEnt.GetDirectoryEntry().Name;
if (ComputerName.StartsWith("CN="))
ComputerName = ComputerName.Remove(0,"CN=".Length);
ComputerNames.Add(ComputerName);
}
mySearcher.Dispose();
entry.Dispose();
return ComputerNames;
}
What EKS suggested is correct, but is performing a little bit slow.
The reason for that is the call to GetDirectoryEntry() on each result. This creates a DirectoryEntry object, which is only needed if you need to modify the active directory (AD) object. It's OK if your query would return a single object, but when listing all object in AD, this greatly degrades performance.
If you only need to query AD, its better to just use the Properties collection of the result object. This will improve performance of the code several times.
This is explained in documentation for SearchResult class:
Instances of the SearchResult class are very similar to instances of
DirectoryEntry class. The crucial difference is that the
DirectoryEntry class retrieves its information from the Active
Directory Domain Services hierarchy each time a new object is
accessed, whereas the data for SearchResult is already available in
the SearchResultCollection, where it gets returned from a query that
is performed with the DirectorySearcher class.
Here is an example on how to use the Properties collection:
public static List<string> GetComputers()
{
List<string> computerNames = new List<string>();
using (DirectoryEntry entry = new DirectoryEntry("LDAP://YourActiveDirectoryDomain.no")) {
using (DirectorySearcher mySearcher = new DirectorySearcher(entry)) {
mySearcher.Filter = ("(objectClass=computer)");
// No size limit, reads all objects
mySearcher.SizeLimit = 0;
// Read data in pages of 250 objects. Make sure this value is below the limit configured in your AD domain (if there is a limit)
mySearcher.PageSize = 250;
// Let searcher know which properties are going to be used, and only load those
mySearcher.PropertiesToLoad.Add("name");
foreach(SearchResult resEnt in mySearcher.FindAll())
{
// Note: Properties can contain multiple values.
if (resEnt.Properties["name"].Count > 0)
{
string computerName = (string)resEnt.Properties["name"][0];
computerNames.Add(computerName);
}
}
}
}
return computerNames;
}
Documentation for SearchResult.Properties
Note that properties can have multiple values, that is why we use Properties["name"].Count to check the number of values.
To improve things even further, use the PropertiesToLoad collection to let the searcher know what properties you are going to use in advance. This allows the searcher to only read the data that is actually going to be used.
Note that the DirectoryEntry and DirectorySearcher objects should
be properly disposed in order to release all resources used. Its best
done with a using clause.
An LDAP query like: (objectCategory=computer) should do the trick.
if you only want to get the enabled computers:
(&(objectclass=computer)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))