Scanning for a Human Interface Device (HID) using C# - c#

I am developing a C# .NET 2.0 application wherein I need to scan for an attached HID. How can this be done? Because it is a HID, Windows does not assign a COM port to it. I only need to programmatically determine if the device is attached. Thank you.
ADDITIONAL INFORMATION
When I connect the USB device to my computer two entries appear under Human Interface Devices in the Device Manager. Clicking into their Properties yields this information in their respective Details tabs:
HID-compliant device
Device Instance Id: HID\VID_1795&PID_6004\7&2694D932&0&0000
USB Human Interface Device
Device Instance Id: USB\VID_1795&PID_6004\B973000000EB0D00

In the WMI Code Creator select these options:
Namespace: root\WMI
Class: MSWmi_PnPInstanceNames
Select InstanceNames from the Results box for the following code:
using System;
using System.Management;
using System.Windows.Forms;
namespace WMISample
{
public class MyWMIQuery
{
public static void Main()
{
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\WMI",
"SELECT * FROM MSWmi_PnPInstanceNames");
foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine("-----------------------------------");
Console.WriteLine("MSWmi_PnPInstanceNames instance");
Console.WriteLine("-----------------------------------");
Console.WriteLine("InstanceName: {0}", queryObj["InstanceName"]);
}
}
catch (ManagementException e)
{
MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
}
}
}
}

