i have a windows application which insert client machine's default printer to database on application launch. It works perfectly in my solution. I use the following code to save this.
string GetDefaultPrinter()
{
string defaultprinter = "";
try
{
PrinterSettings settings = new PrinterSettings();
foreach (string printer in PrinterSettings.InstalledPrinters)
{
settings.PrinterName = printer;
if (settings.IsDefaultPrinter)
{
defaultprinter = printer;
string[] array_printer= defaultprinter.Split('\\');
defaultprinter= array_printer[3].ToString();
string query = string.Format("SELECT * from Win32_Printer WHERE Name LIKE '%{0}'", defaultprinter);
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
ManagementObjectCollection coll = searcher.Get();
foreach (ManagementObject localprinter in coll)
{
foreach (PropertyData property in localprinter.Properties)
{
// Console.WriteLine(string.Format("{0}: {1}", property.Name, property.Value));
//MessageBox.Show(property.Name+"-"+ property.Value);
if (property.Name == "ShareName")
{
defaultprinter = property.Value.ToString().Trim();
}
}
}
}
}
}
catch (Exception ex)
{
MessageBox.Show("defaltprinter- "+defaultprinter+"-" + ex.Message);
}
return defaultprinter;
}<br>
If I host this application in citrix, then what should I do to perform the same function?
regards,
Sivajith S.
Related
I'm trying to identify if a certain service on a remote PC is running or not and identify its start up type.
Using ServiceController I can successfully see the expected service on the remote machine but when switching to use WMI to drill deeper this service no longer appears.
Heres my code:
public static void Main()
{
var ctl = ServiceController.GetServices("[Name]");
List<string> namelist = new List<string>();
foreach (var x in ctl)
{
if (x.DisplayName == "NHS Card Checker")
{
Console.WriteLine(string.Format("NHS Card checker found on MPC - Status: {0}", x.Status));
ConnectionOptions options = new ConnectionOptions();
options.Impersonation = System.Management.ImpersonationLevel.Impersonate;
ManagementScope scope = new ManagementScope(#"[Name]\root\cimv2");
scope.Connect();
string wmiQuery = string.Format("Select * from Win32_Service", x.DisplayName);
ManagementObjectSearcher wmi = new ManagementObjectSearcher(wmiQuery);
ManagementObjectCollection coll = wmi.Get();
foreach (var service in coll)
{
Console.WriteLine(string.Format("{0} - {1}", service["Name"].ToString(), service["StartMode"].ToString()) );
}
}
}
Console.ReadKey();
}
Looks good for the most part. I would lead the scope with "\\" before your machine name. Also, if you are just looking for one specific service, add a WHERE clause to your query.
public static void Main()
{
string MachineName = "[Name]";
var ctl = ServiceController.GetServices(MachineName);
List<string> namelist = new List<string>();
foreach (var x in ctl)
{
if (x.DisplayName == "NHS Card Checker")
{
Console.WriteLine(string.Format("NHS Card checker found on MPC - Status: {0}", x.Status));
ConnectionOptions options = new ConnectionOptions();
options.Impersonation = System.Management.ImpersonationLevel.Impersonate;
ManagementScope scope = new ManagementScope(String.Format(#"\\{0}\root\cimv2", MachineName));
scope.Connect();
string wmiQuery = string.Format("Select * from Win32_Service WHERE DisplayName='{0}'" , x.DisplayName);
ManagementObjectSearcher wmi = new ManagementObjectSearcher(wmiQuery);
ManagementObjectCollection coll = wmi.Get();
foreach (var service in coll)
{
Console.WriteLine(string.Format("{0} - {1}", service["Name"].ToString(), service["StartMode"].ToString()));
}
}
}
Console.ReadKey();
}
or maybe simplify it to only use WMI like...
string MachineName = "[Name]";
string TargetService = "NHS Card Checker";
{
ConnectionOptions options = new ConnectionOptions();
options.Impersonation = System.Management.ImpersonationLevel.Impersonate;
ManagementScope scope = new ManagementScope(String.Format(#"\\{0}\root\cimv2", MachineName));
scope.Connect();
string wmiQuery = String.Format("Select * from Win32_Service WHERE DisplayName='{0}'", TargetService);
ManagementObjectSearcher wmi = new ManagementObjectSearcher(wmiQuery);
ManagementObjectCollection coll = wmi.Get();
if (coll.Count > 0)
{
foreach (var service in coll)
{
Console.WriteLine(string.Format("NHS Card checker found on MPC - Status: {0}", service["Status"].ToString()));
Console.WriteLine(string.Format("{0} - {1}", service["Name"].ToString(), service["StartMode"].ToString()));
}
}
else
{
Console.WriteLine(string.Format("{0} Service was not found", TargetService));
}
}
}
Also, in newer implementations of C# you can use an easier variance of string interpolation. Instead of...
string.format("{0} is your value", VariableName");
you can use
$"{VariableName} is your value";
I want to change NETWORK CONFIGURATION programmatically. Everything is working fine, only IP of DNS doesn't want to change, it stays empty.
I use next code to change configuration:
public void setDNS(string NIC, string DNS)
{
ManagementClass objMC = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection objMOC = objMC.GetInstances();
foreach (ManagementObject objMO in objMOC)
{
if ((bool)objMO["IPEnabled"])
{
// if you are using the System.Net.NetworkInformation.NetworkInterface you'll need to change this line to if (objMO["Caption"].ToString().Contains(NIC)) and pass in the Description property instead of the name
//if (objMO["Caption"].Equals(NIC))
if (objMO["Caption"].ToString().Contains(NIC))
{
try
{
ManagementBaseObject newDNS = objMO.GetMethodParameters("SetDNSServerSearchOrder");
newDNS["DNSServerSearchOrder"] = DNS.Split('.');
ManagementBaseObject setDNS = objMO.InvokeMethod("SetDNSServerSearchOrder", newDNS, null);
}
catch (Exception)
{
throw;
}
}
}
}
}
If you only have one DNS IP address, you need assign the value as
newDNS["DNSServerSearchOrder"] = new string[]{DNS};
If you have two DNS IP addesses and they are separated by ';', you need assign the value as
newDNS["DNSServerSearchOrder"] = DNS.Split(';');
The input value must be a string array.
I'm looking for a way to get the users that are logged in on a remote machine. I would love to know if they are logged on localy or remotely, but most of all I MUST know their status.
I saw some answers on the net that are written in VB, but I need it in c#.
the solution given in markdmak answer here is looking like a good start, but it's in VB and it looks for remote sessions only.
I have this piece of code, which can be a start, but I would like to couple the LogonId to a username and to see its status:
string fqdn = ""; // set!!!
ConnectionOptions options = new ConnectionOptions();
options.EnablePrivileges = true;
// To connect to the remote computer using a different account, specify these values:
// these are needed in dev environment
options.Username = ConfigurationManager.AppSettings["KerberosImpersonationUser"];
options.Password = ConfigurationManager.AppSettings["KerberosImpersonationPassword"];
options.Authority = "ntlmdomain:" + ConfigurationManager.AppSettings["KerberosImpersonationDomain"];
ManagementScope scope = new ManagementScope("\\\\" + fqdn + "\\root\\CIMV2", options);
try
{
scope.Connect();
}
catch (Exception ex)
{
if (ex.Message.StartsWith("The RPC server is unavailable"))
{
// The Remote Procedure Call server is unavailable
// cannot check for logged on users
return false;
}
else
{
throw ex;
}
}
SelectQuery query = new SelectQuery("Select * from Win32_LogonSession");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
ManagementObjectCollection results = searcher.Get();
bool returnVal = false;
foreach (ManagementObject os in results)
{
try
{
if (os.GetPropertyValue("LogonId").ToString() != null && os.GetPropertyValue("LogonId").ToString() != "")
{
returnVal = true;
}
}
catch (NullReferenceException)
{
continue;
}
}
return returnVal;
}
What I really need and can't find, is a way of getting ALL users on a remote machine AND their status, meaning: Active, Disconnected, Logged-off, etc.
You can use the Win32_LogonSession WMI class filtering for the LogonType property with the value 2 (Interactive)
Try this sample
using System;
using System.Collections.Generic;
using System.Management;
using System.Text;
namespace GetWMI_Info
{
class Program
{
static void Main(string[] args)
{
try
{
string ComputerName = "remote-machine";
ManagementScope Scope;
if (!ComputerName.Equals("localhost", StringComparison.OrdinalIgnoreCase))
{
ConnectionOptions Conn = new ConnectionOptions();
Conn.Username = "username";
Conn.Password = "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();
ObjectQuery Query = new ObjectQuery("SELECT LogonId FROM Win32_LogonSession Where LogonType=2");
ManagementObjectSearcher Searcher = new ManagementObjectSearcher(Scope, Query);
foreach (ManagementObject WmiObject in Searcher.Get())
{
Console.WriteLine("{0,-35} {1,-40}", "LogonId", WmiObject["LogonId"]);// String
ObjectQuery LQuery = new ObjectQuery("Associators of {Win32_LogonSession.LogonId=" + WmiObject["LogonId"] + "} Where AssocClass=Win32_LoggedOnUser Role=Dependent");
ManagementObjectSearcher LSearcher = new ManagementObjectSearcher(Scope, LQuery);
foreach (ManagementObject LWmiObject in LSearcher.Get())
{
Console.WriteLine("{0,-35} {1,-40}", "Name", LWmiObject["Name"]);
}
}
}
catch (Exception e)
{
Console.WriteLine(String.Format("Exception {0} Trace {1}", e.Message, e.StackTrace));
}
Console.WriteLine("Press Enter to exit");
Console.Read();
}
}
}
#RRUZ got me started but the Associators query did not work on remote machine with a lot of Win32_LoggedOnUser objects (don't know why). No results were returned.
I also needed remote Desktop sessions so I used LogonType "10" sessions and my ConnectionOptions were differents
I replaced the Associators query with WmiObject.GetRelationships("Win32_LoggedOnUser") and the speed increases by a lot and results were there.
private void btnUnleash_Click(object sender, EventArgs e)
{
string serverName = "serverName";
foreach (var user in GetLoggedUser(serverName))
{
dataGridView1.Rows.Add(serverName, user);
}
}
private List<string> GetLoggedUser(string machineName)
{
List<string> users = new List<string>();
try
{
var scope = GetManagementScope(machineName);
scope.Connect();
var Query = new SelectQuery("SELECT LogonId FROM Win32_LogonSession Where LogonType=10");
var Searcher = new ManagementObjectSearcher(scope, Query);
var regName = new Regex(#"(?<=Name="").*(?="")");
foreach (ManagementObject WmiObject in Searcher.Get())
{
foreach (ManagementObject LWmiObject in WmiObject.GetRelationships("Win32_LoggedOnUser"))
{
users.Add(regName.Match(LWmiObject["Antecedent"].ToString()).Value);
}
}
}
catch (Exception ex)
{
users.Add(ex.Message);
}
return users;
}
private static ManagementScope GetManagementScope(string machineName)
{
ManagementScope Scope;
if (machineName.Equals("localhost", StringComparison.OrdinalIgnoreCase))
Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", "."), GetConnectionOptions());
else
{
Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", machineName), GetConnectionOptions());
}
return Scope;
}
private static ConnectionOptions GetConnectionOptions()
{
var connection = new ConnectionOptions
{
EnablePrivileges = true,
Authentication = AuthenticationLevel.PacketPrivacy,
Impersonation = ImpersonationLevel.Impersonate,
};
return connection;
}
I need to return the DeviceID of the System Reserved partition. I should be able to do this with the Win32_Volume class by first getting the Label property, and if it matches "System Reserved" then get the DeviceID property. The following code crashes with a null reference exception:
static void Main(string[] args)
{
ManagementObjectSearcher ms = new ManagementObjectSearcher("Select * From Win32_Volume");
foreach (ManagementObject mo in ms.Get())
{
if (mo["Label"].ToString() == "System Reserved")
{
Console.WriteLine(mo["DeviceID"].ToString());
}
}
Console.Read();
}
Here it is for anyone that needs to do this:
string sysGuid = "";
try
{
ManagementObjectSearcher ms = new ManagementObjectSearcher("SELECT * FROM Win32_Volume");
foreach (ManagementObject mo in ms.Get())
{
if (mo["Label"].ToString() == "System Reserved")
{
sysGuid = mo["DeviceID"].ToString();
break;
}
}
}
catch (Exception) {}
I want to save my network adapter configuration and then to restore it on another computer. I use WMI to get my network configurations and i save it to the .txt file :
using (TextWriter tw = new StreamWriter(#"D:\\NetworkConfiguration.txt"))
{
if (tw != null)
{
ManagementClass objMC = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection objMOC = objMC.GetInstances();
foreach (ManagementObject objMO in objMOC)
{
if (!(bool)objMO["ipEnabled"])
continue;
string[] ipaddresses = (string[])objMO["IPAddress"];
string[] subnets = (string[])objMO["IPSubnet"];
string[] gateways = (string[])objMO["DefaultIPGateway"];
tw.WriteLine("IpAdresses");
foreach (string sIP in ipaddresses)
tw.WriteLine(sIP);
tw.WriteLine("IpSubnets");
foreach (string sNet in subnets)
tw.WriteLine(sNet);
tw.WriteLine("Gateways");
foreach (string sGate in gateways)
tw.WriteLine(sGate);
// close the stream
tw.Close();
}
}
}
and then , when i want to set tcp/ip settings on another computer , i read the file's information :
using (TextReader tr = new StreamReader(#"D:\\NetworkConfiguration.txt"))
{
List<string> ipAddrr = new List<string>();
List<string> ipSubnet = new List<string>();
List<string> Gateway = new List<string>();
string line = tr.ReadLine();
while (line != null)
{
if (line.Equals("IpAdresses"))
{
ipAddrr.Add(tr.ReadLine());
ipAddrr.Add(tr.ReadLine());
}
if (line.Equals("IpSubnets"))
{
ipSubnet.Add(tr.ReadLine());
ipSubnet.Add(tr.ReadLine());
}
if (line.Equals("Gateways"))
{
Gateway.Add(tr.ReadLine());
}
line = tr.ReadLine();
}
setIP(ipAddrr.ToArray(), ipSubnet.ToArray(), Gateway.ToArray());
}
and set the new setting :
public void setIP(string[] IPAddress, string[] SubnetMask, string[] Gateway)
{
ManagementClass objMC = new ManagementClass(
"Win32_NetworkAdapterConfiguration");
ManagementObjectCollection objMOC = objMC.GetInstances();
foreach (ManagementObject objMO in objMOC)
{
if (!(bool)objMO["IPEnabled"])
continue;
try
{
ManagementBaseObject objNewIP = null;
ManagementBaseObject objSetIP = null;
ManagementBaseObject objNewGate = null;
objNewIP = objMO.GetMethodParameters("EnableStatic");
objNewGate = objMO.GetMethodParameters("SetGateways");
//Set DefaultGateway
objNewGate["DefaultIPGateway"] = Gateway ;
objNewGate["GatewayCostMetric"] = new int[] { 1 };
//Set IPAddress and Subnet Mask
objNewIP["IPAddress"] = IPAddress;
objNewIP["SubnetMask"] = SubnetMask;
objSetIP = objMO.InvokeMethod("EnableStatic", objNewIP, null);
objSetIP = objMO.InvokeMethod("SetGateways", objNewGate, null);
MessageBox.Show(
"Updated IPAddress, SubnetMask and Default Gateway!");
}
catch (Exception ex)
{
MessageBox.Show("Unable to Set IP : " + ex.Message);
}
}
}
but the problem is that when i check my tcp/ip configuration , it never changes.....
i dont understand how to get it work....
Take a look at this question - different method but should work ok.