PrintQueue.Refresh don't show the status of printer - c#

I need to run a Windows Service of server X to show the status of all printers: Out of paper, no toner, etc.
The service is running on a machine but of course not all printers are installed on it. Even when the printers are installed on the machine, we do NOT have the status of the printers!
The only thing I was able to do is to remove the paper, print a test page (notepad), and now I can see that I'm missing paper with the code below, but as you might thing, this is not doable: I don't want to send a test page to every printers of the network every 10 minutes or so!
I try to query PrintQueue.Refresh but status is not updating, I don't see that the printer tray is open (or missing paper, or no toner, whatever I do with the printer.)
BTW, Win32_printer don't show me a better result.
NOTE:
MonitoringWS is the web service that can access the database.
Printers is the list of printers that we want to query.
This is what I try to do.
var printServers = GetListOfPrinterServers();
var listPrinters = printers as List<Printer> ?? printers.ToList();
foreach (
var printServer in
printServers.Select(
server => new PrintServer(server, PrintSystemDesiredAccess.EnumerateServer)))
{
printServer.Refresh();
var printQueues = printServer.GetPrintQueues();
foreach (var printQueue in printQueues)
{
var queue = printQueue;
var printersFound = listPrinters.Where(p =>
string.Equals(p.PrinterName, queue.FullName,
StringComparison.OrdinalIgnoreCase));
foreach (var printer in printersFound)
{
printQueue.Refresh();
Debug.WriteLine(string.Format("{0} {1}", printQueue.FullName, printQueue.HostingPrintServer.Name) );
var pm = new MonitoringWS.PrinterMonitoring
{
FkPrinter = printer.PkPrinter,
QueueStatus = printQueue.QueueStatus,
DriverName = printQueue.QueueDriver.Name,
MonitoringDateTime = DateTime.Now
};
printerMonitorings.Add(pm);
}
}
}

I found a way: SNMP. I use library SNMP# at http://www.snmpsharpnet.com/ and I implement RFC 2790: https://www.rfc-editor.org/rfc/rfc2790 .
With that, when the printer support that standard and when SNMP is active, I got the status of the printer (no toner, no paper, paper jam, etc.)
Thanks everybody for your help.

Related

Trouble with transfer function in WIA C#

I have a problem with the below code. I want to scan a document by clicking a button in a WinForms C# application.
I use WIA, Visual studio and the scanner Fujitsu N7100A working with Windows 8. I am following a tutorial online for using WIA.
But the program doesn't run as expected. It seems to break down at the Transfer method.
// Create a DeviceManager instance
var deviceManager = new DeviceManager();
// Create an empty variable to store the scanner instance
DeviceInfo firstScannerAvailable = null;
// Loop through the list of devices to choose the first available
AddLogs(deviceManager.DeviceInfos.Count.ToString(), filename);
foreach (DeviceInfo d in deviceManager.DeviceInfos)
{
if (d.Type == WiaDeviceType.ScannerDeviceType)
{
firstScannerAvailable = d;
}
}
// Connect to the first available scanner
var device = firstScannerAvailable.Connect();
// Select the scanner
var scannerItem = device.Items[0];
// Retrieve a image in JPEG format and store it into a variable
var imageFile = (ImageFile)scannerItem.Transfer(FormatID.wiaFormatPNG);
//Save the image in some path with filename
var path = #"C:\Documents\scan.png";
if (File.Exists(path))
{
File.Delete(path);
}
// Save image !
imageFile.SaveFile(path);
I just have to remove the addition of lines in the file of log.
This is much more of a workaround since i have no idea about your scanner.
I would assume that all scanners has a drive where they store their scanned documents, like mine, So i would suggest that you read all available drives loop through them check for DriveType and VolumeLabel and then read it's files and copy the document where you want
Something like this :
foreach (var item in DriveInfo.GetDrives())
{
//VolumeLabel differs from a scanner to another
if (item.VolumeLabel == "Photo scan" && item.DriveType == DriveType.Removable)
{
foreach (var obj in Directory.GetFiles(item.Name))
{
File.Copy(obj, "[YOUR NEW PATH]");
break;
}
break;
}
}
Finaly a TWAIN application work with this scanner. I will work with that. I don't said why do that work with TWAIN and not with WIA but that the reality. Sorry for this waste of time. Thank you for the answers. Have a nice day.
I am currently solving this very problem. It seems the N7100A driver sets the Pages property of the device to 0, which should mean continous scanning, but the transfer method is unable to handle this value. You must set that property to 1:
var pages = 1;
// Not all devices have this property, but Fujitsu N7100A has.
device.Properties["Pages"]?.set_Value(ref pages);
I think the problem is here
var scannerItem = device.Items[0];
as WIA indexes are NOT zero based so it should be 1 instead
var scannerItem = device.Items[1];

