3

I have a piece of C# code, that calls an unmanaged dll.

[DllImport("urlmon.dll", CharSet = CharSet.Ansi)]
private static extern int UrlMkSetSessionOption(int dwOption, string pBuffer, int dwBufferLength, int dwReserved);

This code exists in a windows forms control solution, which will be used in another application targeting at a large audience.

As I understand, the DllImport attribute, looks for a dll on the system, and if found, pairs the extern function to it (I mostly know how extern works in C).

How can I ensure that this dll will be found at the user's system? Should I bundle it with my application (I know how to do that)? Is it certain that it will exist, as it is included with Windows*?


*I've seen many applications crashing because of missing dlls in Windows XP and older, so I don't really trust that argument.

RaidenF
  • 3,411
  • 4
  • 26
  • 42
  • 1
    Have you checked this question? http://stackoverflow.com/questions/2292578/check-if-a-dll-is-present-in-the-system The accepted answer included code you can use for checking whether DLL exists on user's machine. – Alex Apr 13 '16 at 11:00
  • This is a particular case of a [function documented in the MSDN as part of Windows/IE](https://msdn.microsoft.com/library/ms775125) from XP onwards. Unless you are expecting to run your code on versions of Windows that have long since ceased to be supported, this *particular* function can be expected to always be present (and separately checking for it adds nothing). The *general* question is more involved. – Jeroen Mostert Apr 13 '16 at 11:46

1 Answers1

2

I'd say the prime responsible party for ensuring that the DLL exists is not your application, but your installer! At the time that your application runs, it's too late to worry about dependencies. However, if you want to fail more 'elegantly' when the installer botched, the following might be useful.


What you want to check is actually if the call will succeed. You can simply try to call the imported function in a try-catch block and see if the call succeeds. If the DLL was not found, a DllNotFoundException is thrown, and if the DLL is found but doesn't have the function then an EntryPointNotFoundException is thrown, as per the answer on How do I handle a failed DllImport?:

bool available = true;
try {
    UrlMkGetSessionOption(...test parameters...);
}
catch (DllNotFoundException)
{
    available = false;
}
catch (EntryPointNotFoundException)
{
    available = false;
}

Of course, this only works if the DLL has a function that allows you to call it with test parameters; in the case of URLMon, a decent function would be UrlMkGetSessionOption as shown in the example. If it doesn't have this, but you know when it is first called, then you can wrap that first call in a test.

But, on the other hand, what could your program reasonably do if the DLL is not present? If it's an optional feature that uses that, you could disable it, but typically if the DLL is not present/functional, then your program cannot function. I guess then the use for this is to fail fast and predictably with a friendly error message, rather than to fail later.

Community
  • 1
  • 1
MicroVirus
  • 5,324
  • 2
  • 28
  • 53
  • Thanks that's exactly what I was looking for. I was going to use clickonce, thus I don't have too much control over what the installer will require from the system, but I can configure that. – RaidenF Apr 13 '16 at 12:53