This is a continuation of https://reverseengineering.stackexchange.com/questions/31886/use-3rd-party-dll-in-my-own-application. You can see that question for background on what I'm trying to do.
I've written a basic application using a 3rd-party DLL (same one mentioned in the other question), that parses serial data sent from water meters, and, for now, just displays the parsed data in a Label on a Form.
Complete code:
public partial class Form1 : Form
{
private static D3GTech d3g = new D3GTech();
private static d3g_tech_managed.BeaconClient beaconClient = new d3g_tech_managed.BeaconClient(d3g, "");
private static d3g_tech_managed.BeaconClient beaconClientBroadcast = new d3g_tech_managed.BeaconClient(d3g);
public Form1() {
InitializeComponent();
}
private void Form1_Load(Object sender, EventArgs e) {
d3g.LoadRuntimeDefinitions(Application.StartupPath+"\\TechnicianNET.d3g");
d3g.FunctionTimeout = 0x00007530;
d3g.RetriesInterval = 0x000000C8;
d3g.FunctionRetries = 1;
d3g.RFType = RFTypes.ETMW;
d3g.SyncLength = 0;
d3g.Open(15, "baud=9600 parity=N data=8 stop=1 ");
beaconClient.BeaconArrived += new BeaconArrivedHandler(this.ReceiveBeacon);
beaconClientBroadcast.BeaconArrived += new BeaconArrivedHandler(this.ReceiveBeaconBroadcast);
}
private void ReceiveBeacon(byte fs1, byte cmdid, string data) {
label1.Text += "\n" + data;
}
private void ReceiveBeaconBroadcast(byte fs1, byte cmdid, string data) {
label3.Text += "\n"+data ;
}
private void button1_Click(Object sender, EventArgs e) {
d3g.InvokeFunctionBroadcast("DumpAll", "", beaconClientBroadcast);
}
}
When I run my application by double-clicking on the .EXE or using "Start Without Debugging", the application works perfectly.
When I run the application using "Start Debugging", the application does not receive any data from the meters.
The application does, however, successfully send the data to the meters, as can be seen in the serial monitor. That tells me that the 3rd-party library, hardware, etc., are working. Additionally, the meters do respond (serial monitor), but it appears that my code is not being "notified" that a beacon has been received.
I've seen this same behaviour also happen if another 3rd-party DLL isn't in the application folder (sending data works fine, no error or response when receiving), but that isn't the case now (since whether I start with or without debugging, the same executable in the same location, with the same files, is being run). I've verified that with the Command Line in Task Manager. Actually, after additional testing, the application is receiving the data; it just appears to be returning from the function before doing anything with it -- at least, when starting with debugging.
I've tried setting the "Working directory" in Project Properties > Debug to the bin\x86\Debug\
folder, as well as the project source code folder (which also contains all DLLs), but same behaviour. I have also tried toggling various settings on the Debug and Build tabs to try to get a different result, but same every time (Define DEBUG/TRACE constant, allow unsafe code, optimize code, generate serialization assembly, working directory, native code debugging).
The same problem happens using the Release configuration, as well. Running either configuration (Release or Debug) without debugging works fine; running either config with debugging has that problem.
I searched, but I couldn't find anything specific about an external DLL having different behaviour when running an application with vs without debugging, and most of the results complain about something working with debugging and not working without (I'm experiencing the opposite of that).
UPDATE: So, the problem appears to specifically be related to starting the application with debugging. If I start it without debugging then attach the debugger afterwards, everything seems to work fine, including breakpoints, locals, etc. While this is acceptable as a workaround, I'm interested to know what the key difference(s) is that would cause this behaviour. Also nice to be able to press F5 and do it all in one shot.
UPDATE 2: The problem doesn't appear to be the 3rd-party library at all... instead, it appears to be the this.label1.Text +=
part!(?)
I changed ReceiveBeacon
to this:
private void ReceiveBeacon(byte fs1, byte cmdid, string data) {
MessageBox.Show("Entered");
MessageBox.Show(data);
MessageBox.Show("Before Label");
this.label1.Text += "\n" + data;
MessageBox.Show("After Label");
MessageBox.Show(data);
}
Running without debugging works as you expect: Shows a message box with "Entered", click OK, then another one with the data, then a third with "Before Label", the label text is appended with the data, then two more message boxes with a string and the data.
However, running with debugging, the first, second, and third message boxes show correctly, including all the data (so the 3rd-party library is doing its job). Then nothing. No label text update, no fourth or fifth message boxes. If I set a breakpoint on MessageBox.Show("Entered");
and step through, it goes through the three message boxes normally, then highlights the label1.Text+=, and after I click Next, nothing. It appears to just return out of the function entirely.
At least, that's what happened as I was writing this. After I finished writing, I retested the exact same thing again, and now it hits the breakpoint on the first MessageBox, but stepping through doesn't even make it to the second one; it returns immediately. Nothing changed from my description in the previous paragraph to now (at least, I didn't change anything). But now I just tried combining the first three MessageBox lines into a single MessageBox.Show("Entered" + data + "Before Label");
and it's working as I described: shows the message box, then returns from the function after highlighting this.label1.Text += "\n" + data;
.
I tried that several times back-to-back, and it performed as I described. After coming here and writing this text, I went back to try again (didn't change any code), and now it's back to correctly hitting the breakpoint and showing the correct data in the Locals tab, but returning from the function immediately (not even showing a single message box). The application didn't "crash," because the "Dump All" button still work correctly, including sending data to the serial port, and getting responses from the meters.
I can't find any particular pattern... so far, it seems like behaviour changes (worsens) if I just leave it alone for some time, which doesn't make sense to me.
If I retry without debugging, it still works normally, including attaching the debugger after it loads.
Any ideas?
Thanks!
Using Visual Studio 2022 17.1.1
Target framework: .NET Framework 4.7.2