Printers visible to exe not visible to web app? - c#

Solved - thanks to Steve. The problem was that the App Pool I used was using the default App Pool Identity, which doesn't have sufficient privileges. Changing to an App Pool that used an account with sufficient privileges fixed the problem.
I have a simple C# class to get a list of available printers. When called from within a simple Console app, it returns the complete list of locally defined printers (9 printers). When called from the code behind in an aspx web app, it only returns the default printer. The web app is installed and runs as a user that is a local administrator on the server, and all printers are defined within that user's profile.
Note - I remote desktop to the server and run the console exe app there and it shows all the printers. I am trying to get a list of all the printers defined on the server.
Is there some security issue that I am missing?
Class code:
using System.Management;
/// <summary>
/// Returns a list of printers available on the current system.
/// </summary>
public static class PrinterList
{
public class Printer
{
public string name { get; set; }
public string server { get; set; }
public string location { get; set; }
public string portname { get; set; }
public string sharename { get; set; }
}
public static Printer[] GetInstalledPrinterList()
{
Printer[] printers = new Printer[0];
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * from Win32_Printer");
ManagementObjectCollection coll = searcher.Get();
foreach (ManagementObject printer in coll)
{
string name = printer.GetPropertyValue("Name").ToString();
if ((!name.ToLower().Contains("send to onenote")) &&
(!name.ToLower().Contains("xps document writer")) &&
(!name.ToLower().Contains("print to pdf")) &&
(!name.ToLower().Contains(" fax")) &&
(!name.ToLower().Equals("fax")))
{
string server = "";
if (printer.GetPropertyValue("ServerName") != null)
server = printer.GetPropertyValue("ServerName").ToString();
string location = "";
if (printer.GetPropertyValue("Location") != null)
location = printer.GetPropertyValue("Location").ToString();
string portname = "";
if (printer.GetPropertyValue("PortName") != null)
portname = printer.GetPropertyValue("PortName").ToString();
string sharename = "";
if (printer.GetPropertyValue("ShareName") != null)
sharename = printer.GetPropertyValue("ShareName").ToString();
Printer newPrinter = new Printer();
newPrinter.name = name;
newPrinter.server = server;
newPrinter.location = location;
newPrinter.portname = portname;
newPrinter.sharename = sharename;
Printer[] newlist = new Printer[printers.Length + 1];
for (int i = 0;i < printers.Length; i++)
{
newlist[i] = printers[i];
}
newlist[printers.Length] = newPrinter;
printers = newlist;
}
}
return printers;
}
}

Your asp.net c# code runs on your server not on client's computer. This is really important fact to remember.
By calling get printers on asp.net you are basically getting the available printers connected to your server not the ones from client.
Edit: Turns out that you were using the default account for the app pool. By using an account with admin right for the app pool solves the problem.

Related

How to get connected web site ip adress from browser?

im trying to detect which website user connected to..
I tried to get tcp connections and i parsed them for example i tried to detect facebook. But when i logout and close facebook its still displaying 31.13.93.3 (ip of facebook)
Here is my codes..
public partial class Form1 : Form
{
static string faceIP = "31.13.93.3";
static string _targetIP,_targetPORT,_connectedWebSiteIP,_connectedWebSitePORT = string.Empty;
static string[] splitted = null;
public Form1()
{
/* 127.0.0.1:5037:127.0.0.1:49569
* First = 127.0.0.1
* Second = 5037
* Third = 127.0.01
* Fourth = 49569
*/
InitializeComponent();
this.Name = "Active Tcp Connections";
if (findFacebookIP())
{
MessageBox.Show("You opened or connected to facebook page!");
}
}
public static bool findFacebookIP(){
IPGlobalProperties properties = IPGlobalProperties.GetIPGlobalProperties();
TcpConnectionInformation[] connections = properties.GetActiveTcpConnections();
foreach (TcpConnectionInformation c in connections)
{
string tcpCon = string.Format("{0}:{1}", c.LocalEndPoint.ToString(), c.RemoteEndPoint.ToString());
splitted = tcpCon.Split(':');
_targetIP = splitted[0]; // Main Machine ip adress / local ip address (First)
_targetPORT = splitted[1]; // Main machine port number (Second)
_connectedWebSiteIP = splitted[2]; // (Third)
_connectedWebSitePORT = splitted[3]; // (Fourth)
if (_connectedWebSiteIP == faceIP)
{
return true;
}
}
return false;
}
// face ip = 31.13.93.3
}
Also im need to run it background all time beacuse this method is working for just opening.. you can see i wrote it in Form1() constructor method.
Thank you for your help.
Check using TcpState:
foreach (TcpConnectionInformation c in connections)
{
//------------rest of your code
if(c.State == TcpState.Closed)
return false;
//------------rest of your code
}
And for running in background use BackgroundWorker.