Here is an example of enumerating Hid devices on Windows:
public static ConnectedDeviceDefinition GetDeviceDefinition(string deviceId, SafeFileHandle safeFileHandle)
{
try
{
var hidAttributes = GetHidAttributes(safeFileHandle);
var hidCollectionCapabilities = GetHidCapabilities(safeFileHandle);
var manufacturer = GetManufacturer(safeFileHandle);
var serialNumber = GetSerialNumber(safeFileHandle);
var product = GetProduct(safeFileHandle);
return new ConnectedDeviceDefinition(deviceId)
{
WriteBufferSize = hidCollectionCapabilities.OutputReportByteLength,
ReadBufferSize = hidCollectionCapabilities.InputReportByteLength,
Manufacturer = manufacturer,
ProductName = product,
ProductId = (ushort)hidAttributes.ProductId,
SerialNumber = serialNumber,
Usage = hidCollectionCapabilities.Usage,
UsagePage = hidCollectionCapabilities.UsagePage,
VendorId = (ushort)hidAttributes.VendorId,
VersionNumber = (ushort)hidAttributes.VersionNumber,
DeviceType = DeviceType.Hid
};
}
catch (Exception)
{
return null;
}
}
Full class here: https://github.com/MelbourneDeveloper/Device.Net/blob/master/src/Hid.Net/Windows/WindowsHidDeviceFactory.cs
API Calls here: https://github.com/MelbourneDeveloper/Device.Net/blob/master/src/Hid.Net/Windows/HidAPICalls.cs
Here is a similar thing for Windows 10 (UWP):
public async Task<IEnumerable<ConnectedDeviceDefinition>> GetConnectedDeviceDefinitions(FilterDeviceDefinition deviceDefinition)
{
var aqsFilter = GetAqsFilter(deviceDefinition.VendorId, deviceDefinition.ProductId);
var deviceInformationCollection = await wde.DeviceInformation.FindAllAsync(aqsFilter).AsTask();
var deviceDefinitions = deviceInformationCollection.Select(d => GetDeviceInformation(d, DeviceType));
var deviceDefinitionList = new List<ConnectedDeviceDefinition>();
foreach (var deviceDef in deviceDefinitions)
{
var connectionInformation = await TestConnection(deviceDef.DeviceId);
if (connectionInformation.CanConnect)
{
await Task.Delay(1000);
deviceDef.UsagePage = connectionInformation.UsagePage;
deviceDefinitionList.Add(deviceDef);
}
}
return deviceDefinitionList;
}
Code:https://github.com/MelbourneDeveloper/Device.Net/blob/77439b1ab0f4b3ad97376e4e62c7efac0a749783/src/Device.Net.UWP/UWPDeviceFactoryBase.cs#L47
Android (https://github.com/MelbourneDeveloper/Device.Net/blob/77439b1ab0f4b3ad97376e4e62c7efac0a749783/src/Usb.Net.Android/AndroidUsbDeviceFactory.cs#L31):
public Task<IEnumerable<ConnectedDeviceDefinition>> GetConnectedDeviceDefinitions(FilterDeviceDefinition deviceDefinition)
{
return Task.Run<IEnumerable<ConnectedDeviceDefinition>>(() =>
{
//TODO: Get more details about the device.
return UsbManager.DeviceList.Select(kvp => kvp.Value).Where(d => deviceDefinition.VendorId == d.VendorId && deviceDefinition.ProductId == d.ProductId).Select(GetAndroidDeviceDefinition).ToList();
});
}
Using Hid.Net, you can enumerate devices in the same way on any platform like below. See the full article.
var devices = await DeviceManager.Current.GetConnectedDeviceDefinitions(new FilterDeviceDefinition { VendorId = 0x1209, ProductId = 0x53C1 });
foreach (var device in devices)
{
Debug.WriteLine(device.DeviceId);
}

Related

Azure Devops - Get release definitions by agent pool ID

I'm trying to find all the builds and releases that are configured to use a specific agent pool, using the .NET Client Libraries.
Assuming agentPoolId, I can get all the build definitions like this:
// _connection is of type VssConnection
using (var buildClient = _connection.GetClient<BuildHttpClient>())
{
List<BuildDefinitionReference> allBuilds = await buildClient.GetDefinitionsAsync(projectName, top: 1000, queryOrder: DefinitionQueryOrder.DefinitionNameAscending);
List<BuildDefinitionReference> builds = allBuilds.Where(x => HasAgentPoolId(x, agentPoolId)).ToList();
}
private bool HasAgentPoolId(BuildDefinitionReference buildDefinition, int agentPoolId)
{
TaskAgentPoolReference pool = buildDefinition?.Queue?.Pool;
if (pool == null)
{
return false;
}
return pool.Id.Equals(agentPoolId);
}
But I couldn't find a way to find the release definitions that have one or more environments configured to use a particular agent. Any suggestion?
I was manged to get all releases by Agent Pool ID via Rest Api and not via NET Client Libraries.Hope that helps.
C# Code snippet:
public class ReleaseResponse
{
[JsonProperty("value")]
public List<ReleaseItem> Value { get; set; }
}
public class ReleaseItem
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("Id")]
public int Id { get; set; }
}
static void Main(string[] args)
{
string tfsURL = "TFS URL";
string releaseDefurl = $"{tfsURL}/_apis/release/definitions?$expand=artifacts&api-version=3.2-preview.3";
const int agentPoolID = "AGENT Pool ID";
List<string> relevantReleases = new List<string>();
WebClient client = new WebClient();
client.UseDefaultCredentials = true;
client.Headers.Add("Content-Type", "application/json");
var releaseList = client.DownloadString(releaseDefurl);
var allReleases = JsonConvert.DeserializeObject<ReleaseResponse>(releaseList).Value;
foreach (var release in allReleases)
{
string releaseInfoApi = $"{tfsURL}/_apis/Release/definitions/{release.Id}";
var getReleseInfo = client.DownloadString(releaseInfoApi);
var releaseInfo = JsonConvert.DeserializeObject<TFSLogic.RootObject>(getReleseInfo);
var deploymentAgents = releaseInfo.environments.ToList().Where(e => e.deployPhases.FirstOrDefault().deploymentInput.queueId == agentPoolID).Count();
if (deploymentAgents > 0)
{
relevantReleases.Add(release.Name);
}
}
}
Find TFSLogic here : https://codebeautify.org/online-json-editor/cb7aa0d9
Powershell Code snippet:
$tfsUrl = "TFS URL"
$releaseDefurl = $tfsUrl + '/_apis/release/definitions?$expand=artifacts&api-version=3.2-preview.3'
$agentPoolID = "Agent Pool ID"
$relevantReleases = #();
$allReleasesID = (Invoke-RestMethod -Uri ($releaseDefurl) -Method Get -UseDefaultCredentials).value.id
function getReleaseByAgentPoolID($releaseID,$agentPoolID)
{
$ReleaseInfo = Invoke-RestMethod -Uri "$tfsUrl/_apis/Release/definitions/$releaseID" -Method Get -UseDefaultCredentials
$deploymentAgents = $ReleaseInfo.environments | % {$_.deployPhases.deploymentInput.queueId} | where {$_ -eq $agentPoolID}
if($deploymentAgents.Count -gt 0)
{
return $ReleaseInfo.name
}
}
foreach ($releaseID in $allReleasesID)
{
$relevantReleases += getReleaseByAgentPoolID -releaseID $releaseID -agentPoolID $agentPoolID
}
UPDATE :
It took me some time,But i was able to achieve that with azure-devops-dotnet-samples
I hope this example is finally what you are looking for.
using Microsoft.VisualStudio.Services.WebApi;
using System;
using System.Linq;
using Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.Clients;
using Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.Contracts;
using Microsoft.VisualStudio.Services.Common;
using System.Collections.Generic;
namespace FindReleaseByAgentPoolID
{
class Program
{
const int agentPoolID = 999;
static void Main(string[] args)
{
var relevantReleases = new List<string>();
VssCredentials c = new VssCredentials(new WindowsCredential(System.Net.CredentialCache.DefaultNetworkCredentials));
var tfsURL = new Uri("TFS URL");
var teamProjectName = "PROJECT";
using (var connection = new VssConnection(tfsURL, c))
using (var rmClient = connection.GetClient<ReleaseHttpClient2>())
{
var releases = rmClient
.GetReleaseDefinitionsAsync(teamProjectName, string.Empty, ReleaseDefinitionExpands.Environments)
.Result.ToArray();
foreach (var release in releases)
{
var r = rmClient.GetReleaseDefinitionAsync(teamProjectName, release.Id);
var deploymentAgents = r.Result.Environments.SelectMany(e =>
e.DeployPhases.Select(dp =>
dp.GetDeploymentInput()).Cast<DeploymentInput>()).Where(di =>
di.QueueId == agentPoolID).Count();
if (deploymentAgents > 0)
{
relevantReleases.Add(release.Name);
}
}
}
}
}
}
Found a solution, many thanks to #amit-baranes for pointing me in the right direction.
I've changed his code sample to use the await keyword instead of using .Result, and use .OfType<DeploymentInput>() instead of .Cast<DeploymentInput>() (it was throwing some exceptions).
Oh, and the most important thing I've learned: agent pool ID and queue ID are different things!!! If you intend to use the agent pool ID to get the release definitions you'll need to get the correspondent agent queue.
Code sample:
// set agent pool Id and project name
int agentPoolId = 123456;
string teamProjectName = ".....";
// _connection is of type VssConnection
using (var taskAgentClient = _connection.GetClient<TaskAgentHttpClient>())
using (var releaseClient = _connection.GetClient<ReleaseHttpClient2>())
{
// please note: agent pool Id != queue Id
// agent pool id is used to get the build definitions
// queue Id is used to get the release definitions
TaskAgentPool agentPool = await taskAgentClient.GetAgentPoolAsync(agentPoolId);
List<TaskAgentQueue> queues = await taskAgentClient.GetAgentQueuesByNamesAsync(teamProjectName, queueNames: new[] { agentPool.Name });
TaskAgentQueue queue = queues.FirstOrDefault();
List<ReleaseDefinition> definitions = await releaseClient.GetReleaseDefinitionsAsync(teamProjectName, string.Empty, ReleaseDefinitionExpands.Environments);
foreach (ReleaseDefinition definition in definitions)
{
var fullDefinition = await releaseClient.GetReleaseDefinitionAsync(teamProjectName, definition.Id);
bool hasReleasesWithPool = fullDefinition.Environments.SelectMany(GetDeploymentInputs)
.Any(di => di.QueueId == queue.Id);
if (hasReleasesWithPool)
{
Debug.WriteLine($"{definition.Name}");
}
}
}
private IEnumerable<DeploymentInput> GetDeploymentInputs(ReleaseDefinitionEnvironment environment)
{
return environment.DeployPhases.Select(dp => dp.GetDeploymentInput())
.OfType<DeploymentInput>();
}

