How to set IP Address of Network adapters? - c#

I have to change IP address very frequently for playing LAN games as well as for using internet at home. I am creating an application in C# which can do it quickly. I have made fields like Adapter Name, IP Address, Subnet, DNS Server Address.
My code which runs on set IP button click is below:
string adapter = comboAdapterName.Text;
string ip = comboIPAddress.Text;
string subnet = comboSubnet.Text;
string dns = comboDNS.Text;
Now I want to use this process method for taking data from those fields and append the string accordingly.
Process p = new Process();
ProcessStartInfo psi = new ProcessStartInfo("netsh", "interface ip set address \"Local Area Connection\" static 192.168.0.10 255.255.255.0 192.168.0.1 1");
p.StartInfo = psi;
p.Start();
But I guess it is not so easy. Because I am unable to edit this without disturbing the format. Also I tried creating a whole new string using many +s which i can place like:
ProcessStartInfo psi = new ProcessStartInfo(mystring);
But still it is too difficult for me. Please suggest an easy way to do this.
==========================================================================
I think I got it:
string ipstring = "netsh interface ip set address " + "\"" + adapter + "\"" + " " + "static" + " " + ip + " " + subnet + " " + dns;

You will need to use the String.Format method.
Example:
string subnet = comboSubnet.Text;
string formatted = string.Format("Subnet is: {0}", subnet);
MessageBox.Show(formatted);
Format that string to look like whatever you want.

