I'm using this code to get cpu temperature, but I'm getting 'not supported' instead of the temperature.
public static string getCpuTemperature()
{
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\WMI",
"SELECT * FROM MSAcpi_ThermalZoneTemperature");
//Win32_TemperatureProbe
foreach (ManagementObject queryObj in searcher.Get())
{
double temp = Convert.ToDouble(queryObj["CurrentTemperature"].ToString());
double temp_critical = Convert.ToDouble(queryObj["CriticalTripPoint"].ToString());
double temp_cel = (temp / 10 - 273.15);
double temp_critical_cel = temp_critical / 10 - 273.15;
return temp_cel.ToString() + " _ " + temp_critical_cel.ToString();
}
}
catch (ManagementException e)
{
//MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
return e.Message.ToString();
}
return "";
}
I've googled the problem and have seen many answers for this including,
- the motherboard doesn't support this feature
- run VS with administration right
etc...
but none of them are true, because programs like OpenHardwareMonitor and SpeedFan show the temperature of cpu and gpu, Hdd temperature, cpu fan speed, and all other informations.
I want to know how do they do that? how is that I get 'not supported' message and these programs don't.
This is not a complete answer but hopefully it helps.
After perusing the code at https://code.google.com/p/open-hardware-monitor/source/browse/trunk/, I can't fully understand this code without downloading it all and investigating further.
The magic seems to happen here,
public override void Update() {
base.Update();
for (int i = 0; i < coreTemperatures.Length; i++) {
uint eax, edx;
// if reading is valid
if (Ring0.RdmsrTx(IA32_THERM_STATUS_MSR, out eax, out edx,
1UL << cpuid[i][0].Thread) && (eax & 0x80000000) != 0)
{
// get the dist from tjMax from bits 22:16
float deltaT = ((eax & 0x007F0000) >> 16);
float tjMax = coreTemperatures[i].Parameters[0].Value;
float tSlope = coreTemperatures[i].Parameters[1].Value;
coreTemperatures[i].Value = tjMax - tSlope * deltaT;
} else {
coreTemperatures[i].Value = null;
}
}
...
This code extracts the temperature data from the result of Ring0.RdmsrTx.
I believe Ring0 is a C implementation of a ring buffer, the code of which is in the repository here. This reads the Model Specific Register data from the CPU driver.
There is more detail in this question.
Easiest way would be probably to find a tool that can output the information you need in machine-readable way and then process that output. SpeedFan logs temperature to logs, you could just read the latest reading from the logs.
I realize this might not be an ideal solution, but it is the only universal. Querying CPU temperature in a Windows system is not an easy task.
I'm probably very late to answer this, but just in case someone stumbles upon this in the future, here's the way I did it:
public string getCPUTemp()
{
UpdateVisitor updateVisitor = new UpdateVisitor();
Computer computer = new Computer();
computer.Open();
computer.CPUEnabled = true;
computer.Accept(updateVisitor);
string res = "";
for (int i = 0; i < computer.Hardware.Length; i++)
{
if (computer.Hardware[i].HardwareType == HardwareType.CPU)
{
for (int j = 0; j < computer.Hardware[i].Sensors.Length; j++)
{
if (computer.Hardware[i].Sensors[j].SensorType == SensorType.Temperature) res = String.Concat(res, (computer.Hardware[i].Sensors[j].Name + ": " + computer.Hardware[i].Sensors[j].Value.ToString() + "ÂșC" + "\r"));
if (computer.Hardware[i].Sensors[j].Value.ToString() == "") { res = ""; return res; }
}
}
}
It worked perfectly with me (even though it didn't work for the GPU part). You just have to download OpenHardwareMonitor (https://openhardwaremonitor.org/), then add the reference to the OpenHardwareMonitorLib.dll which is in the \openhardwaremonitor\Bin\Debug folder, then add "using OpenHardwareMonitor.Hardware;" at the top.
Hope it can still help someone even if not OP!
Related
ive been searching for a way to try to properly capture the sound that is currently playing through the default "speakers" of the pc and make a visualizer out of it.
Thats where NAudio comes in:
MMDevice[] AudioDevices = new MMDeviceEnumerator().EnumerateAudioEndPoints(DataFlow.All, DeviceState.Active).ToArray();
foreach (MMDevice device in AudioDevices)
{
string deviceType = device.DataFlow == DataFlow.Capture ? "INPUT" : "OUTPUT";
string deviceLabel = $"{deviceType}: {device.FriendlyName}";
deviceLabels.Add(deviceLabel);
}
var enumerator = new MMDeviceEnumerator();
var default_device = enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Console);
MMDevice selectedDevice = AudioDevices[0];
AudioDevice = selectedDevice.DataFlow == DataFlow.Render ? new WasapiLoopbackCapture(selectedDevice) : new WasapiCapture(selectedDevice, true, 10);
AudioDevice.DataAvailable += WaveIn_DataAvailable;
Capturing the audio values i use the following event:
private void WaveIn_DataAvailable(object? sender, WaveInEventArgs e)
{
int bytesPerSamplePerChannel = AudioDevice.WaveFormat.BitsPerSample / 8;
int bytesPerSample = bytesPerSamplePerChannel * AudioDevice.WaveFormat.Channels;
int bufferSampleCount = e.Buffer.Length / bytesPerSample;
if (bufferSampleCount >= AudioValues.Length)
{
bufferSampleCount = AudioValues.Length;
}
if (bytesPerSamplePerChannel == 2 && AudioDevice.WaveFormat.Encoding == WaveFormatEncoding.Pcm)
{
for (int i = 0; i < bufferSampleCount; i++)
AudioValues[i] = BitConverter.ToInt16(e.Buffer, i * bytesPerSample);
}
else if (bytesPerSamplePerChannel == 4 && AudioDevice.WaveFormat.Encoding == WaveFormatEncoding.Pcm)
{
for (int i = 0; i < bufferSampleCount; i++)
AudioValues[i] = BitConverter.ToInt32(e.Buffer, i * bytesPerSample);
}
else if (bytesPerSamplePerChannel == 4 && AudioDevice.WaveFormat.Encoding == WaveFormatEncoding.IeeeFloat)
{
for (int i = 0; i < bufferSampleCount; i++)
AudioValues[i] = BitConverter.ToSingle(e.Buffer, i * bytesPerSample);
}
else
{
throw new NotSupportedException(AudioDevice.WaveFormat.ToString());
}
}
Lastly, I then use a FFT library to then convert the audio values to a new array using FFTmagnitude Transformation and then process them further to get my visualizer but this is out of scope of the problem im facing.
The problem i have is that the audio data array outputed from the WaveIn_DataAvailable event is dependant of the "speakers" volume, so if the volume is for example at 2%, the audio values im getting are much lower than if the volume was at 100%.
Strangely if the volume is muted or 0% the audio values are as high as 100%.
What i would like to get instead is, regardless of the volume level to always get the audio values as if it was 100%.
I couldnt find any way to get the audio values this way, there has to be something very obvious or simple that im missing but so far i couldnt find any example or suggestion on how to achieve this.
This is an extended question from here Using UWP monitor live audio and detect gun-fire/clap sound
Thanks to Dernis I finally got the code working to monitor live audio and trigger events when decibel count is above a certain range.
This works perfectly when we run it in office/closed/silent area.
But when I take the app to open road, there will be traffic sound, wind sound, people talk sound and other noises and BLOW events are not identified correctly.
I would like to implement something like Lean Environment button. Before app starts monitoring, the user clicks on "Lean Environment" that recognize the sensitivity levels and set filtering to my live audio and then I start monitoring blows.
If it doesn't add too much load, I would like to record the audio to a file.
Any help on where to start would be appreciated.
OnNavigatedTo
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
//other logic
await CreateInputDeviceNodeAsync(_deviceId);
}
CreateInputDeviceNodeAsync
public async Task<bool> CreateInputDeviceNodeAsync(string deviceId)
{
Console.WriteLine("Creating AudioGraphs");
// Create an AudioGraph with default settings
AudioGraphSettings graphSettings = new AudioGraphSettings(AudioRenderCategory.Media)
{
EncodingProperties = new AudioEncodingProperties
{
Subtype = "Float",
SampleRate = 48000,
ChannelCount = 2,
BitsPerSample = 32,
Bitrate = 3072000
}
};
CreateAudioGraphResult audioGraphResult = await AudioGraph.CreateAsync(graphSettings);
if (audioGraphResult.Status != AudioGraphCreationStatus.Success)
{
_rootPage.NotifyUser("Cannot create graph", NotifyType.ErrorMessage);
return false;
}
_audioGraph = audioGraphResult.Graph;
AudioGraphSettings audioGraphSettings =
new AudioGraphSettings(AudioRenderCategory.GameChat)
{
EncodingProperties = AudioEncodingProperties.CreatePcm(48000, 2, 32),
DesiredSamplesPerQuantum = 990,
QuantumSizeSelectionMode = QuantumSizeSelectionMode.ClosestToDesired
};
_frameOutputNode = _audioGraph.CreateFrameOutputNode(_audioGraph.EncodingProperties);
_quantum = 0;
_audioGraph.QuantumStarted += Graph_QuantumStarted;
LoudNoise += BlowDetected;
DeviceInformation selectedDevice = null;
if (!string.IsNullOrWhiteSpace(_deviceId))
selectedDevice = await DeviceInformation.CreateFromIdAsync(_deviceId);
if (selectedDevice == null)
{
string device = Windows.Media.Devices.MediaDevice.GetDefaultAudioCaptureId(
Windows.Media.Devices.AudioDeviceRole.Default);
if (!string.IsNullOrWhiteSpace(device))
selectedDevice = await DeviceInformation.CreateFromIdAsync(device);
else
{
_rootPage.NotifyUser($"Could not select Audio Device {device}", NotifyType.ErrorMessage);
return false;
}
}
CreateAudioDeviceInputNodeResult result =
await _audioGraph.CreateDeviceInputNodeAsync(MediaCategory.Media, audioGraphSettings.EncodingProperties,
selectedDevice);
if (result.Status != AudioDeviceNodeCreationStatus.Success)
{
_rootPage.NotifyUser("Cannot create device output node", NotifyType.ErrorMessage);
return false;
}
_selectedMicrophone = selectedDevice.Name;
_deviceInputNode = result.DeviceInputNode;
_deviceInputNode.AddOutgoingConnection(_frameOutputNode);
_frameOutputNode.Start();
_audioGraph.Start();
return true;
}
Graph_QuantumStarted
private void Graph_QuantumStarted(AudioGraph sender, object args)
{
if (++_quantum % 2 != 0) return;
AudioFrame frame = _frameOutputNode.GetFrame();
float[] dataInFloats;
using (AudioBuffer buffer = frame.LockBuffer(AudioBufferAccessMode.Write))
using (IMemoryBufferReference reference = buffer.CreateReference())
unsafe
{
// Get the buffer from the AudioFrame
// ReSharper disable once SuspiciousTypeConversion.Global
((IMemoryBufferByteAccess) reference).GetBuffer(out byte* dataInBytes,
out var capacityInBytes);
var dataInFloat = (float*) dataInBytes;
dataInFloats = new float[capacityInBytes / sizeof(float)];
for (var i = 0; i < capacityInBytes / sizeof(float); i++)
{
dataInFloats[i] = dataInFloat[i];
}
}
double decibels = dataInFloats.Aggregate<float, double>(0f, (current, sample) => current + Math.Abs(sample));
decibels = 20 * Math.Log10(decibels / dataInFloats.Length);
_decibelList.Add(decibels);
if (double.IsInfinity(decibels) || decibels < _threshold) return;//-45
if (_watch != null && _watch.Elapsed <= TimeSpan.FromSeconds(1)) return;
LoudNoise?.Invoke(this, decibels);
_watch = Stopwatch.StartNew();
}
This is just statistics. You'll want to collect probably at least 50 frames (1 second) of data before actually having it function (maybe let the user decide by holding and releasing a button). Then you'll probably want to determine where the decibel level is usually around. I can think of 3 ways to do that.
private void Graph_QuantumStarted(AudioGraph sender, object args)
{
...
double decibels = dataInFloats.Aggregate<float, double>(0f, (current, sample) => current + Math.Abs(sample)); // I dislike the fact that the decibels variable is initially inaccurate, but it's your codebase.
decibels = 20 * Math.Log10(decibels / dataInFloats.Length);
if (scanning) // class variable (bool), you can set it from the UI thread like this
{
_decibelList.Add(decibels); // I assume you made this a class variable
}
else if (decibels == Double.NaN)
{
// Code by case below
}
else if (decibels > _sensitivity) //_sensitivity is a class variable(double), initialized to Double.NaN
{
LoudNoise?.Invoke(this, true); // Calling events is a wee bit expensive, you probably want to handle the sensitivity before Invoking it, I'm also going to do it like that to make this demo simpler
}
}
If you can control make sure there's no spike loud enough you want it to go off you can just take the max value of all those frames and say if it's over the sensitivity is maxDecibels + Math.Abs(maxDecibels* 0.2) (the decibels could be negative, hence Abs).
double maxDecibels = _decibelList.OrderByDescending(x => x)[0];
_sensitivity = maxDecibels + Math.Abs(maxDecibels* 0.2);
If you can't control when there's a spike, then you could collect those frames, sort, and have it take item [24] (of your 100 item list) and say that's the sensitivity.
sensitivity = _decibelList.OrderByDescending(x => x)[24]; // If you do a variable time you can just take Count/4 - 1 as the index
(I think it's the best but I really don't know statistics) Walk the list of frame's decibels and track the average difference in value and the what index changed it most. Afterwards, find the max value from after that index and say 75% of the change to there is the sensitivty. (Don't use a LinkedList on this)
int greatestChange, changeIndex = 0;
double p = Double.NaN; // Previous
for (int i = 0; i < _decibelList.Count(); i++)
{
if (p != Double.Nan)
{
change = Math.Abs(_decibelList[i] - p);
if (Math.Abs(change > greatestChange)
{
greatestChange = change;
changeIndex = i;
}
}
p = _decibelList[i];
}
int i = changeIndex;
p = Double.NaN; // reused
double c= Double.NaN; // Current
do
{
p = c != Double.NaN ? c : _decibelList[i];
c = _decibelList[++i];
} while (c < p);
_sensitivity = ((3 * c) + _decibelList[changeIndex]) / 4;
Note: You can (kind of) remove the need to sort by having a LinkedList and inserting in the appropiate place
I am trying to implement Hardware locked Licensing.I found the following code from codeproject that generates hardware id(Machine ID)
This code generates Hardware Key
using System;
using System.Management;
using System.Security.Cryptography;
using System.Security;
using System.Collections;
using System.Text;
namespace Security
{
/// <summary>
/// Generates a 16 byte Unique Identification code of a computer
/// Example: 4876-8DB5-EE85-69D3-FE52-8CF7-395D-2EA9
/// </summary>
public class FingerPrint
{
private static string fingerPrint = string.Empty;
public static string Value()
{
if (string.IsNullOrEmpty(fingerPrint))
{
fingerPrint = GetHash("CPU >> " + cpuId() + "\nBIOS >> " +
biosId() + "\nBASE >> " + baseId()
//+"\nDISK >> "+ diskId() + "\nVIDEO >> " +
videoId() +"\nMAC >> "+ macId()
);
}
return fingerPrint;
}
private static string GetHash(string s)
{
MD5 sec = new MD5CryptoServiceProvider();
ASCIIEncoding enc = new ASCIIEncoding();
byte[] bt = enc.GetBytes(s);
return GetHexString(sec.ComputeHash(bt));
}
private static string GetHexString(byte[] bt)
{
string s = string.Empty;
for (int i = 0; i < bt.Length; i++)
{
byte b = bt[i];
int n, n1, n2;
n = (int)b;
n1 = n & 15;
n2 = (n >> 4) & 15;
if (n2 > 9)
s += ((char)(n2 - 10 + (int)'A')).ToString();
else
s += n2.ToString();
if (n1 > 9)
s += ((char)(n1 - 10 + (int)'A')).ToString();
else
s += n1.ToString();
if ((i + 1) != bt.Length && (i + 1) % 2 == 0) s += "-";
}
return s;
}
#region Original Device ID Getting Code
//Return a hardware identifier
private static string identifier
(string wmiClass, string wmiProperty, string wmiMustBeTrue)
{
string result = "";
System.Management.ManagementClass mc =
new System.Management.ManagementClass(wmiClass);
System.Management.ManagementObjectCollection moc = mc.GetInstances();
foreach (System.Management.ManagementObject mo in moc)
{
if (mo[wmiMustBeTrue].ToString() == "True")
{
//Only get the first one
if (result == "")
{
try
{
result = mo[wmiProperty].ToString();
break;
}
catch
{
}
}
}
}
return result;
}
//Return a hardware identifier
private static string identifier(string wmiClass, string wmiProperty)
{
string result = "";
System.Management.ManagementClass mc =
new System.Management.ManagementClass(wmiClass);
System.Management.ManagementObjectCollection moc = mc.GetInstances();
foreach (System.Management.ManagementObject mo in moc)
{
//Only get the first one
if (result == "")
{
try
{
result = mo[wmiProperty].ToString();
break;
}
catch
{
}
}
}
return result;
}
private static string cpuId()
{
//Uses first CPU identifier available in order of preference
//Don't get all identifiers, as it is very time consuming
string retVal = identifier("Win32_Processor", "UniqueId");
if (retVal == "") //If no UniqueID, use ProcessorID
{
retVal = identifier("Win32_Processor", "ProcessorId");
if (retVal == "") //If no ProcessorId, use Name
{
retVal = identifier("Win32_Processor", "Name");
if (retVal == "") //If no Name, use Manufacturer
{
retVal = identifier("Win32_Processor", "Manufacturer");
}
//Add clock speed for extra security
retVal += identifier("Win32_Processor", "MaxClockSpeed");
}
}
return retVal;
}
//BIOS Identifier
private static string biosId()
{
return identifier("Win32_BIOS", "Manufacturer")
+ identifier("Win32_BIOS", "SMBIOSBIOSVersion")
+ identifier("Win32_BIOS", "IdentificationCode")
+ identifier("Win32_BIOS", "SerialNumber")
+ identifier("Win32_BIOS", "ReleaseDate")
+ identifier("Win32_BIOS", "Version");
}
//Main physical hard drive ID
private static string diskId()
{
return identifier("Win32_DiskDrive", "Model")
+ identifier("Win32_DiskDrive", "Manufacturer")
+ identifier("Win32_DiskDrive", "Signature")
+ identifier("Win32_DiskDrive", "TotalHeads");
}
//Motherboard ID
private static string baseId()
{
return identifier("Win32_BaseBoard", "Model")
+ identifier("Win32_BaseBoard", "Manufacturer")
+ identifier("Win32_BaseBoard", "Name")
+ identifier("Win32_BaseBoard", "SerialNumber");
}
//Primary video controller ID
private static string videoId()
{
return identifier("Win32_VideoController", "DriverVersion")
+ identifier("Win32_VideoController", "Name");
}
//First enabled network card ID
private static string macId()
{
return identifier("Win32_NetworkAdapterConfiguration",
"MACAddress", "IPEnabled");
}
#endregion
}
}
.My aim is to implement strict licensing scheme.As shown in the diagram given below,I am able to generate a unique machine or Hardware ID using the above code.
Based on the Machine ID or Key,I wish to generate an Activation Key so that it would be unique and can be used only on one machine because the Activation key would be generated from that Machines MachineID
How can that be achieved?
Following is the image
I hope my doubt is clear.If not please let me know,I'll update the question with more information
The simple solution
The simple solution would be something like this. When the user buys your software, generate a unique GUID for the license. Let's call this the license key. When the user installs the software, you take your unique hardware key, concatenate that with the license key, and hash the result. The hash you generate will be the activation code that you're looking for. Store that value on your server. If the same license key is ever used to install the software on another machine, you will compare the computed activation code for that installation against the one you have stored on your server and deny the installation if the codes do not match.
The Catch
That being said... the way your current scheme is set up, you are going to risk making your customers very upset. For example, if I buy your software and my hard drive dies on me, with your current setup I would have no way to recover my software. If you're going to do hardware signature based licensing, you should try to restrict it to the features that are least likely to change. BIOS...ok maybe you're safe. But hard drive, network card, video card are much more likely to change.
Also, you might want to give your customers a way to transfer the license to another computer. The way your do this is have a custom action in your uninstaller that will revoke the activation code for the license so it will no longer be tied to that hardware ID.
Conclusion
In all of this, the key is to keep things as simple as possible for your customer. There obviously is a trade-off between security and ease of use, but you DO NOT want to lock out legitimate customers and risk alienating them.
All that being said, there are also plenty of existing commercials options for managing licenses. QLM is pretty good is you're willing to shell out the money. In everything, just consider the cost of securing your software versus the value of securing it.
I'm working on a speech recognition program in C# and I've compiled a few lines of code that speaks back the current battery level when I say "battery level".
if (e.Result.Text.ToLower() == "battery level")
{
System.Management.ManagementClass wmi = new System.Management.ManagementClass("Win32_Battery");
var allBatteries = wmi.GetInstances();
String estimatedChargeRemaining = String.Empty;
foreach (var battery in allBatteries)
{
estimatedChargeRemaining = Convert.ToString(battery["EstimatedChargeRemaining"]);
}
JARVIS.Speak("The Power Level Is At: " + estimatedChargeRemaining + "% sir");
return;
}
Within that I want to create another if statement to alert me if the battery level has dropped below 25%. How can this be done? I'm guessing it will be something like "if estimatedChargeRemaining < 25 then JARVIS.Speak("Warning, Battery level has dropped below 25%") but I'm not quite sure.
I'm not sure what format battery["EstimatedChargeRemaining"] returns but it seems you can convert it to an int instead of a string.
int batteryLevel = Convert.ToInt32(battery["EstimatedChargeRemaining"]);
if(batteryLevel < 25)
JARVIS.Speak("Warning, Battery level has dropped below 25%");
You can then use that batteryLevel variable later on
JARVIS.Speak("The Power Level Is At: " + batteryLevel.ToString() + "% sir");
Not sure if it's intended but your foreach loop means that you'll only get the battery information of the last value in allBatteries. All the previous values will be overwritten.
Edit for comment (you should add error handling)
if (e.Result.Text.ToLower() == "battery level")
{
System.Management.ManagementClass wmi = new System.Management.ManagementClass("Win32_Battery");
var allBatteries = wmi.GetInstances();
//String estimatedChargeRemaining = String.Empty;
int batteryLevel = 0;
foreach (var battery in allBatteries)
{
batteryLevel = Convert.ToInt32(battery["EstimatedChargeRemaining"]);
}
if(batteryLevel < 25)
JARVIS.Speak("Warning, Battery level has dropped below 25%");
else //Guessing you want else
JARVIS.Speak("The Power Level Is At: " + batteryLevel.ToString() + "% sir");
return;
}
how to get all drives in a PC. and types of every drive and free-space of each
i.e. System-Drive, CD-Drive, DVD-Drive, Removable, ... etc.
If a system is attached with a new drive may be a pen drive or external hard disc.
How to detect them at time of attachment ?
To get a list of the drives, you can use the System.IO.DriveInfo class:
foreach(var drive in DriveInfo.GetDrives())
{
Console.WriteLine("Drive Type: {0}", drive.DriveType);
Console.WriteLine("Drive Size: {0}", drive.TotalSize);
Console.WriteLine("Drive Free Space: {0}", drive.TotalFreeSpace);
}
Unfortunately, this doesn't provide a way to listen for USB Key Insertions. There is another question dealing with that you could check out:
.NET - Detecting USB Drive Insertion and Removal...
public string getalldrivestotalnfreespace()
{
string s = " Drive Free Space TotalSpace FileSystem %Free Space DriveType\n\r========================================================================================\n\r";
foreach (DriveInfo drive in DriveInfo.GetDrives())
{
double ts = 0;
double fs = 0;
double frprcntg = 0;
long divts = 1024 * 1024 * 1024;
long divfs = 1024 * 1024 * 1024;
string tsunit = "GB";
string fsunit = "GB";
if (drive.IsReady)
{
fs = drive.TotalFreeSpace;
ts = drive.TotalSize;
frprcntg = (fs / ts) * 100;
if (drive.TotalSize < 1024)
{
divts =1; tsunit = "Byte(s)";
}
else if (drive.TotalSize < (1024*1024))
{
divts = 1024; tsunit = "KB";
}
else if (drive.TotalSize < (1024 * 1024*1024))
{
divts = 1024*1024; tsunit = "MB";
}
//----------------------
if (drive.TotalFreeSpace < 1024)
{
divfs = 1; fsunit = "Byte(s)";
}
else if (drive.TotalFreeSpace < (1024 * 1024))
{
divfs = 1024; fsunit = "KB";
}
else if (drive.TotalFreeSpace < (1024 * 1024 * 1024))
{
divfs = 1024 * 1024; fsunit = "MB";
}
s = s +
" " + drive.VolumeLabel.ToString() +
"[" + drive.Name.Substring(0, 2) +
"]\t" + String.Format("{0,10:0.0}", ((fs / divfs)).ToString("N2")) + fsunit +
String.Format("{0,10:0.0}", (ts / divts).ToString("N2")) + tsunit +
"\t" + drive.DriveFormat.ToString() + "\t\t" + frprcntg.ToString("N2") + "%"+
"\t\t" + drive.DriveType.ToString();
s = s + "\n\r";
}
}
return s;
}
The ouput should look like :-
Environment.GetLogicalDrives();
MSDN link
You can get the drives and info quite easily
DriveInfo[] drives = DriveInfo.GetDrives();
foreach (DriveInfo drive in drives)
{
Console.WriteLine(drive.Name);
Console.WriteLine(drive.TotalSize);
}
There's a good article on detecting adding/removing drives on CodeProject
Environment.GetLogicalDrives();
MSDN link
The WMI libraries will probably help. Also there's a codeproject article that talks about this:
http://www.codeproject.com/KB/cs/UsbManager.aspx
Here is the answer to your first question. To get all logical drives you can try this:
string[] drives = Environment.GetLogicalDrives();
The System.IO.DriveInfo class is the place to start. The DriveType property can tell you what you are looking for.
To get all the drives currently attached:
DriveInfo[] allDrives = DriveInfo.GetDrives();
And for the detection you have to listen to WMI events. Check this out: http://www.techtalkz.com/c-c-sharp/182048-need-detect-insertion-removal-usb-drive.html