Threading issue while printing pdf through c#.net code?

I am trying to print pdf from windows application in my project with iTextSharp dll..
But,The methods I have used till now doesn't seems to be reliable.(Sometimes it work and sometime it doesn't)
I am combining the whole process in a Process class and writing the followin code.
printProcess = new Process[noOfCopies];
// Print number of copies specified in configuration file
for (int counter = 0; counter < noOfCopies; counter++)
{
printProcess[counter] = new Process();
// Set the process information
printProcess[counter].StartInfo = new ProcessStartInfo()
{
CreateNoWindow = true,
Verb = "Print",
FileName = pdfFilePath,
ErrorDialog = false,
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = true,
};
// Start the printing process and wait for exit for 7 seconds
printProcess[counter].Start();
// printProcess[counter].WaitForInputIdle(waitTimeForPrintOut);
printProcess[counter].WaitForExit(waitTimeForPrintOut); //<--**This is line for discussion**
if (!printProcess[counter].HasExited)
{
printProcess[counter].Kill();
}
}
// Delete the file before showing any message for security reason
File.Delete(pdfFilePath);
The problem is that if,no pdf is open then the process works fine...(It prints well).But if any pdf is open then WaitForExit(..) method just doesn't waits for the process to exit..and hence the process runs too fast and as I am deleting the file after print it gives error if counter(no of times..) for printing report is more than once..
I have also used Timer to slow the process but it just doesn't works.I don't know why.
Used Sleep command too..but it makes main thread to go to sleep and hence doesn't suits me either.
Please suggest me some really reliable way to do so..:)
I do not know what kind of application you are trying to print from but a real easy way to print documents or pdfs is to simply copy the file to the printer queue and it will handle everything for you. Very reliable. Just have to have adobe reader installed on the machine printing and the correct driver for the printer. Example code:
var printer = PrinterHelper.GetAllPrinters().FirstOrDefault(p => p.Default);
PrinterHelper.SendFileToPrinter("C:\\Users\\Public\\Documents\\Form - Career Advancement Request.pdf", printer.Name);
Printer Helper code:
public static class PrinterHelper
{
public class PrinterSettings
{
public string Name { get; set; }
public string ServerName { get; set; }
public string DeviceId { get; set; }
public string ShareName { get; set; }
public string Comment { get; set; }
public bool Default { get; set; }
}
/// <summary>
/// Sends the file to printer.
/// </summary>
/// <param name="filePathAndName">Name of the file path and Name of File.</param>
/// <param name="printerName">Name of the printer with Path. E.I. \\PRINT2.company.net\P14401</param>
public static void SendFileToPrinter(string filePathAndName, string printerName)
{
FileInfo file = new FileInfo(filePathAndName);
file.CopyTo(printerName);
}
/// <summary>
/// Gets all printers that have drivers installed on the calling machine.
/// </summary>
/// <returns></returns>
public static List<PrinterSettings> GetAllPrinters()
{
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_Printer");
ManagementObjectSearcher mos = new ManagementObjectSearcher(query);
List<PrinterSettings> printers = new List<PrinterSettings>();
foreach (ManagementObject mo in mos.Get())
{
PrinterSettings printer = new PrinterSettings();
foreach (PropertyData property in mo.Properties)
{
if (property.Name == "Name")
printer.Name = property.Value == null ? "" : property.Value.ToString();
if (property.Name == "ServerName")
printer.ServerName = property.Value == null ? "" : property.Value.ToString();
if (property.Name == "DeviceId")
printer.DeviceId = property.Value == null ? "" : property.Value.ToString();
if (property.Name == "ShareName")
printer.ShareName = property.Value == null ? "" : property.Value.ToString();
if (property.Name == "Comment")
printer.Comment = property.Value == null ? "" : property.Value.ToString();
if (property.Name == "Default")
printer.Default = (bool)property.Value;
}
printers.Add(printer);
}
return printers;
}
}
Try this, you need .net 4 or above. And System.Threading.Tasks
printProcess = new Process[noOfCopies];
// Print number of copies specified in configuration file
Parallel.For(0, noOfCopies, i =>
{
printProcess[i] = new Process();
// Set the process information
printProcess[i].StartInfo = new ProcessStartInfo()
{
CreateNoWindow = true,
Verb = "Print",
FileName = pdfFilePath,
ErrorDialog = false,
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = true,
};
// Start the printing process and wait for exit for 7 seconds
printProcess[i].Start();
// printProcess[counter].WaitForInputIdle(waitTimeForPrintOut);
printProcess[counter].WaitForExit(waitTimeForPrintOut); //<--**This is line for discussion**
if(!printProcess[i].HasExited)
{
printProcess[i].Kill();
}
});
// Delete the file before showing any message for security reason
File.Delete(pdfFilePath);