You can get the current adapter config with following function:
private static void EthernetInf(out string ip, out string dns, out string nic) // To get current ethernet config
{
ip = "";
dns = "";
nic = "";
foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
{
if (ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
{
foreach (IPAddress dnsAdress in ni.GetIPProperties().DnsAddresses)
{
if (dnsAdress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
dns = dnsAdress.ToString();
}
}
foreach (UnicastIPAddressInformation ips in ni.GetIPProperties().UnicastAddresses)
{
if (ips.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork && !ips.Address.ToString().StartsWith("169")) //to exclude automatic ips
{
ip = ips.Address.ToString();
nic = ni.Name;
}
}
}
}
Following Function is used to set the IP in elevated command prompt:
private void SetIP(Button sender, string arg) //To set IP with elevated cmd prompt
{
try
{
if (sender.Background == Brushes.Cyan )
{
MessageBox.Show("Already Selected...");
return;
}
ProcessStartInfo psi = new ProcessStartInfo("cmd.exe");
psi.UseShellExecute = true;
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.Verb = "runas";
psi.Arguments = arg;
Process.Start(psi);
if (sender == EthStatic || sender == EthDHCP )
{
EthStatic.ClearValue(Button.BackgroundProperty);
EthDHCP.ClearValue(Button.BackgroundProperty);
sender.Background = Brushes.Cyan;
}
if (sender == WIFIStatic || sender == WIFIDhcp)
{
WIFIStatic.ClearValue(Button.BackgroundProperty);
WIFIDhcp.ClearValue(Button.BackgroundProperty);
sender.Background = Brushes.Cyan;
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
This click button code passes the arguments to processstartinfo to set the IP
private void EthStatic_Click(object sender, RoutedEventArgs e)
{
SetIP(EthStatic, "/c netsh interface ip set address \"" + EthName + "\" static " + Properties.Settings.Default.EthIPac + " " + Properties.Settings.Default.Subnet + " " + Properties.Settings.Default.EthDnsac + " & netsh interface ip set dns \"" + EthName + "\" static " + Properties.Settings.Default.EthDnsac);
}
The complete app is available at:
https://github.com/kamran7679/ConfigureIP

Related

How can I get a network's connection name in C#?

I want to judge if the computer running my program is in a certain network.
I have tried the code below
ManagementClass vNetworkAdapter = new ManagementClass("Win32_NetworkAdapter");
ManagementObjectCollection vNetworkAdapters = vNetworkAdapter.GetInstances();
foreach (ManagementObject vNetworkAdapterInfo in vNetworkAdapters)
{
string ID = (string)vNetworkAdapterInfo.Properties["NetConnectionID"].Value;
string Caption = (string)vNetworkAdapterInfo.Properties["Caption"].Value;
string Description = (string)vNetworkAdapterInfo.Properties["Description"].Value;
string SSID = (string)vNetworkAdapterInfo.Properties["DeviceID"].Value;
if (ID != null)
{
if (ID == "以太网")//judge certain type of connection by name, I only considered the wired and wireless connection
{
Console.WriteLine("以太网" + "\n" + Caption + "\n" + Description);
Console.WriteLine(SSID);
}
else if (ID == "WLAN")
{
Console.WriteLine("WLAN" + "\n" + Caption + "\n" + Description);
Console.WriteLine(SSID);
}
}
Console.WriteLine("");
}
It returns With
WLAN
[00000002] Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201NGW)
Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201NGW)
以太网
[00000003] Killer E2500 Gigabit Ethernet Controller
Killer E2500 Gigabit Ethernet Controller
But I not wanting this name, I want to get the name shown when we are connecting to a certain network(known as SSID for wireless connection), What I should do? thanks a lot!

How to verify if remote computer is available?

I'm writing a part of a program that shall copy a batch of files from the current computer to a defined list of computers.
If these computers are not available, the code will hang for a long time trying to access them. Is there any functionallity in C# to check if the machine is available and then skip if it's not?
MFWs = File.ReadAllLines(GuiManager.MyConfigManagerConfig.MachinesList);
foreach (string MFW in MFWs)
{
if (MFW != System.Environment.MachineName)
{
String target = #"\\" + MFW + #"\D\IbSi\config\" + Path.GetFileName(ConfigFile);
String backup = #"\\" + MFW + #"\D\IbSi\userdata\" + Path.GetFileName(ConfigFile);
try
{
File.Copy(source, target, true);
File.Copy(source, backup, true);
}
catch (Exception ex)
{
Manager.SendMessage("Failed to copy " + Path.GetFileName(ConfigFile) + " to " + MFW + "\n" + ex.Message);
}
}
}
You could ping the computer before starting the copy (taken from this answer):
using System.Net.NetworkInformation;
public static bool IsHostAvailable(string nameOrAddress)
{
bool pingable = false;
Ping pinger = new Ping();
try
{
PingReply reply = pinger.Send(nameOrAddress);
pingable = reply.Status == IPStatus.Success;
}
catch (PingException)
{
// Discard PingExceptions and return false;
}
return pingable;
}
As noted in the comments you need to make sure the firewall on the servers is open for pings (ICMP echo requests)

SSH connection remained open after debug error

So i am making an application which can open connections to remote devices and execute different commands. So yesterday before i left work i was debugging when i got an error. But as my application ignored it and proceeded and having not enough time to fix it immedietly i decided to do it today. When i wanted to make connection with my program again it said it couldn't authenticate (note* the parameters did not change).
So i did some checks to determine the problem, after logging in on the server and running netstat i found out that there was an active connection to port 22, which originated from my application.
Somehow the connection did not show up in my SSH manager until i rebooted it TWICE.
So to prevent things like this in a production environment, how do i prevent things like this.
my Program.cs
class Program
{
static void Main(string[] args)
{
var ip="";
var port=0;
var user="";
var pwd="";
var cmdCommand="";
ConnectionInfo ConnNfo;
ExecuteCommand exec = new ExecuteCommand();
SSHConnection sshConn = new SSHConnection();
if (args.Length > 0)
{
ip = args[0];
port = Convert.ToInt32(args[1]);
user = args[2];
pwd = args[3];
cmdCommand = args[4];
ConnNfo = sshConn.makeSSHConnection(ip, port, user, pwd);
exec.executeCMDbySSH(ConnNfo, cmdCommand);
}
else {
try
{
XMLParser parser = new XMLParser();
List<List<string>> configVars = parser.createReader("C:\\Users\\myusername\\Desktop\\config.xml");
Console.WriteLine("this is from program.cs");
//iterate through array
for (int i = 0; i < configVars[0].Count; i++)
{
if ((configVars[0][i].ToString() == "device" && configVars[1][i].ToString() == "device") && (configVars[0][i + 6].ToString() == "device" && configVars[1][i + 6].ToString() == "no value"))
{
string ipAdress = configVars[1][i + 1].ToString();
int portNum = Convert.ToInt32(configVars[1][i + 2]);
string username = configVars[1][i + 3].ToString();
string passwd = configVars[1][i + 4].ToString();
string command = configVars[1][i + 5].ToString();
Console.WriteLine("making connection with:");
Console.WriteLine(ipAdress + " " + portNum + " " + username + " " + passwd + " " + command);
ConnNfo = sshConn.makeSSHConnection(ipAdress, portNum, username, passwd);
Console.WriteLine("executing command: ");
exec.executeCMDbySSH(ConnNfo, command);
}
}
}
catch (Exception e) { Console.WriteLine("Error occurred: " + e); }
}
Console.WriteLine("press a key to exit");
Console.ReadKey();
}
}
my executeCommand class:
public class ExecuteCommand
{
public ExecuteCommand()
{
}
public void executeCMDbySSH(ConnectionInfo ConnNfo, string cmdCommand )
{
try
{
using (var sshclient = new SshClient(ConnNfo))
{
//the error appeared here at sshclient.Connect();
sshclient.Connect();
using (var cmd = sshclient.CreateCommand(cmdCommand))
{
cmd.Execute();
Console.WriteLine("Command>" + cmd.CommandText);
Console.WriteLine(cmd.Result);
Console.WriteLine("Return Value = {0}", cmd.ExitStatus);
}
sshclient.Disconnect();
}
}
catch (Exception e) { Console.WriteLine("Error occurred: " + e); }
}
}
and my class where i make conenction:
public class SSHConnection
{
public SSHConnection() { }
public ConnectionInfo makeSSHConnection(string ipAdress, int port, string user, string pwd)
{
ConnectionInfo ConnNfo = new ConnectionInfo(ipAdress, port, user,
new AuthenticationMethod[]{
// Pasword based Authentication
new PasswordAuthenticationMethod(user,pwd),
}
);
return ConnNfo;
}
}
Note* i have not included my XMLParser class because it is not relevant to the question, nor does it have any connections regarding SSH in general.
EDIT
i found out i had compiled the application and it was running in the commandline. Turns out there is no error with the code

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 DirectoryEntry("IIS://Localhost/W3SVC") to change IP address with several host header entries

I'm trying to programmatically change the IP of a website running on Server 2003.
When I run the following code, the site binding itself gets changed, but there are other host header values that need to be changed. How do I change those?
protected static void ChangeServerIP(string old_ip, string new_ip)
{
int siteChangedCount = 0;
DirectoryEntry entry = new DirectoryEntry("IIS://LocalHost/W3SVC");
if (entry != null)
{
foreach (DirectoryEntry site in entry.Children)
{
if (site.SchemaClassName == "IIsWebServer")
{
Console.WriteLine("Server Binding: " + site.Properties["ServerBindings"][0].ToString());
if (site.Properties["ServerBindings"][0].ToString().Contains(old_ip))
{
string ServerComment = site.Properties["ServerComment"].Value.ToString();
Console.WriteLine("Changing " + ServerComment + "'s IP address from " + old_ip + " to " + new_ip);
site.Properties["ServerBindings"].Value = site.Properties["ServerBindings"][0].ToString().Replace(old_ip, new_ip);
site.CommitChanges();
siteChangedCount++;
Console.WriteLine("New IP address bound to site: " + ServerComment + " IP: " + site.Properties["ServerBindings"].Value.ToString());
}
}
}
}
}
Did you try assigning the value to the first item in the PropertyValueCollection?
site.Properties["ServerBindings"][0].Value = site.Properties["ServerBindings"][0].ToString().Replace(old_ip, new_ip);

Categories