Windows IoT Raspberry Pi 3 C# GetDiskFreeSpace

I have a USB thumb-drive connected to my raspberry pi 3. I'd need to find out how to check for the available disk space to be printed on a textblock. I couldn't find any example for UWP application.
What I found was GetDiskFreeSpaceEx function and Is there a method available for UWP apps to get available disk space
Is there any example I could refer to?
Thanks.
Updated:
I have tried [Get available disk free space for a given path on Windows [duplicate]] .. Couldn't get it to work too..
You can use StorageFolder.Properties.RetrievePropertiesAsync() API to get the free space size of USB storage.I tested with the following pieces of code:
var removableDevices = KnownFolders.RemovableDevices;
var externalDevices = await removableDevices.GetFoldersAsync();
var usbDriver = externalDevices.FirstOrDefault();
var allProperties = usbDriver.Properties;
IEnumerable<string> propertiesToRetrieve = new List<string> { "System.FreeSpace" };
var storageIdProperties = await allProperties.RetrievePropertiesAsync(propertiesToRetrieve);
var freeSpaceSize = storageIdProperties["System.FreeSpace"].ToString();

UWP/C# - Issue with AQS and USB Devices

I have an issue with a UWP app that I am trying to write. I am connecting to a custom embedded USB Bulk device that I have programmed (it is actually an out of the box example from Cypress Semiconductor). I am using the WinUSB.sys driver using the embedded MS OS string in the device to allow the device to be used with out having to write a custom INF file to call the WinUSB.sys driver.
In my code, I am using the UsbDevice.GetDeviceSelector method to return an AQS that can then be passed into DeviceInformation.FindAllAsync to begin communicating with the device in my app. I have confirmed that the device shows up in the device manager without any issues, and I have checked in the registry to ensure that it has an Interface GUID. I have a screenshot from USBViewer to show the configuration of the device. This method for finding and connecting with USB devices is from this MSDN example found here.
When I use the UsbDevice.GetDeviceSelector method, it returns a GUID that is not associated with this device. The GUID that it returns is actually associated with Lumia Phones (DEE824EF-729B-4A0E-9C14-B7117D33A817). Because of this, it does not find my device connected to the system.
To troubleshoot, I have both called the DeviceInformation.FindAllAsync with out any arguments to see if my device is listed, and it does find the device (amongst over 1000 other devices that have been connected ever to my machine). I then wrote a custom AQS string without the help of the GetDeviceSelector method, starting with just the GUID. Doing this returned 27 devices, but when I tried to add the VID and PID to this AQS string, nothing returned.
I have also made sure that the device that I want to use is listed in the app manifest by its appropriate VID and PID as this is required for a device with a Custom Class of 0xFF. I have used the Custom USB UWP device example and it can find the device, though it uses a completely different method with a device picker, which I will go to if needed, but this is not my desire as it makes that part of the app not as clean of a solution.
I have posted this question over in the MSDN forums here with more information, but I have not gotten a lot of engagement there. Any help would be appreciated. I know that I must be missing something simple.
Adam
private async void button_Click(object sender, RoutedEventArgs e)
{
//UInt32 vid = 0x04B4;
//UInt32 pid = 0x00F0;
UInt32 vid = uint.Parse(textBox1.Text, System.Globalization.NumberStyles.HexNumber);
UInt32 pid = UInt32.Parse(textBox2.Text, System.Globalization.NumberStyles.HexNumber);
Guid winusbInterfaceGuid = new Guid("a5dcbf10-6530-11d2-901f-00c04fb951ed");
//string aqs = UsbDevice.GetDeviceSelector(vid, pid);
string aqs = UsbDevice.GetDeviceSelector(winusbInterfaceGuid);
var myDevices = await DeviceInformation.FindAllAsync(aqs, null);
//var myDevices = await DeviceInformation.FindAllAsync();
var myDevicesCount = myDevices.Count;
if (myDevicesCount >= 1)
{
textBlock2.Text = "Device Found";
} else
{
textBlock2.Text = "Searching";
await Task.Delay(1000);
textBlock2.Text = "looking for device";
}
}
just dropped you a mail asking about progress (I think, had to guess your mail address), but now it seems I found a solution myself. Please see my answer on UWP app cannot find/connect to USB device
In short, you have to create an inf for installing the winusb driver. I have no clue why, but that did the trick for me (and someone else, see Cannot create UsbDevice from DeviceInformation.Id)
The Guid DEE824EF-729B-4A0E-9C14-B7117D33A817 is actually the standard WinUSB Guid. I don't think it has anything to do with Lumia Phones. I don't know why it is not documented anywhere. I think that the Guid a5dcbf10-6530-11d2-901f-00c04fb951ed you specified is actually a red herring. I mistakenly used that as well, but it just led me down the garden path. It shows up USB interfaces, but I can't connect to them.
You might want to try this class https://github.com/MelbourneDeveloper/Device.Net/blob/master/src/Usb.Net.UWP/UWPUsbDevice.cs .
Here is how it gets the device:
public async Task<IEnumerable<DeviceDefinition>> GetConnectedDeviceDefinitions(uint? vendorId, uint? productId)
{
var aqsFilter = "System.Devices.InterfaceClassGuid:=\"{DEE824EF-729B-4A0E-9C14-B7117D33A817}\" AND System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True AND " + $" System.DeviceInterface.WinUsb.UsbVendorId:={vendorId.Value} AND System.DeviceInterface.WinUsb.UsbProductId:={productId.Value}";
var deviceInformationCollection = await wde.DeviceInformation.FindAllAsync(aqsFilter).AsTask();
//TODO: return the vid/pid if we can get it from the properties. Also read/write buffer size
var deviceIds = deviceInformationCollection.Select(d => new DeviceDefinition { DeviceId = d.Id, DeviceType = DeviceType.Usb }).ToList();
return deviceIds;
}
This sample connects to a device and I think you'll be able to connect to the device in the same way:
private static async Task InitializeTrezor()
{
//Register the factory for creating Usb devices. This only needs to be done once.
UWPUsbDeviceFactory.Register();
//Register the factory for creating Usb devices. This only needs to be done once.
UWPHidDeviceFactory.Register();
//Note: other custom device types could be added here
//Define the types of devices to search for. This particular device can be connected to via USB, or Hid
var deviceDefinitions = new List<DeviceDefinition>
{
new DeviceDefinition{ DeviceType= DeviceType.Hid, VendorId= 0x534C, ProductId=0x0001, Label="Trezor One Firmware 1.6.x" },
new DeviceDefinition{ DeviceType= DeviceType.Usb, VendorId= 0x1209, ProductId=0x53C1, ReadBufferSize=64, WriteBufferSize=64, Label="Trezor One Firmware 1.7.x" },
new DeviceDefinition{ DeviceType= DeviceType.Usb, VendorId= 0x1209, ProductId=0x53C0, ReadBufferSize=64, WriteBufferSize=64, Label="Model T" }
};
//Get the first available device and connect to it
var devices = await DeviceManager.Current.GetDevices(deviceDefinitions);
var trezorDevice = devices.FirstOrDefault();
await trezorDevice.InitializeAsync();
//Create a buffer with 3 bytes (initialize)
var buffer = new byte[64];
buffer[0] = 0x3f;
buffer[1] = 0x23;
buffer[2] = 0x23;
//Write the data to the device
await trezorDevice.WriteAsync(buffer);
//Read the response
var readBuffer = await trezorDevice.ReadAsync();
}
If you connect to the device in this way, you'll get Windows classic, and Android support for free with Device.Net (https://github.com/MelbourneDeveloper/Device.Net)
With Device.net's DeviceManager.Current.GetDevices(deviceDefinitions) using .NET 5 I can't find any device connected to my win10, which can be easily selected by ManagementObjectSearcher:
public List<ManagementBaseObject> GetLogicalDevices()
{
List<ManagementBaseObject> devices = new List<ManagementBaseObject>();
ManagementObjectCollection collection;
ManagementObjectSearcher seacher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM CIM_LogicalDevice");
collection = seacher.Get();
foreach (var device in collection)
{
devices.Add(device);
}
return devices;
}

