Professional OPC
Development Tools

logos

Online Forums

Technical support is provided through Support Forums below. Anybody can view them; you need to Register/Login to our site (see links in upper right corner) in order to Post questions. You do not have to be a licensed user of our product.

Please read Rules for forum posts before reporting your issue or asking a question. OPC Labs team is actively monitoring the forums, and replies as soon as possible. Various technical information can also be found in our Knowledge Base. For your convenience, we have also assembled a Frequently Asked Questions page.

Do not use the Contact page for technical issues.

Wondering if QuickOPC might be the cause of unhandled errors in my applications

More
13 Sep 2023 17:11 #12121 by wmitc2375
All the assemblies that start with OPCLabs*.dll have a version of 5.70.1012.1 in one of my applications and version 5.71.302.1 for the other. I can look into the links you sent as well.

Please Log in or Create an account to join the conversation.

More
13 Sep 2023 16:46 #12120 by support
Thank you.
The reason I have asked OPC Classic is as follows:

We have seen "weird" exceptions (such as SEHException), similar to yours, in relation to 3rd party library that is used in QuickOPC (BoxedApp SDK). In such cases, it was possible to resolve it by disabling that library - see kb.opclabs.com/How_to_disable_prerequisites_boxing .

In versions of QuickOPC up to 5.63, this library has been used for three purposes
1) "boxing" the OPC "Classic" proxies
2) "boxing" the Visual C++ runtime library - used with OPC "Classic"
3) "boxing" the OPC UA Certificate generator

Since QuickOPC version 5.70, only 1) and 2) apply. For OPC UA, we no longer need this library.

I understand that you are using 5.70 or 5.71. But, first of all, are you absolutely sure about the versions? (check Properties -> Details on the OpcLabs.* assemblies within your app binaries) And second, maybe it is still worth to go through the steps described in the linked article, just in case somehow the BoxedApp SDK still kicks in.

Besides that, I cannot think of other suggestion at the moment. Looks like a lower-level system problem. If there is antivirus software installed, couldn't it be interfering somehow?

Regards

Please Log in or Create an account to join the conversation.

More
13 Sep 2023 16:16 #12118 by wmitc2375
Thanks and I don't think so but below is the entire code for the Winform single form application. Hope this helps.


using System;
using System.Data;
using System.Windows.Forms;
using System.Configuration;
using System.IO;
using IBM.Data.DB2.iSeries;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace CoaterScaleWeightCompare
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

iDB2Connection cnDB2 = new iDB2Connection();
iDB2Command cmdDB2 = new iDB2Command();

EasyUAClient easyUAClient1;
UAEndpointDescriptor epd;
UANodeDescriptor node;
string isContactInfo = ConfigurationManager.AppSettings["is_contact_info"];
string scaleIPAddress = ConfigurationManager.AppSettings["scale_ip_address"];
int scalePort = Convert.ToInt16(ConfigurationManager.AppSettings["scale_port"]);
string opcServerHost = ConfigurationManager.AppSettings["ignition_opcserverhost"];
string opcServerEndpoint = ConfigurationManager.AppSettings["ignition_opcserverendpoint"];
string opcSeamDetectNodeId = ConfigurationManager.AppSettings["ignition_seamdetectnodeid"];
int opcServerPortNumber = Convert.ToInt16(ConfigurationManager.AppSettings["ignition_opcserverportnumber"]);
bool loggingEnabled = true;
int loggingRetentionDays = Convert.ToInt16(ConfigurationManager.AppSettings["logging_retentiondays"]);
string logPath = ConfigurationManager.AppSettings["logging_path"];
string quickOPCLicenseInfo;
string rollNumber;
int scaleWeight;
string lastRollNumber = "";



