Click here to Skip to main content
15,887,376 members
Please Sign up or sign in to vote.
5.00/5 (2 votes)
See more:
Hi!

I've been struggling for two days with this problem:

I'm working with Visual Studio C++ 2005 and have added a reference (in the project properties) to my project. This reference is a dll which I compiled in C# and contains some classes. Everything works fine so far. I can access to the classes as intended. The dll thereby is a single file besides the executable program file.
If I remove the dll during runtime (or before) the program crashes when I try to access the dll. The first thing I'm wondering about is why the dotnet framework doesn't check at program startup if all references are available?

Anyways, i tried to implement my own check if the dll is existent before each access to the dll. Therefore I wrote this code:

C
private: System::Void Button_Click(System::Object^  sender, System::EventArgs^  e)
             {
                 if(!(System::IO::File::Exists("LiveDocs.dll")))
                 {
                    MsgBox_Error("Dll not found!");
                    return;
                 }

                 //return;

                 LiveDocs doc();
                 doc.Show(LiveDocs::liveDocType::Manual);
             }


Where LiveDocs is my class inside the C# dll. Now if the dll is missing I get a strange behaviour which I don't understand. The result of the file check is correct and the error message is thrown correctly if I uncomment the second return statement. But if I try to leave the function by the first return statement (second one is commented) the programm crashes with an unhandled exeption saying the dll was not found.
So it seems to me as the object of LiveDocs is instantiated even if the according code is not executed. I think this happens when the function is executed and the compiler knows that the code MAY be executed. In case of the second return statement it cannot be executed at all so it is ignored. Am I right?

But how can I check if the dll is existent during runtime?? Any ideas?

Thank you!
Mathias
Posted

Why don't you just put your code into a try/catch block and handle the exception properly?

C++
private: System::Void Button_Click(System::Object^  sender, System::EventArgs^  e)
{
    try
    {
        LiveDocs doc();
        doc.Show(LiveDocs::liveDocType::Manual);
    }
    catch (SpecialExceptionThatIndicatesDllIsntPresent ex)
    {
        // display appropriate error message
    }
    catch (Exception ex)
    {
        // for any exception that you don't want to handle in a special way
        // display appropriate error message
    }
}
 
Share this answer
 
v3
Comments
mathias.woelfel 23-May-11 10:56am    
Yes, I tried that before!

But although the error message while crashing tells me there is an System.IO.FileNotFoundException I can't catch it with
catch(System::IO::FileNotFoundException ^ex)

And even if I try to catch every exeption with
catch(...)
I've got the same behaviour like I described above.
Sergey Alexandrovich Kryukov 23-May-11 11:15am    
I added a comprehensive solution on checking up references, but you better use John's advice first. Provide full exception dump with stack and all inner exceptions (recursively). The problem could be in native code as well.

In this case, see the last paragraph of my solution.

--SA
Sergey Alexandrovich Kryukov 23-May-11 11:11am    
Good advice, a 5.
--SA
mathias.woelfel 24-May-11 4:21am    
But shouldn't the outer exeption handler catch all inner exceptions anyway? I even tried to nest several try/catch blocks arround the object instantiation what didn't help either. It seems like the FileNotFoundException is not thrown within my try block but anywhere else. Is that possible?

Coming back to your idea with the recursive catching of all inner exceptions: How would you implement this solution? Is there a possibility to find out if there are unhandled exceptions left? Or is there an exception stack which I can read out?
Just a note: even if you use project reference in Visual Studio (which is the best way to set references), during run-time is works like a reference to assembly.

To test references during run time, use System.Reflection.Assembly.GetReferencedAssemblies for any given assembly instance. For each returned instance of System.Reflection.AssemblyName you can also check System.Reflection.AssemblyName.CodeBase to compare with the executable module files you have.

In particular, you can use during run time it with the following assemblies: System.Reflection.Assembly.GetEntryAssembly(), GetCallingAssembly() or GetExecutingAssembly().

See http://msdn.microsoft.com/en-us/library/system.reflection.assembly.aspx[^].

If does not check up for dynamically loaded assemblies and native P/Invoked code. For native code, use Microsoft Dependency Walker, see http://en.wikipedia.org/wiki/Dependency_Walker[^], http://www.dependencywalker.com/[^].

—SA
 
Share this answer
 
v2
Comments
mathias.woelfel 24-May-11 4:04am    
Thank you for this detailed explanation on handling assemblys!
But my problem is another one: As I described my simple check with File::Exists alone works fine. The function returns at the specified point if the dll is not found.
But if I add the instantiation of the object to the function it throws the exception even if this part of the code is not executed.
Sergey Alexandrovich Kryukov 24-May-11 22:03pm    
Hm... Than you need to catch exception and dump it in full with exception stack. The stack will show you the line numbers, you need to indicate where the problem is. Don't forget do dump all InnerExceptions for each exception, recursively. I suspect the problem is not the absence of the DLL.

By the way, my method of check up is comprehensive. If you do something different you may risk the situation when the version of the file you're checking and the one actually referenced or loaded are different.

--SA
mathias.woelfel 25-May-11 4:23am    
Yes that is what I suspected, too. But how to implement this exeption stack if I don't know which exeptions of which type are thrown? How can I implement try&catch recursively?? I'm a little bit at a loss at the moment..
Sergey Alexandrovich Kryukov 25-May-11 4:26am    
Already implemented. See System.Exception.Stack. This is just text, will be enough.
You may go deeper using System.Diagnostic.StackTrace (MSDN page has a good code sample). Also use System.Exception.InnerException.
As InnerException is Exception, you need to get them all, recursively.

Dump it all and see. Is is clear now?
--SA
mathias.woelfel 25-May-11 5:05am    
Ok I got the point now. But when I call my function 'Button_Click' (see above) the programm crashes immediately. Means no code within the function is executed. So I've got no chance to see the content of StackTrace since it is not even executed. That brings me back to my original problem. The program seems to throw the exception somewhere else but not in my function where I try to catch it.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900