C# Logical memory configuration view - c#

How can view logical memory configuration ?
private void button1_Click(object sender, EventArgs e)
{
ObjectQuery winQuery = new ObjectQuery("SELECT * FROM Win32_LogicalMemoryConfiguration");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(winQuery);
foreach (ManagementObject item in searcher.Get())
{
textBox1.Text =("Total Space = " + item["TotalPageFileSpace"]);
textBox2.Text = ("Total Physical Memory = " + item["TotalPhysicalMemory"]);
textBox3.Text = ("Total Virtual Memory = " + item["TotalVirtualMemory"]);
textBox4.Text = ("Available Virtual Memory = " + item["AvailableVirtualMemory"]);
}
}
In this code seems doesn't work . And has no error on compilation .

According to Microsoft
The Win32_LogicalMemoryConfiguration WMI class is no longer available for use as of Windows Vista.
The article suggests you use the Win32_OperatingSystem but you might be better off using Process.GetCurrentProcess().

Related

C# - Logging Available Wifi Connections (While I'm in the car)

For a couple of days, I have puzzled about how to do this in the best way possible. I created a form application like so:
I gave the name "WiFi Hacker" for giggles. But my question is, why does Visual Studio give me this error after a couple minutes using the program?
Additional information: Type 'NativeWifi.Wlan+WlanReasonCode' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed.
I am using NativeWifi for my program, and the code for logging networks is as follows:
WlanClient client = new WlanClient();
private void wifilister()
{
foreach (WlanClient.WlanInterface wI in client.Interfaces)
{
foreach (Wlan.WlanAvailableNetwork network in wI.GetAvailableNetworkList(0))
{
Wlan.Dot11Ssid ssid = network.dot11Ssid;
string networkName = Encoding.ASCII.GetString(ssid.SSID, 0, (int)ssid.SSIDLength);
if (wifis.Contains(networkName) == false)
{
//Name
ListViewItem item = new ListViewItem(networkName);
wifis.Add(networkName);
listBox1.Items.Add(networkName);
//Encryption Type
item.SubItems.Add(network.dot11DefaultCipherAlgorithm.ToString());
wifis.Add(network.dot11DefaultCipherAlgorithm.ToString());
//Signal
item.SubItems.Add(network.wlanSignalQuality + "%");
wifis.Add(network.wlanSignalQuality + "%");
//Logged Time
item.SubItems.Add(DateTime.Now.ToString("T"));
wifis.Add(DateTime.Now.ToString("T"));
listView1.Items.Add(item);
label2.Text = "Networks: " + (wifis.Count / 4).ToString();
}
if (checkBox2.Checked)
{
label1.Text = track;
if (Encoding.ASCII.GetString(ssid.SSID, 0, (int)ssid.SSIDLength) == track)
{
label1.Text += " " + network.wlanSignalQuality + "%";
}
}
}
}
I got most of this off a tutorial from YouTube, but after it logs more than about 40 different networks in the List, it seems to give that weird error about
'NativeWifi.Wlan+WlanReasonCode'.
This annoyed me, is there a way around it?

List Of Hard Disks and drives on them

how can i get a list of hard disks and their partitions(their logical drives) on my computer in c#?
iam looking for code that gives me similar results
harddisk0:partitions are C,D
harddisk1:partitions are C,F,D
i have tried this code
foreach (ManagementObject drive in search.Get())
{
string antecedent = drive["DeviceID"].ToString();
// the disk we're trying to find out about
antecedent = antecedent.Replace(#"\", "\\");
// this is just to escape the slashes
string query = "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='"
+ antecedent
+ "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition";
using (ManagementObjectSearcher partitionSearch = new ManagementObjectSearcher(query))
{
foreach (ManagementObject part in partitionSearch.Get())
{
//...pull out the partition information
Console.WriteLine("Dependent : {0}", part["Dependent"]);
}
}
}
knowing that dependent is a Reference to the instance representing the disk partition residing on the disk drive.
but iam getting the exception Not Found
what should i write please?
here is c# solution generated by me
foreach (ManagementObject drive in search.Get())
{
string antecedent = drive["DeviceID"].ToString(); // the disk we're trying to find out about
antecedent = antecedent.Replace(#"\", "\\"); // this is just to escape the slashes
string query = "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + antecedent + "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition";
using (ManagementObjectSearcher partitionSearch = new ManagementObjectSearcher(query))
{
foreach (ManagementObject part in partitionSearch.Get())
{
//...pull out the partition information
MessageBox.Show(part["DeviceID"].ToString());
query = "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" + part["DeviceID"] + "'} WHERE AssocClass = Win32_LogicalDiskToPartition";
using (ManagementObjectSearcher logicalpartitionsearch = new ManagementObjectSearcher(query))
foreach (ManagementObject logicalpartition in logicalpartitionsearch.Get())
MessageBox.Show(logicalpartition["DeviceID"].ToString());
}
}
}
the plan of this code is described in this script https://blogs.technet.microsoft.com/heyscriptingguy/2005/05/23/how-can-i-correlate-logical-drives-and-physical-disks/

I'm using WMI in C# to get all the installed softwares but it doesn't show all the softwares only Microsoft ones

public ManagementScope GetScope()
{
try
{
//string classScope="winmgmts:" + "{impersonationLevel=impersonate}!\\" + strComputer + "\\root\\cimv2";
string serverString = #"root\cimv2";
ManagementScope scope = new ManagementScope(serverString);
ConnectionOptions options = new ConnectionOptions
{
Impersonation = ImpersonationLevel.Impersonate,
Authentication = AuthenticationLevel.Connect,
EnablePrivileges = true
};
scope.Options = options;
return scope;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
}
public void InvokeMethodsFunctions1()
{
ManagementScope mScope = GetScope();
mScope.Connect();
if (mScope.IsConnected)
{
ManagementClass processClass =
new ManagementClass(mScope.Path);
ManagementObjectSearcher mos = new ManagementObjectSearcher(mScope, new ObjectQuery("SELECT * FROM Win32_Product"));
//get collection of WMI objects
ManagementObjectCollection queryCollection = mos.Get();
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"Result.txt"))
{
textBox1.Text = "";
//enumerate the collection.
foreach (ManagementObject m in queryCollection)
{
// access properties of the WMI object
string line = " " + m["Name"] + " , InstallDate : " + m["InstallDate"] + " LocalPackage : " + m["LocalPackage"];
Console.WriteLine(line);
file.WriteLine(line);
textBox1.Text += line + "\n";
}
}
}
}
So whats wrong in my Code ?
There is nothing wrong , the Win32_Product WMI class only list the products installed by the Windows Installer (MSI).
I just tested the following, simplified version of your code and I see everything installed on my pc, even services I wrote and installed myself:
var products = new ManagementObjectSearcher(new ObjectQuery("SELECT * FROM Win32_Product"));
var result = products.Get();
foreach (var product in result)
{
Console.WriteLine(product.GetPropertyValue("Name").ToString());
}
Console.ReadLine();
It looks like you are narrowing your query by scope, which is possibly why you aren't seeing everything, try the above and see if you have more luck.

How to identify what device was plugged into the USB slot?

I want to detect when the user plugs in or removes a USB sound card. I've managed to actually catch the event when this happens, but I can't tell what just got plugged in.
I tried an approach based on this question:
string query =
"SELECT * FROM __InstanceCreationEvent " +
"WITHIN 2 "
+ "WHERE TargetInstance ISA 'Win32_PnPEntity'";
var watcher = new ManagementEventWatcher(query);
watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
watcher.Start();
While I get the notifications via the EventArrived event, I have no idea how to determine the actual name of the device that just got plugged in. I've gone through every property and couldn't make heads or tails out of it.
I also tried a different query:
var query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent where EventType = 1 or EventType = 2");
var watcher = new ManagementEventWatcher(query);
watcher.EventArrived += watcher_EventArrived;
watcher.Stopped += watcher_Stopped;
watcher.Query = query;
watcher.Start();
but also to no avail. Is there a way to find the name of the device that got plugged in or removed.
The bottom line is that I'd like to know when a USB sound card is plugged in or removed from the system. It should work on Windows 7 and Vista (though I will settle for Win7 only).
EDIT: Based on the suggestions by the winning submitter, I've created a full solution that wraps all the functionality.
If I use your first code, I can define my event like this:
// define USB class guid (from devguid.h)
static readonly Guid GUID_DEVCLASS_USB = new Guid("{36fc9e60-c465-11cf-8056-444553540000}");
static void watcher_EventArrived(object sender, EventArrivedEventArgs e)
{
ManagementBaseObject instance = (ManagementBaseObject )e.NewEvent["TargetInstance"];
if (new Guid((string)instance["ClassGuid"]) == GUID_DEVCLASS_USB)
{
// we're only interested by USB devices, dump all props
foreach (var property in instance.Properties)
{
Console.WriteLine(property.Name + " = " + property.Value);
}
}
}
And this will dump something like this:
Availability =
Caption = USB Mass Storage Device
ClassGuid = {36fc9e60-c465-11cf-8056-444553540000}
CompatibleID = System.String[]
ConfigManagerErrorCode = 0
ConfigManagerUserConfig = False
CreationClassName = Win32_PnPEntity
Description = USB Mass Storage Device
DeviceID = USB\VID_18A5&PID_0243\07072BE66DD78609
ErrorCleared =
ErrorDescription =
HardwareID = System.String[]
InstallDate =
LastErrorCode =
Manufacturer = Compatible USB storage device
Name = USB Mass Storage Device
PNPDeviceID = USB\VID_18A5&PID_0243\07072BE66DD78609
PowerManagementCapabilities =
PowerManagementSupported =
Service = USBSTOR
Status = OK
StatusInfo =
SystemCreationClassName = Win32_ComputerSystem
SystemName = KILROY_WAS_HERE
This should contain everything you need, including the device ID that you can get with something like instance["DeviceID"].
EDIT 1: Oh is see that it is not a USB storage device but only a USB device. I will look for another solution.
Two links that describe the same problem:
http://hintdesk.com/c-catch-usb-plug-and-unplug-event/
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/37123526-83fa-4e96-a767-715fe225bf28/
if (e.NewEvent.ClassPath.ClassName == "__InstanceCreationEvent")
{
Console.WriteLine("USB was plugged in");
//Get disk letter
foreach (ManagementObject partition in new ManagementObjectSearcher(
"ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + mbo.Properties["DeviceID"].Value
+ "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition").Get())
{
foreach (ManagementObject disk in new ManagementObjectSearcher(
"ASSOCIATORS OF {Win32_DiskPartition.DeviceID='"
+ partition["DeviceID"]
+ "'} WHERE AssocClass = Win32_LogicalDiskToPartition").Get())
{
Console.WriteLine("Disk=" + disk["Name"]);
}
}
}
When I tried #AngryHacker solution, I noticed that the DeviceChangedEventArgs class did not ever get called, though. I removed it and just added Console.WriteLines() in the watcher_eventArrived methods.
Besides the deletion of the DeviceChangedEventArgs, here are my changes:
(at line 46 in EstablishedWatchEvents)
// setup the query to monitor removal
const string qryRemoval = "SELECT *" + "FROM __InstanceDeletionEvent "
+ "WITHIN 2 " + "WHERE TargetInstance ISA 'Win32_PnPEntity' ";
#region Events
private void insertWatcher_EventArrived(object sender, EventArrivedEventArgs e)
{
var mbo = (ManagementBaseObject) e.NewEvent["TargetInstance"];
if (new Guid((string) mbo["ClassGuid"]) == GUID_DEVCLASS_USB)
{
var deviceName = (string) mbo["Name"];
Console.WriteLine(deviceName + " was inserted");
}
}
private void removeWatcher_EventArrived(object sender, EventArrivedEventArgs e)
{
var mbo = (ManagementBaseObject)e.NewEvent["TargetInstance"];
if (new Guid((string)mbo["ClassGuid"]) == GUID_DEVCLASS_USB)
{
var deviceName = (string)mbo["Name"];
Console.WriteLine(deviceName + " was removed");
}
}
#endregion

How to use a thread to completion, then reuse the thread?

I'm building a form and I'm trying to use threading in order to get some results from a WMI query to display in a textbox without having the form freeze up on the user. However, when I use the code below and use Break-All when debugging, the code just sits on getPrinterThread.Join(). I know I must be missing something.
My aim is to get a thread to run the ObtainPrinterPort method to completion, then get a thread to run the InstallPrinterPort method to completion. I have the code below as inline code in another method. The code isn't in a separate class or anything and I don't have a background worker because all of the examples I've seen, up until now, have only confused me.
Here's my admittedly poor thread attempt:
Thread printThread = new Thread(ObtainPrinterPort);
printThread.Start();
while (!printThread.IsAlive) ;
Thread.Sleep(1);
printThread.Join(); // Form sits and does nothing; Break-all reveals this line as statement being executed.
Thread installThread = new Thread(InstallPrinterPort);
installThread.Start();
while (!installThread.IsAlive);
Thread.Sleep(1);
installThread.Join();
Is there a simple way I can get something to work that is safe and will allow me to display the results that occur in the methods as they happen to the user in the textbox? Hopefully there's a way to do this that will allow me to continue to use the instance variables/methods/code I've written in the form class...otherwise, I'll have to re-write a lot of code if I'm going to implement a "DoWork"-type example (where my methods are called from the DoWork method/constructor or the Worker class).
Please keep in mind that my methods need to return text from the thread to a textbox to display results to the user. I have code that I'm assuming will allow me to return the text from the thread if it works, but I just wanted to make sure that any suggestions/help kept this in mind. The code I'm using is below:
public void AppendTextBox(string value)
{
if (InvokeRequired)
{
this.Invoke(new Action<string>(AppendTextBox), new object[] { value });
return;
}
txtResults.Text += value;
}
For what it's worth, here's my ObtainPrinterPort method and the CreateNewConnection method that accompanies it...the InstallPrinterPort method is extremely similar, so posting it won't really reveal much:
private ManagementScope CreateNewConnection(string server, string userID, string password)
{
string serverString = #"\\" + server + #"\root\cimv2";
ManagementScope scope = new ManagementScope(serverString);
try
{
ConnectionOptions options = new ConnectionOptions
{
Username = userID,
Password = password,
Impersonation = ImpersonationLevel.Impersonate,
EnablePrivileges = true
};
scope.Options = options;
scope.Connect();
}
catch (ManagementException err)
{
MessageBox.Show("An error occurred while querying for WMI data: " +
err.Message);
}
catch (System.UnauthorizedAccessException unauthorizedErr)
{
MessageBox.Show("Connection error (user name or password might be incorrect): " + unauthorizedErr.Message);
}
return scope;
}
private void ObtainPrinterPort()
{
string computerName = "";
string userID = "";
string password = "";
string printerQuery = "SELECT * FROM Win32_Printer WHERE Name = ";
string portQuery = "SELECT * FROM Win32_TCPIPPrinterPort WHERE Name = ";
string search = "";
SelectQuery query;
foreach (var s in lstServer)
{
computerName = s.ServerName;
userID = s.UserID;
password = s.Password;
}
ManagementScope scope = CreateNewConnection(computerName, userID, password);
foreach (Printers p in lstPrinters)
{
AppendTextBox("Obtaining printer/port info for " + p.PrinterName + "\r\n");
search = printerQuery + "'" + p.PrinterName + "'";
query = new SelectQuery(search);
try
{
using (var searcher = new ManagementObjectSearcher(scope, query))
{
ManagementObjectCollection printers = searcher.Get();
if (printers.Count > 0)
{
AppendTextBox("\tStoring printer properties for " + p.PrinterName + "\r\n");
foreach (ManagementObject mo in printers)
{
StorePrinterProperties(p, mo);
}
}
else
{
lstPrinterExceptions.Add("Printer: " + p.PrinterName);
AppendTextBox("\t**Printer " + p.PrinterName + " not found**\r\n");
}
}
}
catch (Exception exception)
{
MessageBox.Show("Error: " + exception.Message, "Error",
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
if (!lstPrinterExceptions.Contains("Printer: " + p.PrinterName)
&& !lstPrinterExceptions.Contains("Port: " + p.PortName))
{
search = portQuery + "'" + p.PortName + "'";
query = new SelectQuery(search);
try
{
using (var searcher = new ManagementObjectSearcher(scope, query))
{
ManagementObjectCollection ports = searcher.Get();
if (ports.Count > 0)
{
AppendTextBox("\tStoring port properties for " + p.PortName + " (" + p.PrinterName + ")\r\n");
foreach (ManagementObject mo in ports)
{
StorePortProperties(p, mo);
}
}
else
{
lstPrinterExceptions.Add("Port: " + p.PortName);
AppendTextBox("\t**Port " + p.PortName + " for " + p.PrinterName + " not found**\r\n");
}
}
}
catch (Exception exception)
{
MessageBox.Show("Error: " + exception.Message, "Error",
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
AppendTextBox("\tSuccessfully obtained printer/port info for " + p.PrinterName + "\r\n");
}
}
}
Thanks.
Your problem is that the Invoke calls are blocking waiting for the main thread to DoEvents so they can be processed, but the main thread is blocking in Thread.Join. You have a deadlock.
This is how you run a thread without blocking the UI thread. Thread.Join blocks until the other thread finishes, so here I am blocking only for max 100ms, then calling DoEvents so the form can respond to messages (including processing your Invoke calls from the other thread), then looping until the background thread is complete.
Thread printThread = new Thread(ObtainPrinterPort);
printThread.Start();
while (printThread.IsAlive) {
Application.DoEvents();
printThread.Join(100);
}
Calling DoEvents in a loop like this is a bit hacky, but it will work.
You can also look into BackgroundWorker, which makes the whole thing a lot safer and easier.
A simple example:
var bw = new BackgroundWorker();
bw.DoWork += (worker, args) => {
ObtainPrinterPort();
};
bw.RunWorkerAsync();

Categories