private void Form1_Load(object sender, EventArgs e)
{
try
{
lblProgramStarted.Text = DateTime.Now.ToString();
LogActivity("Program Started");
DeleteOldLogFiles();

easyUAClient1 = new EasyUAClient();
//Register the embedded resource license file to prevent QuickOPC 30 minute trial timeout
quickOPCLicenseInfo = UADocExamples.Licensing._LicensingManagement.RegisterManagedResourceWithExistenceCheck(easyUAClient1);

if (quickOPCLicenseInfo.Contains("Failure"))
{
ShowError("There was an issue registering the QuickOPC license file. Seams cannot be detected, the program must now be stopped.", true);
Application.Exit();
Application.ExitThread();
}
else
{
LogActivity("QuickOPC Version : " + typeof(EasyUAClient).Assembly.FullName);
LogActivity("QuickOPC License Key: " + quickOPCLicenseInfo);
}

epd = new UAEndpointDescriptor();
epd.Port = opcServerPortNumber;
epd.Host = opcServerHost;
node = new UANodeDescriptor(opcSeamDetectNodeId);
easyUAClient1.SubscribeDataChange(epd, node, 10000);
easyUAClient1.DataChangeNotification += easyUAClient1_DataChangeNotification;
string modbusRollNumberTagChanged = "RollNumberScanned";
easyUAClient1.SubscribeMultipleMonitoredItems(new[] {
new EasyUAMonitoredItemArguments(modbusRollNumberTagChanged, opcServerEndpoint,
opcSeamDetectNodeId, 1000)
});
}
catch (Exception ex)
{
ShowError(ex.Message + " The program will now exit.", true);
LogActivity("An error occurred. The error was:" + ex.Message);
Application.Exit();
}
}

private void ShowError(string errorMessage, bool showISContactInfo)
{
if (showISContactInfo)
{
errorMessage += isContactInfo;
}
MessageBox.Show(errorMessage);
}

