I have two network adapters in my machine. E.g. adapter A and adapter B. The A keeps connected
I want to monitor the connection status of adapter B. I mean, connected or disconnected status.
I tried the System.Net.NetworkInformation.NetworkChange.NetworkAvailabilityChanged
But it doesn't work, since the adapter A connected.
Maybe WMI is helpful, but I don't have any experience about it, also didn't find much useful article.
Could any one help to show me
how to subscribe WMI event of the adapter A connection status in C#
You can use the Win32_NetworkAdapter WMI class and the NetConnectionStatus property with the __InstanceModificationEvent event.
The WQL sentence will look like so
Select * From __InstanceModificationEvent Within 1 Where TargetInstance ISA 'Win32_NetworkAdapter' AND TargetInstance.Name='Network adapter name'
Try this sample
using System;
using System.Collections.Generic;
using System.Management;
using System.Text;
namespace GetWMI_Info
{
public class EventWatcherAsync
{
private void WmiEventHandler(object sender, EventArrivedEventArgs e)
{
Console.WriteLine("TargetInstance.Name : " + ((ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value)["Name"]);
//2 (0x2) Connected
//7 (0x7) Media disconnected
Console.WriteLine("TargetInstance.NetConnectionStatus : " + ((ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value)["NetConnectionStatus"]);
}
public EventWatcherAsync()
{
try
{
string ComputerName = "localhost";
string WmiQuery;
ManagementEventWatcher Watcher;
ManagementScope Scope;
if (!ComputerName.Equals("localhost", StringComparison.OrdinalIgnoreCase))
{
ConnectionOptions Conn = new ConnectionOptions();
Conn.Username = "";
Conn.Password = "";
Conn.Authority = "ntlmdomain:DOMAIN";
Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", ComputerName), Conn);
}
else
Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", ComputerName), null);
Scope.Connect();
WmiQuery ="Select * From __InstanceModificationEvent Within 1 "+
"Where TargetInstance ISA 'Win32_NetworkAdapter' AND TargetInstance.Name='Tarjeta Mini de media altura WLAN Wireless-N DW1501' ";
Watcher = new ManagementEventWatcher(Scope, new EventQuery(WmiQuery));
Watcher.EventArrived += new EventArrivedEventHandler(this.WmiEventHandler);
Watcher.Start();
Console.Read();
Watcher.Stop();
}
catch (Exception e)
{
Console.WriteLine("Exception {0} Trace {1}", e.Message, e.StackTrace);
}
}
public static void Main(string[] args)
{
Console.WriteLine("Listening {0}", "__InstanceModificationEvent");
Console.WriteLine("Press Enter to exit");
EventWatcherAsync eventWatcher = new EventWatcherAsync();
Console.Read();
}
}
}
Related
I wrote 2 winforms as follows
Check the connection of the Ardruino to PC 1 and write the received information to log.txt file
Read selected information in log files and send them to PC 2 (SQL installed)
Note: PC 1 has 2 network cards (network card 1 receives the signals of the Arduino over the range: 192.168.1.2; Network card 2 connects to PC 2 via the range: 110.110.1.2)
How do I get the information I need from PC 1 and transfer them to PC 2 (with SQL installed) with only 1 program
My code Winform received form Arduino:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Data.SqlClient;
namespace TCPIPSeverMutilClient
{
public partial class Form1 : Form
{
const int MAX_CONNECTION = 30;
const int PORT_NUMBER =1989;
int currentconnect = 0;
delegate void SetTextCallback(string text);
static TcpListener listener;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
IPAddress address = IPAddress.Parse(IPText.Text);
listener = new TcpListener(address, PORT_NUMBER);
AddMsg("Creat Sever with IP :"+ IPText.Text);
AddMsg("Waiting for connection...");
button1.Hide();
listener.Start();
for (int i = 0; i < MAX_CONNECTION; i++)
{
// new Thread(DoWork).Start();
Thread aThread = new Thread(DoWork);
aThread.IsBackground = true; //<-- Set the thread to work in background
aThread.Start();
}
}
private void DoWork()
{
while (true)
{
Socket soc = listener.AcceptSocket();
currentconnect = currentconnect + 1;
SetText("Numbers Connection " + currentconnect.ToString());
Console.WriteLine("Connection received from: {0}", soc.RemoteEndPoint);
try
{
var stream = new NetworkStream(soc);
var reader = new StreamReader(stream);
var writer = new StreamWriter(stream);
writer.AutoFlush = true;
//writer.WriteLine("Welcome to Student TCP Server");
// writer.WriteLine("Please enter the student id");
while (true)
{
string id = reader.ReadLine();
SetText(id);
// writer.WriteLine("END");
if (String.IsNullOrEmpty(id))
break; // disconnect
//if (_data.ContainsKey(id))
// writer.WriteLine("Student's name: '{0}'", _data[id]);
else
{
writer.WriteLine("END");
// writer.WriteLine("Can't find name for student id '{0}'", id);
}
}
stream.Close();
}
catch (Exception ex)
{
SetText("Error: " + ex);
}
// Console.WriteLine("Client disconnected: {0}",soc.RemoteEndPoint);
soc.Close();
currentconnect = currentconnect - 1;
SetText("Numbers Connection " + currentconnect.ToString());
}
}
private void SetText(string text)
{
if (this.rtbText.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText); // khởi tạo 1 delegate mới gọi đến SetText
this.Invoke(d, new object[] { text });
}
else
{
this.AddMsg(text);
}
}
private void SaveText(string text)
{
const string textFileName = "Log.txt";
const int insertAtLineNumber = 0;
List<string> fileContent = File.ReadAllLines(textFileName).ToList();
// AddMsg(fileContent.Count.ToString());
//fileContent.InsertRange(insertAtLineNumber, text);
fileContent.Insert(insertAtLineNumber, text);
File.WriteAllLines(textFileName, fileContent);
}
private void AddMsg(string msg)
{
rtbText.Items.Add(DateTime.Now + " : " + msg);
SaveText(DateTime.Now + " : " + msg);
if (rtbText.Items.Count >= 150)
{ rtbText.Items.RemoveAt(0); }
}
}
}
As the Arduino card attached to PC 1 cannot be accessed from the PC 2.
You need to pass the Arduino data to the MSSQL Database. Then Retrieve the data in PC 2 by accessing it from PC 1. You can use this Reference for How to access Database over network
Up to now, when I returned this case I had a solution.
In PC1, there are 2 network cards, you just need to use the Network class to find the IP with the IP with IP in PC2
Instead of reading from the log file I was inspired directly from Arduino returned and transmitted to PC2
string hostname = Dns.GetHostName();
System.Net.IPHostEntry ip = new IPHostEntry();
ip = Dns.GetHostByName(hostname);
foreach (IPAddress listip in ip.AddressList)
{
if (listip.ToString().StartsWith("110."))
{
ipMay = listip.ToString();
macPairIp = GetMacByIP(ipMay);
try
{
//Do work here
}
catch (...)
{}
}
}
I'm trying to enable/disable my PPPoE adapter according to this answer.
It works great with normal adapters but not with PPPoE which throws an error saying :
An error occurred while querying for WMI data: Invalid method Parameter(s)
The adapter name is correct I used WMI Query tool for that purpose but I have no idea what params need to be set. Any help would be much appreciated.
Edit
Here's the code I used:
static void Main(string[] args)
{
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
"SELECT * FROM Win32_NetworkAdapter WHERE Name = 'WAN Miniport (PPPOE)'");
foreach (ManagementObject queryObj in searcher.Get())
{
queryObj.InvokeMethod("Enable", null);
//Console.WriteLine("Name: {0}", queryObj["Name"]);
}
}
catch (ManagementException e)
{
Console.WriteLine("An error occurred while querying for WMI data: " + e.Message);
}
Console.ReadKey();
}
Ok I've found my way around with DotRas here's the code to connect/disconnect PPPoE connection (AKA dial up):
using System;
using System.Linq;
using System.Net;
using DotRas;
namespace Test_Reconnect_PPPoE
{
class Program
{
public static void Main(string[] args)
{
// Connect
using (RasDialer dialer = new RasDialer())
{
dialer.EntryName = "Your Entry (Connection Name)";
dialer.PhoneBookPath = RasPhoneBook.GetPhoneBookPath(RasPhoneBookType.User);
dialer.Credentials = new NetworkCredential("username", "password");
dialer.Dial();
Console.WriteLine("Connected");
}
// Disconnect
RasConnection conn = RasConnection.GetActiveConnections().Where(o => o.EntryName == "Your Entry (Connection Name)").FirstOrDefault();
if (conn != null)
{
conn.HangUp();
Console.WriteLine("Disconnected");
}
Console.ReadKey();
}
}
}
Hope this will help someone.
Sorry if someone just posts a link to the answer, but I was really struggling to google this.
I can't figure out how to detect mobile phones when they're plugged in and then access their storage. The former is just something I don't know where to start looking and the second befuddles me a little because I'm used to accessing storage with a drive letter. The phones I've used (iPhone 4S and a few different Samsung galaxy's and notes) don't have a drive letter. So where would I start?
I use C# but I'm comfortable with the dllimports etc.
I've now done this code from the thread I linked in a comment above, nice and easy to throw into a program.
using System;
using System.Management;
using System.Threading;
namespace USBDeviceTester
{
class Program
{
static void Main(string[] args)
{
Thread myThread = new Thread(new ThreadStart(ThreadWorker));
myThread.Start();
}
public static void ThreadWorker()
{
WqlEventQuery insertQuery = new WqlEventQuery("SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_USBHub'");
ManagementEventWatcher insertWatcher = new ManagementEventWatcher(insertQuery);
insertWatcher.EventArrived += new EventArrivedEventHandler(DeviceInsertedEvent);
insertWatcher.Start();
WqlEventQuery removeQuery = new WqlEventQuery("SELECT * FROM __InstanceDeletionEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_USBHub'");
ManagementEventWatcher removeWatcher = new ManagementEventWatcher(removeQuery);
removeWatcher.EventArrived += new EventArrivedEventHandler(DeviceRemovedEvent);
removeWatcher.Start();
// Do something while waiting for events
System.Threading.Thread.Sleep(20000000);
}
private static void DeviceInsertedEvent(object sender, EventArrivedEventArgs e)
{
Console.WriteLine("");
Console.WriteLine(" --- DEVICE INSERTED ---");
Console.WriteLine("");
ManagementBaseObject instance = (ManagementBaseObject)e.NewEvent["TargetInstance"];
foreach (var property in instance.Properties)
{
Console.WriteLine(property.Name + " = " + property.Value);
}
Console.WriteLine("");
}
static void DeviceRemovedEvent(object sender, EventArrivedEventArgs e)
{
Console.WriteLine("");
Console.WriteLine(" --- DEVICE REMOVED ---");
Console.WriteLine("");
//ManagementBaseObject instance = (ManagementBaseObject)e.NewEvent["TargetInstance"];
//foreach (var property in instance.Properties)
//{
// Console.WriteLine(property.Name + " = " + property.Value);
//}
}
}
}
Which returns information as so:
--- DEVICE REMOVED ---
--- DEVICE INSERTED ---
Availability =
Caption = Apple Mobile Device USB Driver
ClassCode =
ConfigManagerErrorCode = 0
ConfigManagerUserConfig = False
CreationClassName = Win32_USBHub
CurrentAlternateSettings =
CurrentConfigValue =
Description = Apple Mobile Device USB Driver
DeviceID = USB\VID_05AC&PID_12A0\3ABFD2ED02E3982B5F4455FD684716A6D4958A74
ErrorCleared =
ErrorDescription =
GangSwitched =
InstallDate =
LastErrorCode =
Name = Apple Mobile Device USB Driver
NumberOfConfigs =
NumberOfPorts =
PNPDeviceID = USB\VID_05AC&PID_12A0\3ABFD2ED02E3982B5F4455FD684716A6D4958A74
PowerManagementCapabilities =
PowerManagementSupported =
ProtocolCode =
Status = OK
StatusInfo =
SubclassCode =
SystemCreationClassName = Win32_ComputerSystem
SystemName = MyComputerName
USBVersion =
I am working on WMI(Windows Management Instrumentation) in C# and stuck at a point.
I have to create an application using WMI (C#) similar to File System Watcher.
I would like to get notified every time whenever within a particular folder a new file is created or deleted.
MY WQL query is :
SELECT * from _InstanceModificationEvent within 2 where TargetInstance ISA 'CIM_DataFile' and TargetInstance.Drive = 'C:' AND TargetInstance.Path='\\Test'
While running the query using wbemtest , it displays an Error message prompting Invalid Class.
Can someone please help me out regarding same?
In order to detect when a file is created , modified or deleted you must use the __InstanceOperationEvent WMI Class and the using the value of __Class property you can figure out out if the file was modified, deleted o created.
Try this sample
using System;
using System.Collections.Generic;
using System.Management;
using System.Text;
namespace GetWMI_Info
{
public class EventWatcherAsync
{
private void WmiEventHandler(object sender, EventArrivedEventArgs e)
{
// e.NewEvent
string wclass = ((ManagementBaseObject)e.NewEvent).SystemProperties["__Class"].Value.ToString();
string wop = string.Empty;
switch (wclass)
{
case "__InstanceModificationEvent":
wop = "Modified";
break;
case "__InstanceCreationEvent":
wop = "Created";
break;
case "__InstanceDeletionEvent":
wop = "Deleted";
break;
}
string wfilename = ((ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value)["FileName"].ToString();
if (!string.IsNullOrEmpty(((ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value)["Extension"].ToString()))
{
wfilename += "." + ((ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value)["Extension"].ToString();
}
Console.WriteLine(String.Format("The File {0} was {1}", wfilename, wop));
}
public EventWatcherAsync()
{
try
{
string ComputerName = "localhost";
string WmiQuery;
ManagementEventWatcher Watcher;
ManagementScope Scope;
if (!ComputerName.Equals("localhost", StringComparison.OrdinalIgnoreCase))
{
ConnectionOptions Conn = new ConnectionOptions();
Conn.Username = "";
Conn.Password = "";
Conn.Authority = "ntlmdomain:DOMAIN";
Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", ComputerName), Conn);
}
else
Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", ComputerName), null);
Scope.Connect();
//Check for changes in the path C:\Test
WmiQuery = #"Select * From __InstanceOperationEvent Within 1
Where TargetInstance ISA 'CIM_DataFile' and TargetInstance.Drive = 'C:' AND TargetInstance.Path='\\Test\\'";
Watcher = new ManagementEventWatcher(Scope, new EventQuery(WmiQuery));
Watcher.EventArrived += new EventArrivedEventHandler(this.WmiEventHandler);
Watcher.Start();
Console.Read();
Watcher.Stop();
}
catch (Exception e)
{
Console.WriteLine("Exception {0} Trace {1}", e.Message, e.StackTrace);
}
}
public static void Main(string[] args)
{
Console.WriteLine("Listening {0}", "__InstanceOperationEvent");
Console.WriteLine("Press Enter to exit");
EventWatcherAsync eventWatcher = new EventWatcherAsync();
Console.Read();
}
}
}
the goal is like i said in the Topic. I know there are a lot of articles on that specific Problem and i tried all most all of them.
But since non of them worked out for me, I'm now trying to find out why this one just works sometimes and sometimes nothing is happening although many things are printed.
So this is my code which right now should wait for a job to be printed and just tell me about it. Nothing more.
private void StartMonitor()
{
try
{
var opt = new ConnectionOptions { EnablePrivileges = true };
var scope = new ManagementScope("root\\CIMV2", opt);
scope.Connect();
var query = new WqlEventQuery("SELECT * FROM __InstanceOperationEvent WITHIN 60 WHERE TargetInstance ISA \"Win32_PrintJob\"");
var watcher = new ManagementEventWatcher(query);
Console.WriteLine("Ready to receive Printer Job events...");
var pjEvent = watcher.WaitForNextEvent();
if (pjEvent != null) Console.WriteLine("Event occured: " + pjEvent.Properties["PagesPrinted"]);
}
catch (ManagementException e)
{
Console.WriteLine(e.StackTrace);
Console.WriteLine(e.ErrorCode);
Console.WriteLine(e.ErrorInformation);
_Error = e.Message;
throw;
}
}
To get the progress of the printed pages for a particular job, try using a smaller polling interval and use the EventArrivedEventHandler delegate attached to the WMI event for handling the incoming data in a asynchronous way.
Try this sample.
using System;
using System.Collections.Generic;
using System.Management;
using System.Text;
namespace GetWMI_Info
{
public class EventWatcherAsync
{
private void WmiEventHandler(object sender, EventArrivedEventArgs e)
{
Console.WriteLine("TargetInstance.Caption : " + ((ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value)["Caption"]);
Console.WriteLine("TargetInstance.JobStatus : " + ((ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value)["JobStatus"]);
Console.WriteLine("TargetInstance.PagesPrinted : " + ((ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value)["PagesPrinted"]);
Console.WriteLine("TargetInstance.Status : " + ((ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value)["Status"]);
}
public EventWatcherAsync()
{
try
{
string ComputerName = "localhost";
string WmiQuery;
ManagementEventWatcher Watcher;
ManagementScope Scope;
if (!ComputerName.Equals("localhost", StringComparison.OrdinalIgnoreCase))
{
ConnectionOptions Conn = new ConnectionOptions();
Conn.Username = "";
Conn.Password = "";
Conn.Authority = "ntlmdomain:DOMAIN";
Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", ComputerName), Conn);
}
else
Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", ComputerName), null);
Scope.Connect();
WmiQuery ="Select * From __InstanceOperationEvent Within 1 "+
"Where TargetInstance ISA 'Win32_PrintJob' ";
Watcher = new ManagementEventWatcher(Scope, new EventQuery(WmiQuery));
Watcher.EventArrived += new EventArrivedEventHandler(this.WmiEventHandler);
Watcher.Start();
Console.Read();
Watcher.Stop();
}
catch (Exception e)
{
Console.WriteLine("Exception {0} Trace {1}", e.Message, e.StackTrace);
}
}
public static void Main(string[] args)
{
Console.WriteLine("Listening {0}", "__InstanceOperationEvent");
Console.WriteLine("Press Enter to exit");
EventWatcherAsync eventWatcher = new EventWatcherAsync();
Console.Read();
}
}
}
To get the total pages printed by a job I would try monitoring __InstanceDeletionEvents, I believe that at that time Win32_PrintJob.TotalPages should show the printed pages accurately (can't test this right now, sorry). There is also a nice alternative here:
Monitoring a Printer Queue from VB.NET
If you look at the article comments, the author also advises to monitor JOB_WRITTEN events to get the total number of pages printed.
If you are trying to monitor the progress of large print jobs, try monitoring __InstanceModificationEvents once the job is created, something like this:
Select * From __InstanceModificationEvent Within 1
Where TargetInstance Isa "Win32_PrintJob"
And TargetInstance.PagesPrinted > PreviousInstance.PagesPrinted