How do I identify a paired Bluetooth device that's currently disconnected?

How do I discover a paired Bluetooth device that's currently disconnected?
I've attempted the following code using the Windows 10 SDK:
using Windows.Devices.Enumeration;
using Windows.Devices.Bluetooth.Rfcomm;
var serviceInfoCollection = await DeviceInformation.FindAllAsync(RfcommDeviceService.GetDeviceSelector(RfcommServiceId.SerialPort));
I've also tried the following:
using System;
using System.Diagnostics;
using System.Management;
public class Win32_UsbDriveWatcher
{
ManagementEventWatcher m_watcher;
public delegate void DeviceInsertedEventHandler(object sender, Win32_UsbDriveInsertEventArgs e);
public event DeviceInsertedEventHandler DeviceInserted;
public event EventHandler DeviceRemoved;
public void Start(int pollingInterval)
{
try
{
var queryString =
"SELECT * " +
" FROM __InstanceOperationEvent" +
" WITHIN " + pollingInterval +
" WHERE TargetInstance ISA 'Win32_PnPEntity'";
var processQuery = new EventQuery(queryString);
m_watcher = new ManagementEventWatcher(processQuery);
m_watcher.EventArrived += EventArrived;
m_watcher.Start();
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
void EventArrived(object sender, EventArrivedEventArgs e)
{
var instance = ((PropertyData)(e.NewEvent.Properties["TargetInstance"]));
var obj = (ManagementBaseObject)instance.Value;
var args = new Win32_UsbDriveInsertEventArgs();
if ((string)obj["InterfaceType"] == "BLUETOOTH")
{
args.IsCreated = (obj.ClassPath.ClassName == "__InstanceCreationEvent");
args.DriveName = GetDriveLetterFromDisk((string)obj["Name"]);
if (args.IsCreated)
{
DeviceInserted?.Invoke(this, args);
}
else
{
DeviceRemoved?.Invoke(this, EventArgs.Empty);
}
}
}
static string GetDriveLetterFromDisk(string name)
{
name = name.Replace("\\", "\\\\");
var query = "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + name + "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition";
var queryDrive = new ObjectQuery(query);
using (var searcherDrive = new ManagementObjectSearcher(queryDrive))
{
foreach (ManagementObject drive in searcherDrive.Get())
{
query = "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" +
drive["DeviceID"] +
"'} WHERE AssocClass = Win32_LogicalDiskToPartition";
var queryPartition = new ObjectQuery(query);
using (var searcherPartition = new ManagementObjectSearcher(queryPartition))
{
foreach (ManagementObject disk in searcherPartition.Get())
{
return (string)disk["Name"];
}
}
}
return string.Empty;
}
}
}
public class Win32_UsbDriveInsertEventArgs : EventArgs
{
public bool IsCreated;
public string DriveName;
}
Regardless of the code snippets that I've attempted, I'm still unable to discover paired disconnected devices.
Any suggestions?
There are few way:
Use WM_DEVICE_CHANGE message to know when device connected and disconnected.
Once you found all paired devices query each for its services. Not available (disconnected) device reports error.
Try to connect to device's SDP service using DeviceIOControl (the best way).

Finding Bluetooth Mac address in Windows10 UWP without pairing

I'm trying to write an app that reads all MAC addresses around on Windows 10 IoT. These lines of code is returning all paired devices even if they aren't turn on.
var selector = BluetoothDevice.GetDeviceSelector();
var devices = await DeviceInformation.FindAllAsync(selector);
listBox.Items.Add(devices.Count);
foreach (var device in devices)
{
listBox.Items.Add(device.Id);
}
And I also found this line of code
await DeviceInformation.FindAllAsync(RfcommDeviceService.GetDeviceSelector(RfcommServiceId.SerialPort));
This returning null though. Is there any way to scan for all MAC addresses in a Windows 10 universal app?
You are very close to finding the answer of your question. You might try getting a BluetoothDevice instance from the DeviceId property. You will then be able to get all the specific Bluetooth information including the Bluetooth address
var selector = BluetoothDevice.GetDeviceSelector();
var devices = await DeviceInformation.FindAllAsync(selector);
foreach (var device in devices)
{
var bluetoothDevice = await BluetoothDevice.FromIdAsync(device.Id);
if (bluetoothDevice != null)
{
Debug.WriteLine(bluetoothDevice.BluetoothAddress);
}
Debug.WriteLine(device.Id);
foreach(var property in device.Properties)
{
Debug.WriteLine(" " + property.Key + " " + property.Value);
}
}
There is a new approach using BluetoothLEAdvertisementWatcher to scan for all Bluetooth LE device around.
Here is a piece of code I use in my project:
var advertisementWatcher = new BluetoothLEAdvertisementWatcher()
{
SignalStrengthFilter.InRangeThresholdInDBm = -100,
SignalStrengthFilter.OutOfRangeThresholdInDBm = -102,
SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(2000)
};
advertisementWatcher.Received += AdvertisementWatcher_Received;
advertisementWatcher.Stopped += AdvertisementWatcher_Stopped;
advertisementWatcher.Start();
and later
advertisementWatcher.Stop();
advertisementWatcher.Received -= AdvertisementWatcher_Received;
advertisementWatcher.Stopped -= AdvertisementWatcher_Stopped;
private void OnAdvertisementReceived(BluetoothLEAdvertisementWatcher watcher, BluetoothLEAdvertisementReceivedEventArgs eventArgs)
{
//MessAgeChanged(MsgType.NotifyTxt, "FR_NAME:"+ eventArgs.Advertisement.LocalName + "BT_ADDR: " + eventArgs.BluetoothAddress);
string sDevicename = setup.Default.BLEName.Text;
BluetoothLEDevice.FromBluetoothAddressAsync(eventArgs.BluetoothAddress).Completed = async (asyncInfo, asyncStatus) =>
{
if (asyncStatus == AsyncStatus.Completed)
{
if (asyncInfo.GetResults() == null)
{
if (!FailMsg)
{
MessAgeChanged(MsgType.NotifyTxt, "None");
}
}
else
{
BluetoothLEDevice currentDevice = asyncInfo.GetResults();
Boolean contain = false;
foreach (BluetoothLEDevice device in DeviceList.ToArray())/
{
if (device.DeviceId == currentDevice.DeviceId)
{
contain = true;
}
}
if (!contain)
{
byte[] _Bytes1 = BitConverter.GetBytes(currentDevice.BluetoothAddress);
Array.Reverse(_Bytes1);
// The received signal strength indicator (RSSI)
double rssi = eventArgs.RawSignalStrengthInDBm;
DeviceList.Add(currentDevice);
MessAgeChanged(MsgType.NotifyTxt, currentDevice.Name + " " + BitConverter.ToString(_Bytes1, 2, 6).Replace('-', ':').ToLower() + " " + rssi);
DeviceWatcherChanged(MsgType.BleDevice, currentDevice);
}
}
}
};
}

How to get COM port using 32feet in c#?

How do I get COM port where my mobile device connected through a bluetooth stick? I can already get the name of the device eg. 'Nokia C2-01' with device.DeviceName using the 32feet library but how can I make it look like this? "Nokia c2-01 connected through COM7"?
First, you will need to get the device address using:
string comPort = GetBluetoothPort(device.DeviceAddress.ToString());
if(!string.IsNullOrWhiteSpace(comPort))
{
// enter desired output here
}
The GetBluetoothPort() method will look something like this:
using System.Management;
private string GetBluetoothPort(string deviceAddress)
{
const string Win32_SerialPort = "Win32_SerialPort";
SelectQuery q = new SelectQuery(Win32_SerialPort);
ManagementObjectSearcher s = new ManagementObjectSearcher(q);
foreach (object cur in s.Get())
{
ManagementObject mo = (ManagementObject)cur;
string pnpId = mo.GetPropertyValue("PNPDeviceID").ToString();
if (pnpId.Contains(deviceAddress))
{
object captionObject = mo.GetPropertyValue("Caption");
string caption = captionObject.ToString();
int index = caption.LastIndexOf("(COM");
if (index > 0)
{
string portString = caption.Substring(index);
string comPort = portString.
Replace("(", string.Empty).Replace(")", string.Empty);
return comPort;
}
}
}
return null;
}
This will return the port name i.e. COM7

Find Hard Disk Serial number from Remote SQL Server Installed Hard disk

I have a C#.net Windows form Application with SQL Server. My application use in Multiple user by local Network. Now I need to find Hard disk Serial Number which hard disk installed sql server (Note: By Using C#.net Application Data source ).
How can i find Hard disk Serial number throw by application data source?
This might be useful
using System;
using System.Management;
using System.Collections;
namespace WmiControl
{
public class WMI
{
public bool GetDiskSerial(string Computername)
{
try
{
ManagementScope scope = new ManagementScope(#"\\" + Computername + #"\root\cimv2");
scope.Connect();
ArrayList hdCollection;
ManagementObjectSearcher searcher;
if (GetDiskDrive(scope, out hdCollection, out searcher) || GetDiskSerial(scope, hdCollection, ref searcher))
return true;
else
return false;
}
catch (ManagementException)
{
return false;
}
}
private bool GetDiskSerial(ManagementScope scope, ArrayList hdCollection, ref ManagementObjectSearcher searcher)
{
try
{
ObjectQuery query1 = new ObjectQuery("SELECT * FROM Win32_PhysicalMedia");
searcher = new ManagementObjectSearcher(scope, query1);
int i = 0;
string sDiskSerial = "";
foreach (ManagementObject wmi_HD in searcher.Get())
{
// get the hard drive from collection
// using index
if (i < hdCollection.Count)
{
HardDrive hd = (HardDrive)hdCollection[i];
if (wmi_HD["SerialNumber"] == null)
hd.SerialNo = "";
else
hd.SerialNo = wmi_HD["SerialNumber"].ToString();
}
++i;
}
foreach (HardDrive hd in hdCollection)
{
if (!String.IsNullOrEmpty(hd.SerialNo))
{
sDiskSerial = hd.SerialNo;
break;
}
}
return true;
}
catch (Exception)
{
return false;
}
}
private bool GetDiskDrive(ManagementScope scope, out ArrayList hdCollection, out ManagementObjectSearcher searcher)
{
try
{
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_DiskDrive");
hdCollection = new ArrayList();
searcher = new ManagementObjectSearcher(scope, query);
foreach (ManagementObject wmi_HD in searcher.Get())
{
HardDrive hd = new HardDrive();
hd.Model = wmi_HD["Model"].ToString();
hd.Type = wmi_HD["InterfaceType"].ToString();
hdCollection.Add(hd);
return true;
}
return true;
}
catch (Exception)
{
hdCollection = null;
searcher = null;
return false;
}
}
}
class HardDrive
{
private string model = null;
private string type = null;
private string serialNo = null;
public string Model
{
get { return model; }
set { model = value; }
}
public string Type
{
get { return type; }
set { type = value; }
}
public string SerialNo
{
get { return serialNo; }
set { serialNo = value; }
}
}
}
See here for more info
You might want also to study CLR
You'll need to resort to WMI. With the proper privileges on the SQL Server machine, you can get the serial number of the hard-drives on it. See here for an example on retrieving the hard-disk's serial number using WMI.
You'll need to figure out which disk holds SQL Server and how to access the SQL Server machine on your own.
You have to do it in 3 stages:
The connection string of the data source gives you the name of the machine on which SQL Server is installed
You must then query the machine to find out the drive which drive SQL Server is installed on
You can then use the code supplied by others here to get the serial number

Categories

Resources