private void LogActivity(string strMessageText)
{
string logFilePath = "";

if (!loggingEnabled)
{
return;
}

try
{
string logDateStamp = (DateTime.Now.Year.ToString() + ("0" + DateTime.Now.Month.ToString()).Right(2)) + ("0" + DateTime.Now.Day.ToString()).Right(2);

if (!logPath.EndsWith(@"\"))
{
logPath += @"\";
}

logFilePath = logPath + "CoaterScaleWeightCompare-Activity-" + logDateStamp + ".txt";
StreamWriter swActivity = new StreamWriter(logFilePath, true);
swActivity.WriteLine(DateTime.Now.ToString() + " - " + strMessageText);
swActivity.Close();
}
catch
{
loggingEnabled = false;
ShowError("Could not write to log file: " + logFilePath + ". The program will continue to operate with logging disabled.", true);
}
}

public void DeleteOldLogFiles()
{
try
{
LogActivity("Purging log files older than " + loggingRetentionDays.ToString() + " days from " + logPath);
DateTime testDate = DateTime.Now.AddDays(-1 * loggingRetentionDays);

DirectoryInfo dir = new DirectoryInfo(logPath);
if (dir != null)
{
foreach (FileInfo file in dir.GetFiles())
{
if (file.LastWriteTime < testDate & file.Name.StartsWith("CoaterScaleWeightCompare-Activity-") & file.Name.EndsWith(".txt"))
{
file.Delete();
LogActivity("Deleted old log file: " + file.Name);
}
}
}
}
catch (IOException ex)
{
LogActivity("Error attempting to delete old log files. Error was: " + ex.Message);
}
}

private void easyUAClient1_DataChangeNotification(object sender, EasyUADataChangeNotificationEventArgs e)
{
// if exception, do nothing.
if (e.Exception != null)
{
return;
}

if (!e.AttributeData.HasValue)
{
return;
}

// if no attribute data, do nothing.
if (e.AttributeData.Value == null)
{
return;
}

// try casting attribute data as a booleana and if false, seam detect reset event, do nothing.
try
{
if (Convert.ToString(e.AttributeData.Value) == "")
{
return;
}
}
// if unable to cast to string, not what we need to be processing, do nothing.
catch
{
return;
}

object state = e.Arguments.State;
try
{
if (Convert.ToString(state) != "RollNumberScanned")
{
return;
}
}
catch
{
//if not roll number scanned state, return.
return;
}

try
{
if (Convert.ToString(e.AttributeData.Value) != "")
{
rollNumber = Convert.ToString(e.AttributeData.Value);
int startPos = rollNumber.IndexOf("R");
rollNumber = rollNumber.Substring(startPos);

rollNumber = rollNumber.Replace("R", "");

if (rollNumber == lastRollNumber && lastRollNumber != "")
{
return;
}

if (lastRollNumber == "")
{
lastRollNumber = rollNumber;
return;
}

lastRollNumber = rollNumber;

}
}
catch
{
}

try
{
lblBarcodeRead.Text = DateTime.Now.ToString();
lblBarcodeData.Text = rollNumber;

scaleWeight = 0;
string scaleWeightString = GetScaleWeight(scaleIPAddress, scalePort, "P" + "\r\n");
scaleWeightString = scaleWeightString.Replace("1G", "").Replace("lb", "").Replace("\n", "").Replace(" ", "").Replace("M
", "");
if (scaleWeightString != "")
{
scaleWeight = Convert.ToInt32(scaleWeightString);
CompareWeightWithCAMS(rollNumber, scaleWeight, ref cnDB2, ref cmdDB2);
lblComparedWithCams.Text = DateTime.Now.ToString();
LogActivity("Called CompareWeightWithCAMS - Roll Number: " + rollNumber + ", Weight: " + scaleWeight.ToString());
}

lblScaleWeightRead.Text = DateTime.Now.ToString();
lblScaleData.Text = scaleWeight.ToString();
}
catch (Exception ex)
{
LogActivity("Error: " + ex.Message);
}
}

string GetScaleWeight(string ipAddress, int port, String message)
{
try
{
// Create a TcpClient.
// Note, for this client to work you need to have a TcpServer
// connected to the same address as specified by the server, port
// combination.
System.Net.Sockets.TcpClient tcpClient = new System.Net.Sockets.TcpClient();
tcpClient.Connect(ipAddress, port);
tcpClient.SendTimeout = 5000;
tcpClient.ReceiveTimeout = 10000;

// Translate the passed message into ASCII and store it as a Byte array.
Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
// Get a client stream for reading and writing.
System.Net.Sockets.NetworkStream stream = tcpClient.GetStream();
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length);
//// Receive the TcpServer.response.
//Buffer to store the response bytes.
data = new Byte[18];
//// String to store the response ASCII representation.
String responseData = String.Empty;
String lastResponse = String.Empty;
//// Read the first batch of the TcpServer response bytes.
bool keepReading = true;
int x = 1;
while (keepReading)
{
Int32 bytes = stream.Read(data, 0, data.Length);
lastResponse = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
responseData += lastResponse;
//MessageBox.Show(string.Format("Received {0}: {1}", x, responseData));
x++;

if (responseData.Contains("lb"))
{
keepReading = false;
}

}
// Close everything.
stream.Close();
tcpClient.Close();
return responseData;
}
catch (System.Net.Sockets.SocketException e)
{
LogActivity("Error: " + e.Message);
return "0";
}
catch (ArgumentNullException e)
{
LogActivity("Error: " + e.Message);
return "0";
}

}

void CompareWeightWithCAMS(string rollNumber, int weight, ref iDB2Connection cnDB2, ref iDB2Command cmdDB2)
{
try
{
if (cnDB2.State != ConnectionState.Open)
{
string CAMSConnectionString = ConfigurationManager.ConnectionStrings["CAMS"].ConnectionString;
cnDB2.ConnectionString = CAMSConnectionString;
cnDB2.Open();
cmdDB2.Connection = cnDB2;
cmdDB2.CommandType = CommandType.StoredProcedure;
cmdDB2.CommandText = "CAMSPGM.COMPARESCALEWEIGHT";
}


cmdDB2.Parameters.Clear();
cmdDB2.CommandTimeout = 0;
cmdDB2.Parameters.Add("ROLLNUMBER", rollNumber);
cmdDB2.Parameters.Add("WEIGHT", Convert.ToString(weight));
cmdDB2.ExecuteNonQuery();
}
catch (Exception ex)
{
LogActivity("Error: " + ex.Message);
}
}

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
const string message =
"Closing this program while the coater is in operation will prevent rolls from being weighed and wil result in a loss of quality control information! Are you sure that you would like to close this application?";
const string caption = "Confirm Close Application";
var result = MessageBox.Show(message, caption,
MessageBoxButtons.YesNo,
MessageBoxIcon.Question);

// If the no button was pressed ...
if (result == DialogResult.No)
{
// cancel the closure of the form.
e.Cancel = true;
}
else
{
LogActivity("User confirmed closing the program.");
}
}
}
}

static class Extensions
{
public static string Right(this string value, int length)
{
return value.Substring(value.Length - length);
}
}

Please Log in or Create an account to join the conversation.

More
13 Sep 2023 16:11 #12117 by support
Thanks, I understand that, this is "our" part. My question was whether you, in your code, are actually doing OPC "Classic" connections (using objects such as EasyDAClient).

Regards

Please Log in or Create an account to join the conversation.

More
13 Sep 2023 14:25 #12111 by wmitc2375
I do see it referenced in the References node of the Solution in Visual Studio -

App_Web_OpcLabs.EasyOpcClassicRaw.amd64
App_Web_OpcLabs.EasyOpcClassicRaw.x86

I am not sure how those got there or if they are being used though, possibly through installing the OPCLabs.QuickOPC package with NuGet Package Manager?

