Capture debug output generated by 3rd-Party Library in C# - c#

My winform application incorporates a 3rd-party dll (under the .NET 4.5) made by a device manufacturer in which I can use the exposed functions of its class to communicate with the device. But due to their crappy design once any function might fail no error detail can be retrieved from the class itself, but the class somehow put some information into the console window (appeared in the Output tab under Debug filter) in case of anything wrong.
Now the problem is, the application can only be executed on the computer that is authorized to communicate otherwise the class won't initiate. So when I test my application on the trusted computer, I can only know that some functions return false but no debug info available. I've tried to add TraceListener to Trace.Listeners but nothing shows from this answer, I also tried Debug.Listeners with no result even I manually flushes after each while.
System.Diagnostics.Trace.Listeners.Add(new System.Diagnostics.TextWriterTraceListener("debug.txt"));
System.Diagnostics.Trace.AutoFlush = true;
The DebugView won't generate anything either, I don't know it's because I don't know how to properly use this tool or not. I just opened it, and nothing shows whatever I do to my application.
I'm highly suspicious that this DLL might just use some try...catch snippet to capture its own exceptions and output those info not by using Debug.Write(). What else I can do? I simply can't just install another Visual Studio on that trusted machine and debug my application there.

Try adding a First-Chance Exception Handler:
using System;
using System.Runtime.ExceptionServices;
class Example
{
static void Main()
{
AppDomain.CurrentDomain.FirstChanceException +=
(object source, FirstChanceExceptionEventArgs e) =>
{
Console.WriteLine("FirstChanceException event raised in {0}: {1}",
AppDomain.CurrentDomain.FriendlyName, e.Exception.Message);
};
How to: Receive First-Chance Exception Notifications

Related

C# .NET app launch exception when referenced library is missing

I have a C# .NET app that makes calls into a 3rd party library. The app compiles and runs fine when the library is present, but halts on launch when it isn't.
The user has to install the referenced program separately from my program, so I would like to be able to warn the user that my program won't operate properly if the referenced program hasn't been installed.
I have tried checking the registry for the appropriate entries, and I have tried instantiating the reference object and making a simple method/property call inside a try/catch block, but these never get a chance to work, as Windows pops an exception when it tries to load the referenced library on program startup.
Is there any way I can catch this exception and warn the user nicely that the required program needs to be installed?
TIA,
Frank
So the answer, at least for my issue, was pretty simple once I really understood the problem. My C# .NET app crashed on load when a referenced library was missing. After looking through the above comments and doing some more reading, I discovered that .NET apps by default don't load reference libs until they are needed, so what was happening to me shouldn't be happening. After looking a little more closely at my code, I found this:
//private BCObject bc = null; //11/12/22 assigning bc crashes when BC not installed
private BCObject bc; //11/12/22 this doesn't, so can chk later in frmMain.Shown()
The commented-out line caused .NET to load the referenced dll, and when it failed, I got an unhandled exception. After some trial-and-error, I figured out that I could replace it with the uncommented line, which puts the 'bc' object at frmMain scope, but doesn't trigger a load because it's just a declaration, not a call. This allowed me to write the following in the frmMain.Shown() event:
private void frmMain_Shown(object sender, EventArgs e)
{
//11/12/22 added dummy call to BC object to check for pgm install. Can't use registry to check
bInitialized = true;
UpdateControls();
//string logstr = string.Format("Checking install status of Bridge Composer....", programDisplayName);
//IsProgramInstalled("BridgeComposer");
string logstr = string.Format("Checking Bridge Composer install status ....");
try
{
if (bc == null)
{
bc = new BCObject(); //this will cause an exception if BC not installed
}
bc.Noui = true;
logstr += "INSTALLED";
AppendToLog(logstr, Color.Green);
bBridgeComposerAvail = true;
}
catch (Exception)
{
logstr += "NOT INSTALLED! See https://bridgecomposer.com/Download.htm";
AppendToLog(logstr, Color.Red);
bBridgeComposerAvail = false;
}
if (chkFTP.CheckState == CheckState.Checked)
{
DoFtpUrlCheck();
}
//added 11/11/17
if (chkEmail.CheckState == CheckState.Checked)
{
DoEmailListFileCheck();
}
//moved to bottom 11/11/17
UpdateControls();
}
Here I instantiate the declared 'bc'object using
bc = new BCObject(); //this will cause an exception if BC not installed
And now this is where .NET attempts to load the library. If it exists, great. If it doesn't, then the exception gets handled properly - yay!
This approach also solved another problem, in that previously I had attempted to do this by checking for a registry entry. This works when the 32-bit version of the library is installed, because my app is 32-bit and thus the library registry entries are in the same registry hive that my app accesses by default. However, if the user installs the 64-bit version of the library, then by default my app can't see the registry entries, and thinks the library is missing even when it isn't. Moreover, my previous solution only worked when the registry key search succeeded, which makes it no solution at all.
.NET is happy to load either the 32-bit library or the 64-bit library and the change I made to delay the load operation into frmMain.Shown() works fine for either 'bitness' library.

Memory dump using Ping .net

I'm trying to do a ping to a server in a Windows Forms Application but when my program is running, I have memory dump on my computer. Very, very strange.
In my method I only have:
private void CheckServer()
{
this.txResponse.Text = "";
IPAddress IpAdress = IPAddress.Parse("anAdress");
Ping ping = new Ping();
PingReply pingToReply = ping.Send(IpAdress);
if (pingToReply.Status == IPStatus.Success)
txResponse.Text = pingToReply.Status.ToString();
}
I really don't understand what is going on.
I'm using Visual Studio 2012 with .NET Framework 4.5 on Windows 8.If it is necessary more information, please let me know.
Verify that the parsing of the IP Address is successful; otherwise check the surrounding processing outside of the CheckServer method.
Ahhh, the joys of programming having a program blow up when there is absolutely nothing wrong with the code... (your code looks fine other than putting a try/catch block around it)
It could be a hardware issue (memory, disk etc), bad dll, or any number of things that go bump in the night. I assume you have tried rebooting your computer, and pinging your server at the DOS prompt. If not do so.
One thing you could try is to call ping.exe directly with a command line/ip of your choice synchronously or asynchronously, see http://www.codeproject.com/Articles/25983/How-to-Execute-a-Command-in-C and then parse the output to get what you need (lines starting with "Reply from" or "Request timed out." or even the % loss line.
Another thing to try is bypass the c# Ping and PingReply calls entirely and use net sockets and a timer, see http://sourceforge.net/projects/pingutil/?source=typ_redirect particularly the ping.cs file.
These solutions would allow you to potentially write around the problem, but it does not necessarily solve the problem at hand, which does not appear to programming related from the code you have provided.
OK, other thoughts... 1)Do a rebuild all on your project 2) Try compiling using an older version of .NET 3) Create a new project and copy block the source into the newly created files. 4) run the project on another computer to see if you get the same results. Any exception error that may or may not be generated should never cause a core dump.
Yet another option is to analyze the core dump, for an application, see: http://sourceforge.net/projects/core-analyzer/ and also check out
Tool for analyzing java core dump
Worse comes to worse, you may have to reload Visual Studio and/or .NET.

