5

I have run into this issue too many times and need this to be an automated approach:

I have multiple DLL files that are constantly being built/changed that multiple projects use.

I have created a C# application that detects if the DLL files are present and warns the operator if they are not and kills the program. In this C# application, I want it to also check to determine if it is a "debug" version - in other words it would crash if it ran on an end users computer.

Now I have been searching high and low and found a few possible solutions, but they all fall through.

Assembly.LoadFrom(string) does not work for unmanaged code. I can use this to test against the managed DLL files but not the C++ ones.

I thought I might be able to use Dependency Walker or similar program to run within my application to give me the data of the assembly references, unfortunately, the depends.exe console only outputs to a file (and then I would have to read in each file and parse it for my data (very intensive plus I have to include the depends.exe and DLL files in my projects)), furthermore, it doesn't seem to output the data I really want (or at least I wasn't able to make it).

Also tried dumpbin, but I can't seem to get it to run on my machine.

I also found some links that were supposed to give me the source for Dependency Walker. Unfortunately they all turned up dead. I wouldn't think this is that hard of a thing to do, but for whatever reason I am having quite the difficulty figuring out how automate this.

Some source links that have been helpful to me, but none of them have solved the issue with unmanaged assembly data.

Community
  • 1
  • 1
GregM
  • 3,624
  • 3
  • 35
  • 51
  • There's nothing C++-specific about DLLs- all code that compiles to a native format is DLL. – Puppy Aug 01 '11 at 19:38
  • Correct, but managed vs unmanaged there are differences and this is where the issue arises... managed I can use Assembly.FromFile() which will return me the assembly data of a dll (see links above) unmanaged I cannot, I am looking for the equivalent so I can use the data similar to how dependency walker uses it – GregM Aug 01 '11 at 20:01
  • Sure, I understand that. I'm just saying that for unmanaged DLLs, C++ is not relevant.# – Puppy Aug 01 '11 at 20:14
  • 1
    More appropriate is "Thanks for correcting the tags on the question, as they were incorrect, and teaching me something this fine day". – Puppy Aug 01 '11 at 21:18
  • yeah no, seeing how that's inaccurate, The majority of c# users that reference unmanaged code use c++ – GregM Aug 02 '11 at 12:51

2 Answers2

1

If you know the names of all the DLLs (because, for example, you ran Dependency Walker) you can just use LoadLibrary to check for unmanaged DLLs.

[DllImport("kernel32.dll")]
static extern IntPtr LoadLibrary(string dllToLoad);

[DllImport("kernel32.dll")]
static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, uint dwFlags);
const UInt32 DONT_RESOLVE_DLL_REFERENCES = 0x00000001;
const UInt32 LOAD_LIBRARY_AS_DATAFILE = 0x00000002;
const UInt32 LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008;

[DllImport("kernel32.dll")]
static extern bool FreeLibrary(IntPtr hModule);

[DllImport("kernel32.dll")]
static extern UInt32 GetLastError();

void CheckUnmanagedDll(string DllName)
{
    IntPtr hModule = LoadLibrary(DllName);
    if (hModule.Equals(IntPtr.Zero))
        MessageBox.Show("Can't find " + DllName);
     FreeLibrary(hModule);
 }
Ed Bayiates
  • 11,060
  • 4
  • 43
  • 62
  • Sorry, Don't think I made what I need to do clear.... I can load in and use a dll just fine, I want to check the dlls ASSEMBLY to determine if it references any Debug dlls – GregM Aug 01 '11 at 19:40
  • this is what I can get from dependency walker... as you can see referenced to Debug DLLS will only be on computers with debuggers installed API-MS-WIN-CORE-DEBUG-L1-1-0.DLL API-MS-WIN-CORE-ERRORHANDLING-L1-1-0.DLL API-MS-WIN-CORE-FIBERS-L1-1-0.DLL API-MS-WIN-CORE-FILE-L1-1-0.DLL API-MS-WIN-CORE-HANDLE-L1-1-0.DLL API-MS-WIN-CORE-HEAP-L1-1-0.DLL API-MS-WIN-CORE-IO-L1-1-0.DLL API-MS-WIN-CORE-LIBRARYLOADER-L1-1-0.DLL API-MS-WIN-CORE-LOCALIZATION-L1-1-0.DLL API-MS-WIN-CORE-MEMORY-L1-1-0.DLL API-MS-WIN-CORE-MISC-L1-1-0.DLL API-MS-WIN-CORE-NAMEDPIPE-L1-1-0.DLL ... – GregM Aug 01 '11 at 19:54
  • 1
    Yes, and you can use my code above to check for any of those. If they do not exist you can avoid a runtime error and react the way you want to. If you are looking to read the import tables like DependencyWalker does, here's an example: http://win32assembly.online.fr/pe-tut6.html – Ed Bayiates Aug 01 '11 at 19:57
  • I think I understand where your going with "use code above to check" your saying if there is a specific dll such as the first one dependcy walker found "API-MS-WIN-CORE-DEBUG-L1-1-0.DLL" is not found then return a error.... this approach may work, but would assume it would not work in all cases There are many different dlls that could be referenced based on many different compiler settings and includes within the dlls... My approach was going to look for ANYTHING referencing "debug" within the references, this way no versions,types,or differences would matter, if it contains "debug" thenerror – GregM Aug 01 '11 at 20:09
  • I will investigate your links more and see if this is a solution... looks very tedious from initial view, Reason I posted this question was because I assume there's already a solution for this instead of parsing every bit of the file – GregM Aug 01 '11 at 20:11
  • 1
    I found some better sources here: http://archive.msdn.microsoft.com/mag200202Windows – Ed Bayiates Aug 01 '11 at 20:20
  • -That does it, The article includes some code examples and from within that I can use the PE to capture if the referenced files from vs are the 'd' version or not, should be enough to get me by! Thank you for your help – GregM Aug 01 '11 at 20:59
1

Use GetModuleHandle to check for the presence of a DLL with the given name. If you want to know if it's a debug version or not, then you need to compile that information into the EXE and check for it somehow. "Debug" vs. "Release" is not a concept built-in to PE format; it's just a set of compile options. Many people put a flag in the version information to indicate whether it's an internal vs. public release.

P/Invoke reference for GetModuleHandle

tenfour
  • 36,141
  • 15
  • 83
  • 142
  • Sorry, Don't think I made what I need to do clear.... I can load in an use a dll just fine, I want to check the dlls ASSEMBLY to determine if it references any Debug dlls – GregM Aug 01 '11 at 19:39
  • Just when I think I understand your question, I realize it's a ridiculous question. At this point I'll just give up. If you want to check DLL dependencies, just load the DLL. If it fails, look at the error code. The OS has dependency checking code already; no need to reinvent that wheel. If you're checking for an EXE... well, wait why would anyone want to do that? – tenfour Aug 01 '11 at 19:46
  • uh, ok... as stated this is for release version aka I have multiple threads within dlls, and the apps where simply printing out error codes isn't always feasible, nor are these console apps where I can just print out data, Also as stated I am working with ALOT of dlls, so a simple checker at the beginning or the program (AS MY PROVIDED LINKS SHOW) is not complicated with managed dlls, its the unmanaged ones, THERE IS A REASON DEPENDENCY WALKER WAS CREATED, CLEARLY THERE ARE CIRCUMSTANCES WHERE THIS WOULD BE MORE EFFICIENT FOR SOMEONE, HENCE WHY I CAME FOR HELP AND THIS IS NOT A "RIDICULOUS" Q – GregM Aug 01 '11 at 19:58