Does that help? Glad to provide more information as needed.

Please Log in or Create an account to join the conversation.

More
13 Sep 2023 14:08 #12109 by support
Hello.

I can see OPC UA-related calls in the stack; I have a question before I can answer: Do you also use OPC "Classic" in this application anywhere?

Regards

Please Log in or Create an account to join the conversation.

More
13 Sep 2023 13:47 #12108 by wmitc2375
I have a few applications that use your product. One is a slightly older app so it still needs updating to the latest but below are the versions being used -
OpcLabs.EasyOpcUA, Version=5.70.1012.1
OpcLabs.EasyOpcUA, Version=5.71.302.1

I was recently made aware that on occasion the operator on the production line has found the programs to no longer be running and is needing to restart the programs. I checked the Windows Application Event Log and find at those times there are unhandled exceptions being logged. Below is an example. I cannot find (yet) any particular time of day, length of time the program has been running, etc. that might tell me why it crashes. Sometimes the program will run for days without an issue and other times it might crash and have to be restarted twice in a 24 hour period. Please let me know if this might be something I can solve with an update to QuickOPC. I did try using Visual Studio 2019 to do performance profiling and did not see what appeared to be memory leaks which I thought it might be since researching that exception says low resources on a computer can cause. My applications looks to keep a very small memory footprint of around 45mb and 96mb respectively. Thank you for your help!

Application: BackPrintInterface.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.Runtime.InteropServices.SEHException
at OpcLabs.EasyOpc.UA.Implementation.NetSdk.Client.EasyUAClientEngine.GetMonitoredItemEntry(OpcLabs.EasyOpc.UA.Implementation.NetSdk.Client.NetSdkEasyUAClient, Int32)
at OpcLabs.EasyOpc.UA.Implementation.NetSdk.Client.EasyUAClientEngine.InnerUnsubscribeMonitoredItems(OpcLabs.EasyOpc.UA.Implementation.NetSdk.Client.NetSdkEasyUAClient, Int32[])
at OpcLabs.EasyOpc.UA.Implementation.NetSdk.Client.EasyUAClientEngine.UnsubscribeMonitoredItems(OpcLabs.EasyOpc.UA.Implementation.NetSdk.Client.NetSdkEasyUAClient, Int32[])
at OpcLabs.EasyOpc.UA.Implementation.NetSdk.Client.NetSdkEasyUAClient.InternalUnsubscribeAllMonitoredItems()
at OpcLabs.EasyOpc.UA.Implementation.NetSdk.Client.NetSdkEasyUAClient.InternalDispose(Boolean)
at OpcLabs.BaseLib.Internal.DisposableObject.Dispose(Boolean)
at OpcLabs.BaseLib.Internal.DisposableObject.Finalize()


Faulting application name: BackPrintInterface.exe, version: 1.0.0.0, time stamp: 0x63e3ca19
Faulting module name: clr.dll, version: 4.8.4645.0, time stamp: 0x648f709e
Exception code: 0xc0000006
Fault offset: 0x00026619
Faulting process id: 0x1854
Faulting application start time: 0x01d9e2001ec97ae4
Faulting application path: \\ENTDFS01\Applications\Mperia\Sites\SD\BackPrintInterface.exe
Faulting module path: C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
Report Id: ce8267d7-9654-4b7c-a7a1-bf07306d5c8d
Faulting package full name:
Faulting package-relative application ID:
Windows cannot access the file for one of the following reasons: there is a problem with the network connection, the disk that the file is stored on, or the storage drivers installed on this computer; or the disk is missing. Windows closed the program BackPrintInterface because of this error.

Program: BackPrintInterface
File:

The error value is listed in the Additional Data section.
User Action
1. Open the file again. This situation might be a temporary problem that corrects itself when the program runs again.
2. If the file still cannot be accessed and
- It is on the network, your network administrator should verify that there is not a problem with the network and that the server can be contacted.
- It is on a removable disk, for example, a floppy disk or CD-ROM, verify that the disk is fully inserted into the computer.
3. Check and repair the file system by running CHKDSK. To run CHKDSK, click Start, click Run, type CMD, and then click OK. At the command prompt, type CHKDSK /F, and then press ENTER.
4. If the problem persists, restore the file from a backup copy.
5. Determine whether other files on the same disk can be opened. If not, the disk might be damaged. If it is a hard disk, contact your administrator or computer hardware vendor for further assistance.

Additional Data
Error value: C0000034

Please Log in or Create an account to join the conversation.

Moderators: support
Time to create page: 0.171 seconds