Running same C# application twice

The application is a form application and it is too complicated. It is mostly used to connect to a database with an user interface. It also uses third party dlls.
I copied my VS C# application`s bin folder to my desktop.
"C:\Users\asd\Desktop\bin"
After that, I made some changes in my solution and building it, I again copied the application`s bin file under C:\;
"C:\bin"
Now when I run "C:\Users\asd\Desktop\bin\Debug\LIVE.exe" and let it remain open I can`t run "C:\bin\Debug\LIVE.exe". There is no error when I try to open the second .exe file. It simply does nothing.
I want both of the applications to be open at the same time.
Depending on the application, there are ways to prevent execution of a second instance (I have actually implemented the described behaviour in production code) so check the production specs of the application to see if that's a desired behaviour on client machines.
Because it's using a database connection and third party DLLs, there may be other specific limitations in place preventing proper execution, so check whether any exceptions are being cuaght by hooking into the FirstChanceException (WARNING: Never use this code outside a debug context!)
#if DEBUG
static Program()
{
AppDomain.CurrentDomain.FirstChanceException += (sender, e) => { };
}
#endif
Insert this into your Program class, or whichever class houses the Main method (and rename it if it's not Program of course) and then breakpoint the opening of the handler - this will often catch lots of exceptions you're better off not worrying about, but it may also clue you in if there is a problem keeping your code from starting.
As always, make sure to run this from within VS's Debug, so as to see any exceptions as they occur.

Debugging Help: Wrapped c++ DLL running fine in one application, crashing another

I'm migrating some C# Demo Code from a Command Window Application to an WPF Application. The Demo Code is accessing a wrapped unmanaged C++ Library. The library is provided by a third party, so I don't have access to the code.
While the Demo Code is running fine, the exact same code crashes in my WPF application after a while. The library is accessed, some configuration files are loaded but when I'm calling a certain method my application is throwing an error (I had to enable "Unmanaged Code Debuggin" to see it):
First-chance exception at 0x7726c41f in Application.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x279ce1b4..
SCAPE exception caught: bad allocation
This is the part where the error is thrown:
unsafe
{
fixed (S_DATA* pim = &_im)
{
bool success = false;
try
{
success = RunAnalytics(_im); // <--- returns false, error message in debugger
}
catch (Exception ex)
{
throw new ScrException("ERROR: Unmanaged exception", ex);
}
}
}
Both applications are running on ".NET Framework 4.0 Client Profile".
Any hints how to proceed from here on? I'm out of ideas...
Edit:
I spent the last days setting up different scenarios trying to figure out, what's the source for the issue.
Original WPF in Original Solution > fails
Original WPF in Dummy Solution > works
Dummy CMD in Original Solution > works
Dummy CMD in Dummy Solution > works
Minimal WPF in Dummy Solution > works
Minimal WPF in Original Solution > works
I'm not really any wiser...
Edit 2: After a long, long time I figured it out - a post-build script interfered with some local resources that were copied on top of one another, so I was using an outdated configuration file with some new settings... not a very satisfying solution.

SharePoint fails to load a C++ DLL on Windows 2008

I have a SharePoint DLL that does some licensing things and as part of the code it uses an external C++ DLL to get the serial number of the hardisk.
When I run this application on Windows Server 2003 it works fine, but on Windows Server 2008 the whole site (loaded on load) crashes and resets continually. This is not Windows Server 2008 R2 and is the same in 64 or 32 bits.
If I put a Debugger.Break before the DLL execution then I see the code get to the point of the break and then never come back into the DLL again. I do get some debug assertion warnings from within the function, again only in Windows Server 2008, but I'm not sure this is related.
I created a console application that runs the C# DLL, which in turn loads the C++ DLL, and this works perfectly on Windows Server 2008 (although it does show the assertion errors, but I have suppressed these now).
The assertion errors are not in my code but within ICtypes.c, and not something I can debug.
If I put a breakpoint in the DLL it is never hit and the compiler says:
"step in: Stepping over non user code"
If I try to debug into the DLL using Visual Studio.
I have tried wrapping the code used to call the DLL in:
SPSecurity.RunWithElevatedPrivileges(delegate()
But this also does not help.
I have the source code for this DLL so that is not a problem.
If I delete the DLL from the directory I get an error about a missing DLL. If I replace it, back to no error or warning just a complete failure.
If I replace this code with a hardcoded string the whole application works fine.
Any advice would be much appreciated, I can't understand why it works as a console application, yet not when run by SharePoint. This is with the same user account, on the same machine...
This is the code used to call the DLL:
[DllImport("idDll.dll", EntryPoint = "GetMachineId", SetLastError = true)]
extern static string GetComponentId([MarshalAs(UnmanagedType.LPStr)]String s);
public static string GetComponentId()
{
Debugger.Break();
if (_machine == string.Empty)
{
string temp = "";
id= ComponentId.GetComponentId(temp);
}
return id;
}
This could be security related:
An important point is that it works in a console app.
In a console app RunWithElevatedPrivileges has no effect since it emulates the app pool user for your worker process, a user that should have no special rights on the box itself.
In contrast a console app runs in context of the logged in user.
Try emulating a user with rights like when you run the console application specified here (with Undo() inside try/finally mind you!). When obtaining the token you can create an SPUserToken and establish site context using the SPSite constructor that takes a GUID and a SPUserToken
Theres several examples out there documenting this approach, here for example.
EDIT: oh and the reason it worked on 2003 could be that your app pool account had way too many rights ;-)
Why not use WMI to get the serial number of hard disk, thus avoids execution of unmanaged code. See this sample How to Retrieve the REAL Hard Drive Serial Number
That non-deterministic crashing behavior is often seen with memory overwrites/corruption; sometimes it matters (crash), sometimes you get lucky.
You might want to check into getting a crash dump and analyze it with WindDbg. Since you have the source you could re-build it with the various stack, heap memory protection and warning systems enabled (depending on your compiler) and see what you get.
I'd find out if it is a User Account Control related problem, you can try to disable it.
2003 doesn't have UAC.
Your app pool account might not have the right to retrieve this information?
In visual studio, go into the properties of your executable assembly, and under the debug tab, check the enable debugging unmanaged code option.
If the method your are importing belongs to a class, you need to add the mangled C++ name (e.g. 2#MyClass#MyMethod?zii) as an entry point to the DllImport attribute (run depends on the native DLL to get it).
You do not need C++ for that: http://www.codeproject.com/KB/cs/hard_disk_serialno.aspx
If i put a breakpoint in the DLL it is
never hit and the compiler says :
"step in: Stepping over non user code"
That's the debugger, not the compiler, and if you configured it properly it wouldn't do that. Look for the options calls "Use native debugging" and "Just my code". The first one should be on and the second one off.
This problem may happen due to one of the problems listed below.
the web part may not have the right permissions to call the DLL or
you may not have set the appropriate trust level for your SharePoint site.
For the permission you can use impersonation and for the trust level below site can help you.
http://msdn.microsoft.com/en-us/library/dd583158(office.11).aspx
I made a new C++ DLL from scratch which works fine when referenced as a console application on Windows Server 2003 and Windows Server 2008, but as soon as I reference it from the DLL in SharePoint the same things happens and it won't run.
It does find the DLL, but I think it has no permissions to execute it, even if I put it into the My Documents section and reference it directly!

Categories

Resources