As shown below in the picture, when I tried to retrieve all printers, I got only 2 printers.
Is there a way to return all printers using either PowerShell WMI or C#(so that I can translate it in powershell)?
I have tried System.Drawing.Printing.PrinterSettings.InstalledPrinters (refer to how to get the list of all printers in computer - C# Winform) but also displays only 2 entries.
Simply,
via System.Drawing.Printing
foreach (String printer in PrinterSettings.InstalledPrinters)
{
Console.WriteLine(printer.ToString()+Environment.NewLine);
}
via WMI
public static void AvailablePrinters()
{
oManagementScope = new ManagementScope(ManagementPath.DefaultPath);
oManagementScope.Connect();
SelectQuery oSelectQuery = new SelectQuery();
oSelectQuery.QueryString = #"SELECT Name FROM Win32_Printer";
ManagementObjectSearcher oObjectSearcher =
new ManagementObjectSearcher(oManagementScope, #oSelectQuery);
ManagementObjectCollection oObjectCollection = oObjectSearcher.Get();
foreach (ManagementObject oItem in oObjectCollection)
{
Console.WriteLine("Name : " + oItem["Name"].ToString()+ Environment.NewLine);
}
}
via PowerShell
Get-WMIObject -class Win32_Printer -computer $printserver | Select Name,DriverName,PortName
For more information, please check this article & WMI Printer Class
Related
I'm using the following code to get my drive serial number. It's working fine with Windows 7, 8, 8.1, and 10 Professional, but I'm getting an error on Windows 10 Home.
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");
foreach (ManagementObject wmi_HD in searcher.Get())
{
if (wmi_HD["SerialNumber"] == null)
hddId = null;
else
hddId = wmi_HD["SerialNumber"].ToString();
}
I'm getting
System.NullReferenceException : Object reference not set to an instance of an object.
Does anyone know why? What do I need to do to get the serial number in this case?
One more question: if I boot the OS from my pendrive, will this code work? How could I know that the OS is running from a pendrive or disk or any other resource?
When I go to the Device Manager, I see this:
I am adding this as an answer because it can save lot of time while debugging scenarios like System.NullReferenceException in WMI.
Windows+R (run command)
Type wbemtest
And connect to the machine for which you want to fetch information. Fire the query for Win32_DiskDrive and check the output for properties that you can fetch.
This is what I'm using on Windows 10 v1809:
using System;
using System.Management;
namespace GetSerialNo
{
class Program
{
static void Main(string[] args)
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");
foreach (ManagementObject info in searcher.Get())
{
Console.WriteLine("DeviceID: " + info["DeviceID"].ToString());
Console.WriteLine("Model: " + "Model: " + info["Model"].ToString());
Console.WriteLine("Interface: " + "Interface: " + info["InterfaceType"].ToString());
Console.WriteLine("Serial#: " + "Serial#: " + info["SerialNumber"].ToString());
}
Console.ReadLine();
}
}
}
For details please see http://csharphelper.com/blog/2017/10/get-hard-drive-serial-number-c/
For the associated link Get Hard disk serial Number given by #ADreNaLiNe-DJ I wasn't able to find the required assembly reference for HardDrive hd = new HardDrive();
I have some problem (c#).
I can retrieve some mainboard info from win32-baseboard but when I want to get Model
but an error accrued.
How can we get a list of installed software on windows (like xp).
How can we get a list of installed Peripheral device on Windows (with detail) (like scanner, webcam).
How to obtain total amount of ram (just) directly.
Use WMI (I suspect you already using it):
Model is blank. Try Manufacturer property. Also get the Product property to get the model.
Installed software: Get the Win32_Product class.
Try Win32_PnPSignedDriver class and iterate through.
Use Win32_ComputerSystem class and get TotalPhysicalMemory property.
Get WMIEXPLORER and play with it. LINK
Sample for C#:
If you require to connect to remote computer with credentials (strUsername and strPassword variables):
private ManagementScope CreateNewManagementScope(string server)
{
string serverString = #"\\" + server + #"\root\cimv2";
ManagementScope scope = new ManagementScope(serverString);
if (!chkUseCurrentUser.Checked)
{
ConnectionOptions options = new ConnectionOptions
{
Username = strUsername,
Password = strPassword,
Impersonation = ImpersonationLevel.Impersonate,
Authentication = AuthenticationLevel.PacketPrivacy
};
scope.Options = options;
}
return scope;
}
Get the services:
private void GetServicesForComputer(string computerName)
{
ManagementScope scope = CreateNewManagementScope(computerName);
SelectQuery query = new SelectQuery("select * from Win32_Service");
try
{
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query))
{
ManagementObjectCollection services = searcher.Get();
List<string> serviceNames =
(from ManagementObject service in services select service["Caption"].ToString()).ToList();
lstServices.DataSource = serviceNames;
}
}
catch (Exception exception)
{
lstServices.DataSource = null;
lstServices.Items.Clear();
lblErrors.Text = exception.Message;
Console.WriteLine(Resources.MainForm_GetServicesForServer_Error__ + exception.Message);
}
}
Some screens from wmiexplorer:
How am I able do find all local printers of the machine where the program is running with a user that doesn't have admin rights. I need to remap the printer IP and set the printer as default. My idea is to use impersonation to do this but I don't know where to find the printer and if it is a good solution to use impersonation.
Thanks for any help!
I don't think you will have any luck with this. Impersonation will not work here and just throw a exception. You can try this by making a impersonation and try to open Environment.Domain it should give you a exception.
You can try something like this without impersonation:
ManagementScope mscope = new ManagementScope(#"\root\CIMV2", options);
mscope.Connect();
System.Management.ObjectQuery oQuery = new ObjectQuery("Select * from Win32_TCPIPPrinterPort");
System.Management.ManagementObjectSearcher searcher = new ManagementObjectSearcher(mscope, oQuery);
ManagementObjectCollection moCollection = searcher.Get();
foreach (ManagementObject mo in moCollection)
{
string name = mo["Name"].ToString();
if (name.Equals(this.portName))
{
System.Threading.Thread.Sleep(10000);
mo["HostAddress"] = this.printerIP;
mo.Put();
Console.WriteLine("Adjusted Printer Port to new IP address " + this.printerIP);
return true;
}
}
I am working on a Winforms application that allows users to print a few different Reporting Services reports. Unfortunately, if the user tries to print to PDF using the Adobe PDF printer, it crashes. We haven't been able to solve this issue, so as a work around we want remove the ability for users to print to the Adobe PDF printer.
Is there any way to programmatically remove the Adobe PDF printer from the list of printers in the print dialog?
Call this with the printer name before calling PrintDialog().... I think this will solve your issue
public bool RemovePrinter(string printerName)
{
ManagementScope scope = new ManagementScope(ManagementPath.DefaultPath);
scope.Connect();
SelectQuery query = new SelectQuery("select * from Win32_Printer");
ManagementObjectSearcher search = new ManagementObjectSearcher(scope, query);
ManagementObjectCollection printers = search.Get();
foreach (ManagementObject printer in printers)
{
string printerName = printer["Name"].ToString().ToLower();
if (printerName.Equals(printerName.ToLower()))
{
printer.Delete();
break;
}
}
return true;
}
The answer from manish gave me what I needed. In my case, I had a virtual printer driver that was being created by a library, and it left orphans like Printer (1), Printer (2), etc. I wanted to delete all of those, so I used a variant of the WMI code above.
using System.Management;
//...
var scope = new ManagementScope(ManagementPath.DefaultPath);
scope.Connect();
var query = new SelectQuery($#"select * from Win32_Printer where Name like '{PrinterDeviceName}%'");
foreach (var o in new ManagementObjectSearcher(scope, query).Get())
((ManagementObject) o).Delete();
You need a reference to System.Management.
Recently I am making a system monitoring tool. For that I need a class to monitor print job.
Such as when a print started, is it successful or not, how many pages.
I know that I can do it using winspool.drv. But dont how. I've searched extensively but having no luck. Any code/suggestion could be very helpful.
Thanks.
Well I don't know about the winspool.drv, but you can use the WMI to get the status of the printer. Here is an example of the using Win32_Printer.
PrintDialog pd = new PrintDialog();
pd.ShowDialog();
PrintDoc.PrinterSettings = pd.PrinterSettings;
PrintDoc.PrintPage += new PrintPageEventHandler(PrintDoc_PrintPage);
PrintDoc.Print();
object status = Convert.ToUInt32(9999);
while ((uint)status != 0) // 0 being idle
{
ManagementObjectSearcher mos = new ManagementObjectSearcher("select * from Win32_Printer where Name='" + pd.PrinterSettings.PrinterName + "'");
foreach (ManagementObject service in mos.Get())
{
status = service.Properties["PrinterState"].Value;
Thread.Sleep(50);
}
}
If you don't use the PrintDialog object (to choose a printer) you can run the WMI query and it will return all the printers in the system.