Microsoft OPOS hangs on Claim after PC restart - c#

I am using 'Microsoft Point of Service for .NET v1.14.' dlls to connect with Posiflex Thermal Printer (PP8800 model).
Code snippet which I am using is also pasted below. I am running this code from WPF application.
But I am facing one strange issue. If printer is powered on and machine on which the printer is connected is restarted, below pasted code is not able to claim the printer and it also does not come out of the Claim() statement. Whereas if I power off the printer and then power it on before running the below code snippet then it is able to claim the printer.
PosExplorer posExplorer = new PosExplorer();
var printerList = posExplorer.GetDevices(DeviceType.PosPrinter);
foreach (DeviceInfo item in printerList)
{
if (item.ServiceObjectName != printerName)
continue;
posPrinter = (PosPrinter)posExplorer.CreateInstance(item);
posPrinter.Open();
posPrinter.PowerNotify = PowerNotification.Enabled;
posPrinter.FlagWhenIdle = true;
posPrinter.StatusUpdateEvent += PosPrinter_StatusUpdateEvent;
posPrinter.DirectIOEvent += PosPrinter_DirectIOEvent;
posPrinter.ErrorEvent += PosPrinter_ErrorEvent;
posPrinter.OutputCompleteEvent += PosPrinter_OutputCompleteEvent;
try
{
posPrinter.Claim(100);
if (posPrinter.Claimed)
{
isPrinterClaimed = true;
}
else
{
isPrinterClaimed = false;
}
}
catch (Exception ex)
{
isPrinterClaimed = false;
}
break;
}
Has anybody faced the same issue while using OPOS libraries?

Related

ServerManager fails with 0x80040154 in c# Winforms app creating simple web application in IIS

