Link to home
Start Free TrialLog in
Avatar of jjsather
jjsather

asked on

Detect if DLL Reference is Valid on Client Machine


When my exe is on a client machine, I want to see if a reference in the program is valid. Mine happens to be for SMO, but it could be anything. In my project, I've added the necessary dll references. My code is follows...

Imports Microsoft.SqlServer.Management.Smo

Private Function DoesSMOExist() As Boolean
    Try
        Dim oServer As New Server() ' See if SMO dlls are even present on the machine.
        Return True
    Catch ex As Exception
        Return False
    End Try
End Function

Open in new window


I want my Try-Catch to return true or false, based on if a new object to this particular reference can be created. Instead, I get an unhandled exception that pops up a message, which I definitely want to avoid showing the users. The text is as follows...

System.IO.FileNotFoundException: Could not load file or assembly Microsoft.SqlServer.Smo, Version 10.0.0.0...

Anyway, I don't need this to only work for this particular reference/object, but I want to know how to do it for *any* reference/object to determine if a client machine can handle it. I don't want to put the dlls on the client machine, nor do I want to search the registry (could be multiple places), nor do I want to see if a certain dll is in a certain location (could be multiple places).

I only want to detect if a given machine can reference (and create) a given DLL reference without popping up an ugly message.

Anyone know how to do it? Or can't it be done?
Avatar of Todd Gerbert
Todd Gerbert
Flag of United States of America image

Yeah, you would get an exception if a client is missing a DLL before any of your code ever runs - I'm not sure there's anyway to trap that exception since it's thrown by the runtime before your code ever runs.

You could create a stub application (which does not reference anything else) to attempt to use System.Reflection to load a particular library, and if successful you know the necessary DLL is present and then use Diagnostics.Process to start your main (i.e. actual) application. Otherwise you can show a meaningful error message to the user.
>> I'm not sure there's anyway to trap that exception since it's thrown by the runtime before your code ever runs.

The phrase I'm not sure is key here, there could be a way I just don't know what it is. ;)
Avatar of jjsather
jjsather

ASKER


For what it's worth, the exe pulls up fine and runs. However, the moment that function is called, I get the ugly MS message. (And maybe that's what you meant, but I just wanted to clarify.)

Thanks for the input, but we'd really like to keep it all internal to the app, if possible, and fairly clean. Though like I wondered above, maybe it's not possible. At the very least, I assumed there'd be a way to suppress that message, but maybe not.
SOLUTION
Avatar of Todd Gerbert
Todd Gerbert
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial

I tried the ReflectionOnlyLoad, which works if my libFullName is this value...

"Microsoft.SqlServer.Smo, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91"

But my concern is Smo has different versions, so this will only catch the one version, right?

Otherwise, I like the idea of a global exception handler (assuming it can catch this problem.) But can I have it only catch this error, or will it handle every single error, thereby ignoring all the other Try-Catch statements in my code?

After googling it, I'm a bit confused. What's the cleanest way to implement a global exception handler?
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial

Thanks for the unhandled exception error. To learn it, I gave it a try, without worrying about multithreads. When running through VS, I get "Your message" and it puts the next line on the unhandled exception. But once I create an exe, I don't get the "Your message" and it instead crashes. Are unhandled exceptions only supposed to work in VS, but not in an exe? If so, then it's very limited in it's helpfulness.

So does anyone know why much tweaked code works above? I'm still scratching my head on it.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial

The point of is to see if SMO exists on the machine, so including the dlls would defeat the purpose.

You made me wonder if it was because I'd been using a debug exe on the client. So I ran a release exe on the test machine, but the app still loads, even though it has a references to dlls that don't exist on the machine. So while I hear what you're saying, the real life situation is different.

To make sure it wasn't SMO only, I  added a reference to an unrelated 3rd party control and created a new object of it in the code, and the same things occurs -- app loads fine, and only get an error when I try to create the object in code. And if I nest it in a separate function, I can trap it fine.

So even with the release exe, I appear to be fine to nest my call to create a New Object to a reference dll to see if it exists. It doesn't really make sense to me, but it works.

I'll gladly take any more input on this mystery and/or I'd be curious if someone can verify it with their own code.
It works, but not sure why.