A managed DLL / Application will have a primary dependency on MSCOREE.dll... So, if you open the DLL in Dependency Walker you have no problems in telling a managed library from an unmanaged one.
Actually, if you open a .NET Library / Application in a binary editor, you will see that the ASCI text "BSJB" is shortly followed by the version of the Framework that the DLL / EXE needs.
So, depending on the presence of this search attribute, you can not only identify whether the library / executible is a managed library, but also the version of the Framework it uses.
Note: This is actually a hack as there seems to be no API that will help you out with your requirement - but, it is reliable (so far) and you can enforce some strong checks that nobody fools your application (though, I doubt if anyone will want to do this).
I have written a small function to determine whether a function is a .net assembly or not. It might be useful to other people as well (since I couldn't find anything on the internet about it).
Code:
bool IsNetAssembly(CString sFilename)
{
// Declare variables
bool bAssembly = false;
bool bTagFound = false;
bool bVersionFound = false;
char szBuffer[2048];
char szTagBuffer[5];
char szVersionBuffer[4];
int iBytesRead = 0;
CFile oFile;
// Set up tag
strcpy(szTagBuffer, "BSJB");
// Check if file exists
if (!PathFileExists(sFilename))
{
// No assembly
return bAssembly;
}
// Read the contents of this file
if (!oFile.Open(sFilename, CFile::modeRead | CFile::shareDenyNone, NULL))
{
// No assembly
return bAssembly;
}
// Read file
while (iBytesRead = oFile.Read(szBuffer, 2048))
{
// Check if we can find the special tag
if (!bTagFound)
{
if (ValueExistsInCharBuffer((char *)&szBuffer, iBytesRead, (char *)&szTagBuffer, 4))
{
// Tag found
bTagFound = true;
}
}
// Check if we can find the version
if (bTagFound && !bVersionFound)
{
// Loop all versions (until .net framework 9
for (int i = 1; i < 10; i++)
{
// Set up version
sprintf(szVersionBuffer, "v%d.", i);
if (ValueExistsInCharBuffer((char *)&szBuffer, iBytesRead, (char *)&szVersionBuffer, 3))
{
// Version found
bVersionFound = true;
}
}
}
// Did we find both?
if (bTagFound && bVersionFound)
{
// This is an assembly
bAssembly = true;
// Don't search any longer
break;
}
}
// Close file
oFile.Close();
// Return result
return bAssembly;
}
//=====================================================================
bool ValueExistsInCharBuffer(char * pBuffer, int iBufferSize, char * pValue, int iValueLength)
{
// Loop complete buffer
for (int i = 0; i < iBufferSize - iValueLength; i++)
{
// Check if this part contains the value
for (int j = 0; j < iValueLength; j++)
{
// Check the character
if (pBuffer[i + j] == pValue[j])
{
// Check if we compared whole item
if (j == iValueLength - 1)
{
// Yes!
return true;
}
}
else
{
// Break internal loop
break;
}
}
}
// Not found
return false;
}
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.