Find Hard Disk Serial number from Remote SQL Server Installed Hard disk

I have a C#.net Windows form Application with SQL Server. My application use in Multiple user by local Network. Now I need to find Hard disk Serial Number which hard disk installed sql server (Note: By Using C#.net Application Data source ).
How can i find Hard disk Serial number throw by application data source?
This might be useful
using System;
using System.Management;
using System.Collections;
namespace WmiControl
{
public class WMI
{
public bool GetDiskSerial(string Computername)
{
try
{
ManagementScope scope = new ManagementScope(#"\\" + Computername + #"\root\cimv2");
scope.Connect();
ArrayList hdCollection;
ManagementObjectSearcher searcher;
if (GetDiskDrive(scope, out hdCollection, out searcher) || GetDiskSerial(scope, hdCollection, ref searcher))
return true;
else
return false;
}
catch (ManagementException)
{
return false;
}
}
private bool GetDiskSerial(ManagementScope scope, ArrayList hdCollection, ref ManagementObjectSearcher searcher)
{
try
{
ObjectQuery query1 = new ObjectQuery("SELECT * FROM Win32_PhysicalMedia");
searcher = new ManagementObjectSearcher(scope, query1);
int i = 0;
string sDiskSerial = "";
foreach (ManagementObject wmi_HD in searcher.Get())
{
// get the hard drive from collection
// using index
if (i < hdCollection.Count)
{
HardDrive hd = (HardDrive)hdCollection[i];
if (wmi_HD["SerialNumber"] == null)
hd.SerialNo = "";
else
hd.SerialNo = wmi_HD["SerialNumber"].ToString();
}
++i;
}
foreach (HardDrive hd in hdCollection)
{
if (!String.IsNullOrEmpty(hd.SerialNo))
{
sDiskSerial = hd.SerialNo;
break;
}
}
return true;
}
catch (Exception)
{
return false;
}
}
private bool GetDiskDrive(ManagementScope scope, out ArrayList hdCollection, out ManagementObjectSearcher searcher)
{
try
{
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_DiskDrive");
hdCollection = new ArrayList();
searcher = new ManagementObjectSearcher(scope, query);
foreach (ManagementObject wmi_HD in searcher.Get())
{
HardDrive hd = new HardDrive();
hd.Model = wmi_HD["Model"].ToString();
hd.Type = wmi_HD["InterfaceType"].ToString();
hdCollection.Add(hd);
return true;
}
return true;
}
catch (Exception)
{
hdCollection = null;
searcher = null;
return false;
}
}
}
class HardDrive
{
private string model = null;
private string type = null;
private string serialNo = null;
public string Model
{
get { return model; }
set { model = value; }
}
public string Type
{
get { return type; }
set { type = value; }
}
public string SerialNo
{
get { return serialNo; }
set { serialNo = value; }
}
}
}
See here for more info
You might want also to study CLR
You'll need to resort to WMI. With the proper privileges on the SQL Server machine, you can get the serial number of the hard-drives on it. See here for an example on retrieving the hard-disk's serial number using WMI.
You'll need to figure out which disk holds SQL Server and how to access the SQL Server machine on your own.
You have to do it in 3 stages:
The connection string of the data source gives you the name of the machine on which SQL Server is installed
You must then query the machine to find out the drive which drive SQL Server is installed on
You can then use the code supplied by others here to get the serial number

How to get machine account from which the user login to my application?

How to get the user machine account from which he access the application in the case of Form authentication .
I use the following method but it doesn't get the required data:
protected string[] TrackUser()
{
System.Web.HttpContext context = System.Web.HttpContext.Current;
string IP = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
string compName = (Dns.GetHostEntry(Request.ServerVariables["remote_addr"]).HostName);
string account = Request.ServerVariables["AUTH_USER"];
string[] user_network_data = new string[3];
if (!string.IsNullOrEmpty(IP))
{
string[] addresses = IP.Split(',');
if (addresses.Length != 0)
{
IP = addresses[0];
}
}
else
{
IP = context.Request.ServerVariables["REMOTE_ADDR"];
}
user_network_data[0] = IP;
user_network_data[1] = compName;
user_network_data[2] = account;
return user_network_data;
}
I think you're just grabbing the wrong initial information from the request. Try these:
string IP = context.Request.UserHostAddress;
string compName = context.Request.UserHostName;
string account = context.Request.LogonUserIdentity.Name;
I think the rest of your code should work fine once you have the right data to start off with.

Change option DHCP/BOOTP in dhcp reservation

I'm using C# (Visual Studio 2010) to programmatically create a DHCP reservation.
I've used the information in this post to get the DHCPOBJECTS.DLL. Connecting to the DHCP server works well. I'm also able to create a new reservation or enumerate through existing reservations.
class CDHCP
{
private Manager dhcpmgr;
private Server dhcpsrvr;
public CDHCP()
{
dhcpmgr = new Manager();
dhcpsrvr = dhcpmgr.Servers.Connect("192.168.1.3");
}
public void create_reservation(string sName, string sAddress, string sDescription, string sMAC)
{
Reservation DHCPReservation = dhcpsrvr.Scopes["192.168.1.0"].Reservation.CreateNew();
DHCPReservation.Name = sName;
DHCPReservation.UniqueID = sMAC;
DHCPReservation.Address = sAddress;
DHCPReservation.Comment = sDescription;
DHCPReservation.Update();
}
public void get_reservations()
{
List<Reservation> reservations = new List<Reservation>();
for(int i = 1; i <= dhcpsrvr.Scopes.Count; i++)
{
for(int j = 1; j <= dhcpsrvr.Scopes[i].Reservations.Count; j++)
{
reservations.Add(dhcpsrvr.Scopes[i].Reserations[j]);
}
}
}
}
Unfortunately when creating a new reservation the supported type is always set to "both". In our network we have to use only DHCP.
Anyone knows how to set the supported type to DHCP via the DHCPOBJECTS.DLL?
EDIT:
Okay it seems that I'm not able to change this option via DHCPOBJECTS.DLL.
Now I will try to realize this via the microsoft dhcp server management api

Categories

Resources