asp.net network printer not showing the zebra printers?

Hi i have a method that gets a printer list from the network and fill my drop-down list:
private void fillprinterslist()
{
System.Management.ManagementScope objMS =
new System.Management.ManagementScope(ManagementPath.DefaultPath);
objMS.Connect();
SelectQuery objQuery = new SelectQuery("SELECT * FROM Win32_Printer");
ManagementObjectSearcher objMOS = new ManagementObjectSearcher(objMS, objQuery);
System.Management.ManagementObjectCollection objMOC = objMOS.Get();
foreach (ManagementObject Printers in objMOC)
{
if (Convert.ToBoolean(Printers["Network"])) // ALL NETWORK PRINTERS.
{
DropDownList3.Items.Add(Printers["Name"].ToString());
}
}
}
not all network printers are getting filled in the drop down list, for example i have an zebra label printer in the next room that i am using as a test for this project and it does not show up in the drop down list
the printer is located on:
\ksmsv010\kcmzbl63
In my drop down list i am able to see other printers that are not Zebra Printers
**how do i only list the zebra printers from all servers?? **
from what information i had all the zebra printers have "zbl" common in the naming convention so i dont know if we can filter based on those 3 letter.
Please help thanks!!!!

Enumerate available WiFi Printers in my Windows Phone app

