Reputation: 476
I created a client in C# in MS Visual Studio 2022 (.NET 6) using the third-party provided API.dll file — my code compiles without any error.
The purpose of the client above is to connect to a server, which uses DCOM and OPC technologies. I have never worked with these technologies.
I successfully built my OPC server and client using OPC packages I found online. OPC server client development was straightforward.
I can not use these packages to build the client's connection to this particular Server using DCOM technology.
When I build the client with the API.dll file provided by the 3rd party and try to connect to Server, I get the following error:
Retrieving the COM class factory for component with CLSID {5044B1D9-6D96-47CD-9DD2-A8A06EB99B6C} failed due to the following error: 80040154 Class not registered (0x80040154 (REGDB_E_CLASSNOTREG)).
I was advised to register my application dll file using regsvr32
and
regasm myClient.dll /tlb:myClient.tlb
Both commands failed, indicating that it was not the correct dll file.
I did run regsvr32
on the thirdpary.dll
API file, and it worked without any problem. Even after that, when I ran my client application, it failed with the same error.
I can not understand why I should register a client DCOM application. Please advise.
Here is my code
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RegisterForComInterop>true</RegisterForComInterop>
</PropertyGroup>
<ItemGroup>
<COMReference Include="OPCBRIDGELib">
<VersionMinor>0</VersionMinor>
<VersionMajor>1</VersionMajor>
<Guid>f38628bd-c890-40fb-9098-110a235f9252</Guid>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>false</Isolated>
<EmbedInteropTypes>true</EmbedInteropTypes>
</COMReference>
</ItemGroup>
</Project>
public Monitor()
{
Console.WriteLine("Welcome to Alarm Viewer Console Program");
Console.WriteLine("Enter 'Exit' to close the program.");
// Initialize the subscription
Subscription oSubscription = new Subscription();
// Subscription oSubscription;
// Main loop
while (true)
{
Console.Write("Enter Server Name: ");
string? serverName = Console.ReadLine();
if (serverName != null && serverName.ToLower() == "exit")
{
break;
}
try
{
if (serverName != null)
ConnectToServer(serverName, oSubscription);
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
// Disconnect and clean up
DisconnectFromServer(oSubscription);
oSubscription = null;
Console.WriteLine("Program closed.");
}
void ConnectToServer(string serverName, Subscription oSubscription)
{
// Initialize the subscription if it's null
if (oSubscription == null)
{
Console.WriteLine("oSubscription is null");
// oSubscription = new Subscription();
}
oSubscription = new Subscription();
// Connect to the server
oSubscription.Server = serverName;
EventGroups oAvailableGroups;
EventGroups oGroups = new EventGroups();
EventGroup? oGroup = new EventGroup();
oAvailableGroups = oSubscription.GetAvailableGroups();
foreach (EventGroup group in oAvailableGroups)
{
oGroups.Add(group);
}
oSubscription.MaximumPriority = 9;
oSubscription.MinimumPriority = 1;
oSubscription.CheckEnabled = 1;
oSubscription.CheckInterval = 10;
oSubscription.ConnectAttempts = 1;
oSubscription.ConnectInterval = 1;
oSubscription.NotifyOnFailure = 0;
oSubscription.Activate();
oSubscription.Refresh();
Console.WriteLine("Connected to server.");
Console.WriteLine("Listening for alarm events...");
// Keep the program running until the user types 'Exit'
while (true)
{
// You can add any additional logic here if needed
// For example, you can handle events received from the server
// by implementing the event handler oSubscription_OnEvent
// Sleep for a while to avoid consuming too much CPU
Thread.Sleep(1000);
}
}
void DisconnectFromServer(Subscription oSubscription)
{
// Disconnect from the server
if (oSubscription != null)
{
oSubscription.Deactivate();
Console.WriteLine("Disconnected from server.");
}
}
private void oSubscription_OnEvent(IEventNotification pNotification)
{
// Handle event notifications here
// Display the alarm event in the console
Console.WriteLine("Alarm Event:");
Console.WriteLine($" Message: {pNotification.Message}");
Console.WriteLine($" Alarm: {(pNotification.Alarm == 1 ? "Yes" : "No")}");
Console.WriteLine($" Active: {(pNotification.Active == 1 ? "Yes" : "No")}");
Console.WriteLine($" Processed: {(pNotification.Processed == 1 ? "Yes" : "No")}");
Console.WriteLine($" Acknowledged: {(pNotification.Acknowledged == 1 ? "Yes" : "No")}");
Console.WriteLine($" Cookie: {pNotification.Cookie}");
Console.WriteLine();
}
}
Upvotes: 0
Views: 327
Reputation: 4698
You need to install Classic OPC core components. You can use any third-party library, but this installation package will register all Classic OPC-related components in the system.
Start from Matrikon OPC Explore (as an example) to test connection with the OPC Server. After successful testing you can proceed to debug your application.
Then your next step is to build your app based on .NET API Sample Client Source Code. It will allow you to create a good OPC DA (HDA, A&E) client application.
Upvotes: 0