Try Catch Block doesn´t work with Secugen Fingerprint - c#

I'm working on a fingerprint recognition software on c#, WPF Visual Studio 2012, I'm using secugen hamster to take the fingerprints, the software is all done, I can register the fingerprints correctly to the database and succesfull retrieve and compare them for the user access, but sometimes when the software is matching the stored fingerprint with the one just taken of the user, the method MatchIsoTemplate generates an error 'attempt to read or write protected memory. this is often an indication that other memory damaged' and the program stops, I tried to catch this with a try catch but It doesn't work, no matter what the program stops there, this is the code I'm using according to the example of secugen sdk
SGFPMISOTemplateInfo sample_info = new SGFPMISOTemplateInfo();
Int32 err = m_FPM.GetIsoTemplateInfo(customer.Huella, sample_info);
bool matched = false;
for (int i = 0; i < sample_info.TotalSamples; i++)
{
try
{
m_FPM.MatchIsoTemplate(customer.Huella, i, m_VrfMin, 0, m_SecurityLevel, ref matched);
}
catch (Exception)
{
MessageBox.Show("Try Again", "Aviso", MessageBoxButton.OK, MessageBoxImage.Hand);
}
if (matched)
{
//fill data

I answer my own question, finally I discover how to do it, i just need to wrap the method around the [HandleProcessCorruptedStateExceptions] from System.Runtime.ExceptionServices and use a Try Catch in the correct part of the method, like this
[HandleProcessCorruptedStateExceptions]
void myFunction()
{
try
{
switch (sequence)
{
case 0:
sequence++;
m_FPMAux.MatchIsoTemplate(customer.Huella, i, m_VrfMin, 0, m_SecurityLevel, ref matched);
break;
case 1:
sequence++;
m_FPMAux.MatchIsoTemplate(m_VrfMin, 0, customer.Huella, i, m_SecurityLevel, ref matched); .......

Related

C# Procedures Do Not Hit

I'm trying to convert some VB.NET programs to C#. I'm quite familiar with VB and am just now getting started with C#. My first program seems to have been exported well enough. I used the MSDN to take care of a few errors after the conversion. BUT the two procedures below do not hit. The program has 0 errors in Visual Studios, and from what I can tell, they are structured just like the examples on the MSDN website. I'm using Visual Studio 2015.
It’s a simple program that opens a COM port and receives data; very basic. Works perfect in VB, and in C# everything but these 2 procedures fire. Any insight on what I’m doing wrong would be immensely appreciated.
//catches incoming data from serial device.
private void SerialPort1_DataReceived(System.Object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
try
{
ReceivedText(serialPort1.ReadExisting());
}
catch (Exception ex)
{
MessageBox.Show("Error (4)", "Error", MessageBoxButtons.OK);
}
}
//input from ReadExisting
private void ReceivedText(string text)
{
try
{
if (this.txtOutput.InvokeRequired)
{
SetTextCallback x = new SetTextCallback(ReceivedText);
this.Invoke(x, new object[] { (text) });
}
else
{
this.txtOutput.Text += text;
}
//append text
}
catch (Exception ex)
{
MessageBox.Show("Error (5)", "Error", MessageBoxButtons.OK);
}
}
When adding a serial port through the designer, set the call back in the properties window under the events tab:

Is it safe to use static methods on File class in C#?

I have following code in code-behind of an ASP.Net app, where a file is being read followed by writing to the file.
Code
var state= File.ReadAllText(Server.MapPath(string.Format("~/state/{0}", fileName)));
if(state.indexOf("1") == 0)
{
File.WriteAllText(Server.MapPath(string.Format("~/state/{0}", fileName)), newState);
}
Sometimes, but not always, I get the following exception.
Exception
The process cannot access the file 'C:\inetpub\wwwroot\mywebsite1\state\20150905005929435_edf9267e-fad1-45a7-bfe2-0e6e643798b5' because it is being used by another process.
I am guessing that the file read operation sometimes is not closing the file before the write operation happens, Or may be the file write operation is not closing the file before the next request from web application comes. But, I cannot find what exactly is the reason.
Question: How can I avoid this error from happening? Is it not safe to use the File class and instead use the traditional approach of FileStream object where I would always dispose the FileStream object explicitly?
UPDATE 1
I tried a retry loop approach, but even that didn't seem to solve the problem , since I was able to reproduce the same error if the ASP.Net page was submitted very quickly multiple times one after another. So I am back to finding a fool-proof solution in my case.
string state = null;
int i = 0;
while (i < 20) {
try {
state = File.ReadAllText(Server.MapPath(string.Format("~/state/{0}", fileName)));
} catch (Exception ex2) {
//log exception
Elmah.ErrorSignal.FromCurrentContext().Raise(ex2);
//if even retry doesn't work then throw an exception
if (i == 19) {
throw;
}
//sleep for a few milliseconds
System.Threading.Thread.Sleep(10);
}
i++;
}
i = 0;
while (i < 20) {
try {
File.WriteAllText(Server.MapPath(string.Format("~/state/{0}", fileName)), newState);
} catch (Exception ex2) {
//log exception
Elmah.ErrorSignal.FromCurrentContext().Raise(ex2);
//if even retry doesn't work then throw an exception
if (i == 19) {
throw;
}
//sleep for a few milliseconds
System.Threading.Thread.Sleep(10);
}
i++;
}
UPDATE 2
The only fool proof solution that seemed to work is by using a File Sequencing approach, as suggested by usr. This involves writing to a different file and not to the same file that was just read. The name of file being written to is the name of file that was just read appended by a sequence number.
string fileName = hiddenField1.Value;
string state = null;
int i = 0;
while (i < 20) {
try {
state = File.ReadAllText(Server.MapPath(string.Format("~/state/{0}", fileName)));
} catch (Exception ex2) {
//log exception
Elmah.ErrorSignal.FromCurrentContext().Raise(ex2);
//if even retry doesn't work then throw an exception
if (i == 19) {
throw;
}
//sleep for a few milliseconds
System.Threading.Thread.Sleep(10);
}
i++;
}
i = 0;
while (i < 20) {
try {
//***************FILE SEQUENCING**************************
//Change the file to which state is written, so no concurrency errors happen
//between reading from and writing to same file. This is a fool-proof solution.
//Since max value of integer is more than 2 billion i.e. 2,147,483,647
//so we can be sure that our sequence will never run out of limits because an ASP.Net page
//is not going to postback 2 billion times
if (fileName.LastIndexOf("-seq_") >= 0) {
fileName = fileName.Substring(0, fileName.LastIndexOf("-seq_") + 4 + 1) + (int.Parse(fileName.Substring(fileName.LastIndexOf("-seq_") + 4 + 1)) + 1);
} else {
fileName = fileName + "-seq_1";
}
//change the file name so in next read operation the new file is read
hiddenField1.Value = fileName;
File.WriteAllText(Server.MapPath(string.Format("~/state/{0}", fileName)), newState);
} catch (Exception ex2) {
//log exception
Elmah.ErrorSignal.FromCurrentContext().Raise(ex2);
//if even retry doesn't work then throw an exception
if (i == 19) {
throw;
}
//sleep for a few milliseconds
System.Threading.Thread.Sleep(10);
}
i++;
}
The only downside to above approach is that many files would get created as end users post back to the same ASP.Net page. So, it would be good to have a background job that deleted stale files so number of files would be minimized.
File Names with sequencing
UPDATE 3
Another fool proof solution is to alternate between read and write file names. This way we do not end up creating many files and only use 2 files as the end user posts back to the same page many times. The code is same as in code under UPDATE 2 except the code after FILE SEQUENCING comment should be replaced by code below.
if (fileName.LastIndexOf("-seq_1") >= 0) {
fileName = fileName.Substring(0, fileName.LastIndexOf("-seq_1"));
} else {
fileName = fileName + "-seq_1";
}
File Names with Alternating approach
I am guessing that the file read operation sometimes is not closing the file before the write operation happens, Or may be the file write operation is not closing the file before the next request from web application comes.
Correct. File systems do not support atomic updates well. (Especially not on Windows; many quirks.)
Using FileStream does not help. You would just rewrite the same code that the File class has. File has no magic inside. It just uses FileStream wrapped for your convenience.
Try keeping files immutable. When you want to write a new contents write a new file. Append a sequence number to the file name (e.g. ToString("D9")). When reading pick the file with the highest sequence number.
Or, just add a retry loop with a small delay.
Or, use a better data store such as a database. File systems are really nasty. This is an easy problem to solve with SQL Server for example.
I am guessing that the file read operation sometimes is not closing the file before the write operation happens
Although according to the documentation the file handle is guaranteed to be closed by this method, even if exceptions are raised, the timing of the closing is not guaranteed to happen before the method returns: the closing could be done asynchronously.
One way to fix this problem is to write the results into a temporary file in the same directory, and then move the new file in place of the old one.

Exception on call hangup for landline phone

I am developing software for landline phones and full-duplex voice modems using C# and TAPI 3 library. Call answering is working fine but call hangup is throwing an exception. I did a lot of search to find solution but I could not. Following are the errors:
Exception is occurring on calling method ici.ReleaseUserUserInfo();
{"This implementation doesn't take advises (Exception from HRESULT:
0x80040003 (OLE_E_ADVISENOTSUPPORTED))"} System.Exception
{System.Runtime.InteropServices.COMException}"
My goal is to save recorded calls. One interesting thing is that if, before call hangup, I close the application, it successfully saves the recorded call.
My code:
private void BtnAnswer_Click(object sender, EventArgs e)
{
IEnumCall ec = ia[line].EnumerateCalls();
uint arg = 0;
ITCallInfo ici;
ITTerminal recordTerminal;//NY test record
try
{
ec.Next(1, out ici, ref arg);
ITBasicCallControl2 bc = (TAPI3Lib.ITBasicCallControl2)ici;
recordTerminal = bc.RequestTerminal(TapiConstants.CLSID_String_FileRecordingTerminal,
TapiConstants.TAPIMEDIATYPE_MULTITRACK,
TAPI3Lib.TERMINAL_DIRECTION.TD_RENDER);
ITMediaControl mediacontrol = (ITMediaControl)recordTerminal;
ITMediaRecord mediarecord = (ITMediaRecord)recordTerminal;
mediarecord.FileName = "a.wav";
bc.SelectTerminalOnCall(recordTerminal);
bc.Answer();
mediacontrol.Start();
}
catch (Exception exp)
{
MessageBox.Show("There may not be any calls to answer! \n\n" + exp.ToString(), "TAPI3");
}
}
private void BtnHang_Click(object sender, EventArgs e)
{
IEnumCall ec = ia[line].EnumerateCalls();
uint arg = 0;
ITCallInfo ici;
try
{
ec.Next(1, out ici, ref arg);
ITBasicCallControl bc = (ITBasicCallControl)ici;
bc.Disconnect(DISCONNECT_CODE.DC_NORMAL);
ici.ReleaseUserUserInfo();
}
catch (Exception exp)
{
MessageBox.Show("No call to disconnect!", "TAPI3");
}
}
I believe that the error code you're seeing is actually TAPI_E_NOTSUPPORTED!
According to the MSDN documentation for ITCallInfo::ReleaseUserUserInfo:
The ReleaseUserUserInfo method informs the service provider that the application has processed the user-user information obtained from the ITCallInfo::GetCallInfoBuffer method, called with the CIB_USERUSERINFO member of CALLINFO_BUFFER, and subsequently received user-user information can now be written.
Hwoever, User-user information is specific to the ISDN Q.931 standard and not all service providers support it.
Unless you specifically want to exchange this information between your client and the remote end, it is probably sufficient to simply delete the offending line of code, as it is otherwise both unused and unsupported.

IPC Cannot Find the File Specified

using IPC over local TCP to communicate from Client to a Server thread. The connection itself doesn't seem to be throwing any errors, but every time I try to make one of the associated calls, I get this message:
System.Runtime.Remoting.RemotingException: Could not connect to an IPC Port: The System cannot Find the file specified
What I am attempting to figure out is WHY. Because this WAS working correctly, until I transitioned the projects in question (yes, both) from .NET 3.5 to .NET 4.0.
Listen Code
private void ThreadListen()
{
_listenerThread = new Thread(Listen) {Name = "Listener Thread", Priority = ThreadPriority.AboveNormal};
_listenerThread.Start();
}
private void Listen()
{
_listener = new Listener(this);
LifetimeServices.LeaseTime = TimeSpan.FromDays(365);
IDictionary props = new Hashtable();
props["port"] = 63726;
props["name"] = "AGENT";
TcpChannel channel = new TcpChannel(props, null, null);
ChannelServices.RegisterChannel(channel, false);
RemotingServices.Marshal(_listener, "Agent");
Logger.WriteLog(new LogMessage(MethodBase.GetCurrentMethod().Name, "Now Listening for commands..."));
LogEvent("Now Listening for commands...");
}
Selected Client Code
private void InitializeAgent()
{
try
{
_agentController =
(IAgent)RemotingServices.Connect(typeof(IAgent), IPC_URL);
//Note: IPC_URL was originally "ipc://AGENT/AGENT"
// It has been changed to read "tcp://localhost:63726/Agent"
SetAgentPid();
}
catch (Exception ex)
{
HandleError("Unable to initialize the connected agent.", 3850244, ex);
}
}
//This is the method that throws the error
public override void LoadTimer()
{
// first check to see if we have already set the agent process id and set it if not
if (_agentPid < 0)
{
SetAgentPid();
}
try
{
TryStart();
var tries = 0;
while (tries < RUNCHECK_TRYCOUNT)
{
try
{
_agentController.ReloadSettings();//<---Error occurs here
return;
} catch (RemotingException)
{
Thread.Sleep(2000);
tries++;
if (tries == RUNCHECK_TRYCOUNT)
throw;
}
}
}
catch (Exception ex)
{
HandleError("Unable to reload the timer for the connected agent.", 3850243, ex);
}
}
If you need to see something I haven't shown, please ask, I'm pretty much flying blind here.
Edit: I think the issue is the IPC_URL String. It is currently set to "ipc://AGENT/AGENT". The thing is, I have no idea where that came from, why it worked before, or what might be stopping it from working now.
Update
I was able to get the IPC Calls working correctly by changing the IPC_URL String, but I still lack understanding of why what I did worked. Or rather, why the original code stopped working and I needed to change it in the first place.
The string I am using now is "tcp://localhost:63726/Agent"
Can anyone tell me, not why the new string works, I know that...but Why did the original string work before and why did updating the project target to .NET 4.0 break it?

c# Excel Interop alternatives to waiting to handle 0x800AC472 error

I have an application that writes many times to a formula/macro-laden workbook. It loops through some data 3 times creating, filling, saving, then closing an excel file in each iteration. While it works fine when it's the only version of itself running, if there are multiple instances of it running it has trouble.
Specifically, I'm getting a 0x800AC472 error when writing data to certain cells. It isn't the same cell or value each time but it has seemed to be on the second pass through each time. This is the relevant code:
public void SetCellValue(int row, int col, string val)
{
if (_currWorkSheet != null)
{
string parms = string.Format("row={0}; col={1}; val={2}", row.ToString(), col.ToString(), val);
for (short i = 0; i < _maxRetries; i++)
{
try { (_currWorkSheet.Cells[row, col] as Range).Value2 = val; return; }
catch (Exception ex) { HandleError(ex, parms); }
}
Exception newExc = new Exception("Too many retries attempting to set cell value.");
newExc.Data.Add("parms", parms);
throw newExc;
}
}
private void HandleError(Exception exc, string parms)
{
if (exc != null && exc.Message != null)
{
// Excel error that just needs more time to complete. http://social.msdn.microsoft.com/forums/en-US/vsto/thread/9168f9f2-e5bc-4535-8d7d-4e374ab8ff09/
if (exc.Message.Contains("0x800AC472"))
Thread.Sleep(_threadSleepMs); // Give excel a chance to catch up, then keep processing.
else
{
Exception newExc = new Exception("Unexpected Error", exc);
newExc.Data.Add("parms", parms);
throw newExc;
}
}
}
I've set the _maxRetries to 10 and the _threadSleepMs to 500 and continue to get the error, so I don't think that increasing it anymore makes sense.
I was wondering if there are alternatives to sleeping the thread to give it a chance to get "unstuck" as it were.
And maybe this would qualify as a second question but I'm not as concerned about this but, when it crashes I still perform a Close() on it in the finally block, but I still have instances of it hanging around. This is how I close it:
public void Dispose()
{
if (!_disposed)
{
if (_currWorkBook != null)
for (short i = 0; i < _maxRetries; i++)
{
try { _currWorkBook.Close(false, _missing, _missing); break; }
catch (Exception ex) { HandleError(ex, ""); }
}
if (_app != null)
{
if (_app.Workbooks != null)
for (short i = 0; i < _maxRetries; i++)
{
try { _app.Workbooks.Close(); break; }
catch (Exception ex) { HandleError(ex, ""); }
}
for (short i = 0; i < _maxRetries; i++)
{
try { _app.Quit(); break; }
catch (Exception ex) { HandleError(ex, ""); }
}
if (_currWorkSheet != null)
{
Marshal.ReleaseComObject(_currWorkSheet);
_currWorkSheet = null;
}
if (_currWorkBook != null)
{
Marshal.ReleaseComObject(_currWorkBook);
_currWorkBook = null;
}
Marshal.ReleaseComObject(_app);
_app = null;
}
GC.Collect();
_disposed = true;
}
}
It doesn't throw and error, so I was just wondering if there were any holes in it?
Thank you,
Jeff
The only solution I was able to come up with was to create a lock on the thread once it needs to use the excel functionality. This just ensured I only have one process using excel at one time. It's not perfect, especially if unrelated processes also try to use excel, but it was the only fix I could come up with.
In my experience Excel cannot be made to run reliably with multiple instances being driven from COM Interop. We have a lot of test code which we run against Excel so we've tried to get this to work. The only solution is to limit your application to one instance at a time - and even then my experience is that there is an occasional unexplained exception.
SpreadsheetGear for .NET might solve your problem. SpreadsheetGear has a "workbook set" which is roughly analogous to an Excel application, and supports any number of workbook sets being used from different threads.
You can see live ASP.NET samples here and download the free trial here if you want to try it yourself.
Disclaimer: I own SpreadsheetGear LLC
You can often get this error because you are trying to work with an Office document on a synced folder (your home folder for example in a corporate desktop)
Just copy the files to a local disk folder first (e.g. temp), and all should be OK
If you are updating the Excel workbook, or waiting for a data table or PivotTable refresh use some artificial delays
e.g
field.ClearAllFilters();
Thread.Sleep(500);
Application.DoEvents();
field.CurrentPageName = value;
Thread.Sleep(500);
Application.DoEvents();

Categories