I know similar questions have been asked a lot, ie "can I print from my wp8?". Most folks seem content with the simple "no" response. I am looking to add this functionality into my app and I know it can be accomplished at some level - even if I can only support a very minimum printer set for now.
I've looked at the app PrintHand, and it appears to have the capabilities I need: print to wireless and Bluetooth printers.
I've been looking through the Bluetooth scenarios document a bit and I think this might help discover a Bluetooth printer. That's a start. Perhaps it will help in identifying wireless printers also.
I realize I need to start very small with this project and I want to first try to enumerate any wireless printers (I don't have a Bluetooth one yet) available on the current network. Would anybody happen to have a pointer in the right direction on how to get started or better yet, some related sample code?
Thanks so much!
Best I can give is my Github Repo which isn't related to Wifi printers, but Google cloud printing.
There isn't really a .net reference for using Google Cloud Print in their documentation, but the code works in Mono, and should be easy to move over to .NET and hence, Windows Phone.
MonoGCP
I was able to detect a nearby wireless printer using Simple Service Discovery Protocol.
Here is my sample function:
private const string SSDP_IP = "239.255.255.250";
private const string SSDP_PORT = "1900";
public async static void DiscoverAsync2()
{
var multicastIP = new HostName(SSDP_IP);
var found = false;
using (var socket = new DatagramSocket())
{
socket.MessageReceived += (sender, e) =>
{
var reader = e.GetDataReader();
var bytesRemaining = reader.UnconsumedBufferLength;
var receivedString = reader.ReadString(bytesRemaining);
// TODO: something useful with this new info
found = true;
};
await socket.BindEndpointAsync(null, string.Empty);
socket.JoinMulticastGroup(multicastIP);
while (true)
{
found = false;
using (var stream = await socket.GetOutputStreamAsync(multicastIP, SSDP_PORT))
{
var request = new StringBuilder();
request.AppendLine("M-SEARCH * HTTP/1.1");
request.AppendLine("HOST: " + SSDP_IP + ":" + SSDP_PORT);
request.AppendLine("MAN: \"ssdp:discover\"");
request.AppendLine("MX: 3");
request.AppendLine("ST: urn:schemas-upnp-org:device:Printer:1"); // use ssdp:all to get everything
request.AppendLine(); // without this extra blank line, query won't run properly
var buff = Encoding.UTF8.GetBytes(request.ToString());
await stream.WriteAsync(buff.AsBuffer());
await Task.Delay(5000);
if (!found)
break;
}
}
}

Categories