I am writing a small app that installs IIS and configures a website before deploying the files to it.
On a freshly reset Windows 10, the first attempt always fails with the 0x80040154 COM+ component failure as documented in This question
I looked at the version I am using and it is the latest and correct one for .net standard (4.8) and not the one meant for .net core
When I press the button to rerun the function it always finishes correctly. I tried using a retry routine, and it fails on each retry, yet runs fine again when the button is pressed. The reason for this I assume is that the server manager object isn't disposed when it hits the catch block since its in a using statement.
I can work around that, but I really want to understand the issue and make a permanent fix.
My routine simply creates a website in IIS and creates an app pool to assign to it.
And it is running with elevated privileges
For reference:
Machine is Windows 10 latest from the downloadable media creator.
Microsoft.Web.Administrator version is 7.0.0.0
App is .net 4.8 standard windows forms
using (var serverManager = new ServerManager())
{
string iisrootdir = drive;
//Check for inetpub/wwwroot
if (!Directory.Exists(iisrootdir)) //Check for Drive D
{
iisrootdir = #"C:\";
}
string iiscmsdir = Path.Combine(iisrootdir, "webdir", "appdir");
if (!Directory.Exists(iiscmsdir))
Directory.CreateDirectory(iiscmsdir);
var settings = new ApplicationSettings();
settings.ReadFromFile();
settings.CMSPATH = iiscmsdir;
settings.SaveToFile();
try
{
string poolName = "DefaultAppPool";
if (serverManager.Sites.Count > 0)
{
Site myDefualtWebsite = serverManager.Sites[0];
if (myDefualtWebsite != null)
{
OnRaiseInstallEvent(new InstallEventArgs("CreateWebsite", ProcessState.Started,
"Remove Default Website"));
serverManager.Sites.Remove(myDefualtWebsite);
serverManager.CommitChanges();
}
}
if (!WebsiteExists("sitename"))
{
mySite.ServerAutoStart = true;
}
Site site = serverManager.Sites["sitename"];
if (!AppPoolExists(poolName))
{
serverManager.ApplicationPools.Add(poolName);
}
ApplicationPool apppool = serverManager.ApplicationPools[poolName];
apppool.ManagedPipelineMode = ManagedPipelineMode.Integrated;
apppool.ManagedRuntimeVersion = "";
serverManager.Sites["sitename"].ApplicationDefaults.ApplicationPoolName = poolName;
foreach (var item in serverManager.Sites["sitename"].Applications)
{
item.ApplicationPoolName = poolName;
}
serverManager.CommitChanges();
apppool.Recycle();
serverManager.CommitChanges();
}
catch (Exception ex)
{
if (ex.Message.Contains("80040154") && errorCount < 4)
{
if (serverManager != null)
serverManager.Dispose();
errorCount++;
OnRaiseInstallEvent(new InstallEventArgs("CreateWebsite", ProcessState.Started,
"Error encountered with COM+ object, trying again: " + errorCount));
CreateWebsite(#"D:\");
}
else
{
if (serverManager != null)
serverManager.Dispose();
errorCount = 0;
OnRaiseErrorEvent(new InstallErrorEventArgs("CreateWebsite", ProcessState.Error, ex));
return false;
}
}
finally
{
serverManager?.Dispose();
}
Thanks for the help Guys. I found the problem.
DISM was running in its own thread. The Process object exited the moment it launched. My function was then attempting to configure IIS before it had finished installing.

PosExplorer - barcode scanner - getting error 'Root element is missing' after scanner.Open()

I am programming an application in WPF which initializes posExplorer on a particular page, acquires the required scanner and then open and listen on DataEvent handler. It already worked and there wasn't any problem.
Then it suddenly (yep, suddenly) began to throw exception:
An exception of type 'System.Exception' occurred in HHSO4NET.dll but was not handled in user code...
Something like 'Root element is missing' [from Czech translation, which I can't change]
And yes, Barcode scanner was connected into computer. I already tried to reinstall pos for net 1.12, but still the same error.
There is code behind this:
Private PosExplorer posExplorer = new PosExplorer ();
Private Scanner scan;
PosExplorer.DeviceAddedEvent + = new
DeviceChangedEventHandler(posExplorer_DeviceAddedEvent);
Var deviceCollection = posExplorer.GetDevices (DeviceType.Scanner);
Foreach (DeviceInfo dInfo in deviceCollection)
{
If (dInfo.Type == "Scanner" && dInfo.ServiceObjectName == "HoneywellScannerSO")
{
If (dInfo.LogicalNames.Length> 0)
{
Devicess.Add (dInfo);
}
}
}
Scan = (Scanner) posExplorer.CreateInstance (devicess [0]);
If (! (Scan.State == ControlState.Idle))
{
Scan.Open (); //AFTER THAT IT FAILS
Scan.Claim (0);
Scan.DeviceEnabled = true;
Scan.DataEvent + = new DataEventHandler (activeScanner_DataEvent);
Scan.DataEvent = true;
Scan.DecodeData = true;
}
Can somebody tell me, how is possible that it worked and later without any modification in this code it do not work? Thanks for your answers.
Well, after a few days I finally solved it. It required software reinstal from Honeywell - POS4NET Configuration utility. Then remove and again add scanner on specified port and it running. How simple, right? But still dont know why it happened.

How to print files to client rollpaper printer from MVC Web Application?

In my project I came across this problem that I have been struggling for so much hours. Hope somebody could help me.
My client needs to print many tickets from the web (with one click) with some info from the database, let's say Name, Date and Price. All the tickets will be printed on a Rollpaper Printer, so after every ticket it should autocut each one.
Which would be an appropriate way to achieve this task?
I have a working code, that uses the PrintDocument Class (code below), the problem is that I need to have access to the printer to use it.
Scenario:
I'm using ASP.NET MVC3 on Visual Studio 2010.
The app is on a Shared Server.
Need to generate many tickets that will print all at once.
I have access to the Client PC, so I can install everything there and touch whatever is neccesary.
The app is used with Firefox and/or Chrome.
The printer is an Epson TMT82.
Thanks in advance.
public static bool PrintTicket(ref string Msg, string Impresora)
{
bool result = false;
try
{
System.Drawing.Printing.PrintDocument Pd = new System.Drawing.Printing.PrintDocument();
//If empty, Default
if(!String.IsNullOrEmpty(Impresora))
Pd.PrinterSettings.PrinterName = Impresora;
Margins margins = new Margins(10, 0, 0, 0);
Pd.DefaultPageSettings.Margins = margins;
Pd.PrintController = new System.Drawing.Printing.StandardPrintController();
Pd.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(printTicket_PrintPage);
Pd.Print();
PrintServer ps = new PrintServer();
PrintQueue printerQueue = LocalPrintServer.GetDefaultPrintQueue();
SpotTroubleUsingProperties(ref Msg, printerQueue);
result = (Msg == String.Empty);
if (!result)
{
var jobs = printerQueue.GetPrintJobInfoCollection();
foreach (var job in jobs)
{
job.Cancel();
}
}
}
catch (Exception ex)
{
Msg = ex.Message;
}
return result;
}

Mapped drivelabel windows 7 issue

I am going crazy with an issue with LABEL of mapping a drive to windows with windows 7 OS. Scenario;
We need to map the drive as soon as user logs in to the machine. That seems to be working fine with other os versions except windows 7. Steps for windows 7;
EXE (c# made by us) launched in windows 7
EXE has mapped drive correctly
User logged out
Logged in back
Again exe is trying to map drive (Its registered as a startup exe)
The mapped drive label becomes "Network Drive" (Not sure how)
We are setting the proper values in registry as well as shown in below figure;
Problem is here;
Issue is only occurring when we do logout and login. If we manually launch exe, it works fine...
I have also tried to DELETE all these registry before mapping driving assuming it might be cache or something but nothing helped..
We are using zMapDrive to map a drive;
//create struct data
structNetResource stNetRes = new structNetResource();
stNetRes.iScope = 2;
stNetRes.iType = RESOURCETYPE_DISK;
stNetRes.iDisplayType = 3;
stNetRes.iUsage = 1;
stNetRes.sRemoteName = ls_ShareName;
stNetRes.sLocalName = ls_Drive;
//prepare params
int iFlags = 0;
if (lf_SaveCredentials) { iFlags += CONNECT_CMD_SAVECRED; }
if (lf_Persistent) { iFlags += CONNECT_UPDATE_PROFILE; }
if (ls_PromptForCredentials) { iFlags += CONNECT_INTERACTIVE + CONNECT_PROMPT; }
if (psUsername == "") { psUsername = null; }
if (psPassword == "") { psPassword = null; }
//if force, unmap ready for new connection
if (lf_Force) { try { zUnMapDrive(true); } catch { } }
//call and return
int i = WNetAddConnection2A(ref stNetRes, psPassword, psUsername, iFlags);
if (i > 0) { throw new System.ComponentModel.Win32Exception(i); }
Maybe a simple powershell script, renaming network drive will work for you? You can then use Task Scheduler to run it every time a user logs in.
$Rename = New-Object -ComObject Shell.Application
$Net = New-Object -ComObject WScript.Network
# map the drive if the path doesn't exist
If (!(Test-Path Z:))
{
$Net.MapNetworkDrive("Z:", '\\SERVER_ADDRESS\Directory', $false, "user", "password")
}
# change the drive name
$Rename.NameSpace("Z:\").Self.Name = "MyNetDriveLabel"
From my experience, support for network mapped drives is somewhat buggy in Windows 7, so I use similar workaround on a few of our Win7 machines.

ManagementObjectSearcher to detect drivers for Sixnet

This is what I get for installed software. I downloaded the Sixnet driver package and installed it. Now I want to detect if it has actually installed the drivers with the code below:
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PnPSignedDriver");
foreach (ManagementObject obj in searcher.Get())
{
//Looking for Sixnet USB Ethernet/RNDIS Gadget. Only try on objects that actually have a description.
if (obj.GetPropertyValue("Description") != null)
{
try
{
if (obj.GetPropertyValue("Description").ToString().Contains("Sixnet USB Ethernet"))
{
return true;
}
}
catch (Exception e)
{
}
}
}
return false;
I am pretty sure it was returning true earlier today but now I cannot get this block to work, it does not detect the driver.
Lower down in the code I connect to the NIC and that works but it was my understanding that it would only connect to the NIC if the driver was actually installed because the default driver does not work.
Below is my network connections and I can see the modem as Network 5 - the one with Sixnet in the name. Why does my code not want to show that the drivers are installed? I want to run the software to first check if the drivers were installed and then if I can connect to the Sixnet modem via a USB cable. Thank you
Edit: Ok, I changed obj.GetPropertyValue("Description") to obj.GetPropertyValue("Devicename") and it did not work immediately so I moved on to other work and 10 minutes later it worked? How do I refresh the WMI database?
Edit #2:
private bool Check_Drivers()
{
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PnPSignedDriver where DeviceName LIKE '%Sixnet USB%'");
if (searcher.Get().Count > 0)
{
searcher = null;
return true;
}
searcher = null;
return false;
}
I changed my whole method to the code above. The searcher = null; was my attempt to make sure every call to this method reloads the management object.

Categories