Manifest strikes again

  • Thread starter Thread starter _iycrd
  • Start date Start date
I

_iycrd

After several frustrating attempts to wrap a native DLL w a C++/CLI
DLL, I finally got an assembly to compile, only to find a *runtime*
error. The app comes up fine. Test dialog displays. Clicking on the
button that creates the wrapper class causes an exception, not in the
button's event handler, but in Application.Run() within Main(). The
error:

! System.IO.FileNotFoundException was unhandled
Message="The specified module could not be found. (Exception from
HRESULT: 0x8007007E)"

I initially thought the message was complete nonsense, but on
researching this I found a number of similar incidents. Apparently
this relates, once again, to a manifest file.

The thread at:

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=130243&SiteID=1
refers to a bug report submitted to Microsoft:
http://tinyurl.com/f78bv

Unfortunately, MS closed the bug report as 'by design.' Why MS would
regard it as 'by design' is beyond me, and I can't make much sense of
their recommendation (can anyone?). Their workaround (copying/
renaming the manifest from the DLL to the C# app folder) did not work,
of course.

Does anyone have any idea what's going on here or how to get around
this?

PS: Platform is VS2005, XP Pro, 32-bit, Pentium, all standard stuff.
Someone in the thread above said "weren't these .NET languages
supposed to be compatible?"
 
Hello,

Generally you have this error when your native DLL isn't in the same
directory as your wrapper assembly. So copy your native DLL in the
directory of your wrapper assembly. The best is to use the same output
directory (in the project properties of VS) for the project of your
native library and for the project of your wrapper.
 
You have to embed the manifest in your DLL (using MT.EXE), or you have to
link with the static C runtime library. Note that in the first case, you
need to 'deploy' the C runtime with your application if the target machine
doesn't have VS2005 or the SDK istalled. In the latter case this isn't
needed as the run-time is statically linked.

Willy.

| After several frustrating attempts to wrap a native DLL w a C++/CLI
| DLL, I finally got an assembly to compile, only to find a *runtime*
| error. The app comes up fine. Test dialog displays. Clicking on the
| button that creates the wrapper class causes an exception, not in the
| button's event handler, but in Application.Run() within Main(). The
| error:
|
| ! System.IO.FileNotFoundException was unhandled
| Message="The specified module could not be found. (Exception from
| HRESULT: 0x8007007E)"
|
| I initially thought the message was complete nonsense, but on
| researching this I found a number of similar incidents. Apparently
| this relates, once again, to a manifest file.
|
| The thread at:
|
| http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=130243&SiteID=1
| refers to a bug report submitted to Microsoft:
| http://tinyurl.com/f78bv
|
| Unfortunately, MS closed the bug report as 'by design.' Why MS would
| regard it as 'by design' is beyond me, and I can't make much sense of
| their recommendation (can anyone?). Their workaround (copying/
| renaming the manifest from the DLL to the C# app folder) did not work,
| of course.
|
| Does anyone have any idea what's going on here or how to get around
| this?
|
| PS: Platform is VS2005, XP Pro, 32-bit, Pentium, all standard stuff.
| Someone in the thread above said "weren't these .NET languages
| supposed to be compatible?"
|
 
"VS2005 or the SDK" should read "VS2005 or the .NET V2".

Willy.

| You have to embed the manifest in your DLL (using MT.EXE), or you have to
| link with the static C runtime library. Note that in the first case, you
| need to 'deploy' the C runtime with your application if the target machine
| doesn't have VS2005 or the SDK istalled. In the latter case this isn't
| needed as the run-time is statically linked.
|
| Willy.
|
| || After several frustrating attempts to wrap a native DLL w a C++/CLI
|| DLL, I finally got an assembly to compile, only to find a *runtime*
|| error. The app comes up fine. Test dialog displays. Clicking on the
|| button that creates the wrapper class causes an exception, not in the
|| button's event handler, but in Application.Run() within Main(). The
|| error:
||
|| ! System.IO.FileNotFoundException was unhandled
|| Message="The specified module could not be found. (Exception from
|| HRESULT: 0x8007007E)"
||
|| I initially thought the message was complete nonsense, but on
|| researching this I found a number of similar incidents. Apparently
|| this relates, once again, to a manifest file.
||
|| The thread at:
||
|| http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=130243&SiteID=1
|| refers to a bug report submitted to Microsoft:
|| http://tinyurl.com/f78bv
||
|| Unfortunately, MS closed the bug report as 'by design.' Why MS would
|| regard it as 'by design' is beyond me, and I can't make much sense of
|| their recommendation (can anyone?). Their workaround (copying/
|| renaming the manifest from the DLL to the C# app folder) did not work,
|| of course.
||
|| Does anyone have any idea what's going on here or how to get around
|| this?
||
|| PS: Platform is VS2005, XP Pro, 32-bit, Pentium, all standard stuff.
|| Someone in the thread above said "weren't these .NET languages
|| supposed to be compatible?"
||
|
|
 
_iycrd said:
After several frustrating attempts to wrap a native DLL w a C++/CLI
DLL, I finally got an assembly to compile, only to find a *runtime*
error. The app comes up fine. Test dialog displays. Clicking on the
button that creates the wrapper class causes an exception, not in the
button's event handler, but in Application.Run() within Main(). The
error:

! System.IO.FileNotFoundException was unhandled
Message="The specified module could not be found. (Exception from
HRESULT: 0x8007007E)"

I initially thought the message was complete nonsense, but on
researching this I found a number of similar incidents. Apparently
this relates, once again, to a manifest file.

The thread at:

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=130243&SiteID=1
refers to a bug report submitted to Microsoft:
http://tinyurl.com/f78bv

Unfortunately, MS closed the bug report as 'by design.' Why MS would
regard it as 'by design' is beyond me, and I can't make much sense of
their recommendation (can anyone?). Their workaround (copying/
renaming the manifest from the DLL to the C# app folder) did not work,
of course.

Does anyone have any idea what's going on here or how to get around
this?

See Richard Grimes' article in the April 2006 issue of Dr. Dobb's Journal on
this very subject.

-cd
 
maybe a summary of the article might do here since we all don't subscribe to
Dobbs

--
Warm Regards,
Alvin Bruney [MVP ASP.NET]

[Shameless Author plug]
The Microsoft Office Web Components Black Book with .NET
Now Available @ www.lulu.com/owc
Professional VSTO 2005 - Wrox/Wiley 2006
Blog: http://msmvps.com/blogs/Alvin/
 
You have to embed the manifest in your DLL (using MT.EXE), or you have to
link with the static C runtime library. Note that in the first case, you
need to 'deploy' the C runtime with your application if the target machine
doesn't have VS2005 or the SDK istalled. In the latter case this isn't
needed as the run-time is statically linked.

Willy, As far as I know, VS2005 does not accept static linkage for a
/clr app. Have you got this to work?

Also, strangely enough, it looks like the manifest was embedded by VS.
Hex dump from near the end of the DLL:

PA<assembly xmlns="urn:schemas-microsoft-com:asm.v1"
manifestVersion="1.0">.. <dependency>.. <dependentAssembly>..
<assemblyIdentity type="win32" name="Microsoft.VC80.DebugCRT"
version="8.0.50608.0" processorArchitecture="x86"
publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>..
</dependentAssembly>..</dependency>..</assembly>
PPADDINGXXPADDINGPADDINGXXPADDINGPADDING

Given that, I'm not sure what could cause the error.
 
| On Thu, 9 Mar 2006 14:37:32 +0100, "Willy Denoyette [MVP]"
|
| >You have to embed the manifest in your DLL (using MT.EXE), or you have to
| >link with the static C runtime library. Note that in the first case, you
| >need to 'deploy' the C runtime with your application if the target
machine
| >doesn't have VS2005 or the SDK istalled. In the latter case this isn't
| >needed as the run-time is statically linked.
|
| Willy, As far as I know, VS2005 does not accept static linkage for a
| /clr app. Have you got this to work?
|

Sure, what makes you think that?

| Also, strangely enough, it looks like the manifest was embedded by VS.
| Hex dump from near the end of the DLL:
|
| PA<assembly xmlns="urn:schemas-microsoft-com:asm.v1"
| manifestVersion="1.0">.. <dependency>.. <dependentAssembly>..
| <assemblyIdentity type="win32" name="Microsoft.VC80.DebugCRT"
| version="8.0.50608.0" processorArchitecture="x86"
| publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>..
| </dependentAssembly>..</dependency>..</assembly>
| PPADDINGXXPADDINGPADDINGXXPADDINGPADDING
|
| Given that, I'm not sure what could cause the error.

VS2005 embeds the manifest by default, not surprising. So your problem is
due to some other missing depency.
 
Alvin Bruney - ASP.NET MVP said:
maybe a summary of the article might do here since we all don't subscribe
to
Dobbs

If no one else chimes in, I'll provide such a summary next time I'm at my
office where my copy of the issue is.

-cd
 
Carl Daniel said:
If no one else chimes in, I'll provide such a summary next time I'm at my
office where my copy of the issue is.

Here's the gist:

Side by side manifests for native DLLs don't work - you have to create an
embedded manifest. In order to create one, you need to use a couple of
undocumented options of MT.EXE - the manifest tool:

mt /manifest your.dll.manifest /outputresource:your.dll;#2

note the inconsistency in option style - /manifest expects the name of a
manifest file, separated by whitespace while /outputresource expects a colon
between the option and the file name.

You can also embed the manifest directly in your native resources by giving
it a resource ID of 2 and the name RT_MANIFEST.

Incidentally, the linker creates the manifest file for you, it simply
doesn't embed it in the DLL.

-cd

Here's an example (from the article):

// native.cpp
using namespace System;
public ref class Test
{
public:
void CallMe()
{
Console::WriteLine("called me");
}
};

// managed.cs
using System;

class App
{
static void Main()
{
Test test = new Test();
test.CallMe();
}
}

// build steps
cl /clr /LD native.cpp
mt /manifest native.dll.manifest /outputresource:native.dll;#2
csc managed.cs /r:native.dll
 
Here's the gist:

Side by side manifests for native DLLs don't work - you have to create an
embedded manifest. In order to create one, you need to use a couple of
undocumented options of MT.EXE - the manifest tool:

mt /manifest your.dll.manifest /outputresource:your.dll;#2

Thanks for the summary, Carl. Condensed nicely. Bottom line is that
the process for embedding manifests, etc. is not reliable. Not sure
why Microsoft would claim that's "by design."

I don't see why the new scheme involving complex deployment strategies
and several levels of forced indirection (manifest->policy->dll) is
any improvement over the older 'DLL-hell' scenario. It's a different
set of problems.

Any missed subtleties in deployment of dlls, even for native-only
apps, result in obscure error messages. End-users will not have a
clue. Apparently this is not all as easy as some at Microsoft have
implied, or they would not have missed the steps outlined in Richard
Grimes' article.

I understand the problems in DLL versioning, and remember well when a
new VS version introduced native runtime DLLs with identical names to
their previous DLLs. I think that was the problem though: they should
have just changed DLL names (preferably to something simple that could
be deployed to System32).

One of the new constructs does seem logical and useful: Policy files.
If this could have been done in more direct fashion, that may have
solved a lot of versioning problems. I see no reason why policy-file
redirection could not have worked with an older style
"\System32\UniqueName.DLL"

BTW, Richard Grimes' article is online at:
http://www.ddj.com/documents/q=1/ddj0604f/0604f.html
 
| Willy, As far as I know, VS2005 does not accept static linkage for a
| /clr app. Have you got this to work?

Sure, what makes you think that?

In case that was vague, I was referring to changing C++ compile
options from /MDd to /MTd (and equivalent for release build). The
compiler reports that that is not compatible with /clr build. (Anyone
know why?)

How did you get that to compile? I tried again, even created an empty
class lib, and I consistently get the compile-time error message:

"Command Line Error D8016: 'MTd' and '/clr' command line options are
incompatible."

That would apply to /clr:pure and :safe as well.
| Given that, I'm not sure what could cause the error.

VS2005 embeds the manifest by default, not surprising. So your problem is
due to some other missing depency.

Or something has gone astray in the long chain back to the DLLs.
Seems that there are a lot more places for things to go wrong now:
manifest generation, embedding process, policy file indirection,
location/deployment of DLLs. It's something in that path. I think a
lot of developers are going back to static linkage. I'd like to, but
as above, it does not seem to work in this case.

Richard Grimes' article also touched on something else I was wondering
about: V2005 manifests call for a different runtime DLL version from
what you'd expect. That version is then redirected by a policy to get
to the correct DLL version. I do understand how that works, but I was
wondering why MS didn't just generate manifests with the correct
version to begin with given that VS2005 was a major release.
 
_iycrd said:
Richard Grimes' article also touched on something else I was wondering
about: V2005 manifests call for a different runtime DLL version from
what you'd expect. That version is then redirected by a policy to get
to the correct DLL version. I do understand how that works, but I was
wondering why MS didn't just generate manifests with the correct
version to begin with given that VS2005 was a major release.

It has to do with locking certain things down before RTM to help deal with
dependencies within the various bits of Visual Studio. By fixing the RTM
"version number" before RTM, there's a little more leeway in the build
process to get VS out the door - only the policy file needs to be updated
with the actual RTM version number.

-cd
 
| Willy, As far as I know, VS2005 does not accept static linkage for a
In case that was vague, I was referring to changing C++ compile
options from /MDd to /MTd (and equivalent for release build). The
compiler reports that that is not compatible with /clr build. (Anyone
know why?)

How did you get that to compile? I tried again, even created an empty
class lib, and I consistently get the compile-time error message:

"Command Line Error D8016: 'MTd' and '/clr' command line options are
incompatible."

That would apply to /clr:pure and :safe as well.

Using the static version of the CRT is *not* supported with /clr. There is
not that much more to say about it.
Or something has gone astray in the long chain back to the DLLs.
Seems that there are a lot more places for things to go wrong now:
manifest generation, embedding process, policy file indirection,
location/deployment of DLLs. It's something in that path. I think a
lot of developers are going back to static linkage. I'd like to, but
as above, it does not seem to work in this case.

Richard Grimes' article also touched on something else I was wondering
about: V2005 manifests call for a different runtime DLL version from
what you'd expect. That version is then redirected by a policy to get
to the correct DLL version. I do understand how that works, but I was
wondering why MS didn't just generate manifests with the correct
version to begin with given that VS2005 was a major release.

I don't know Grimes' article, but maybe this informatin helps you:

1) Assemblies compiled with /clr depend on the multithreaded DLL version of
the CRT (msvcr80.dll] and an additional .NET assembly (msvcm80.dll, when
compiled with /clr, msvcp80.dll when compiled with /clr:pure)
2) Both, msvcr80.dll and msvcm80.dll are deployed as a native assembly (in
the %windir%\WinSxs directory)
3) The fact that msvcm80.dll is a managed assembly deployed as a native
assembly (in WinSxs) causes the problems you have.
4) To load msvcm80.dll, a native manifest is necessary.
5) The simplest way to provide this is to copy the file
yourMixedCodeLib.dll.manifest to yourCSharpClientApp.exe.manifest
 
| >>| Willy, As far as I know, VS2005 does not accept static linkage for a
| >>| /clr app. Have you got this to work?
| >>
| >>Sure, what makes you think that?
| >
| > In case that was vague, I was referring to changing C++ compile
| > options from /MDd to /MTd (and equivalent for release build). The
| > compiler reports that that is not compatible with /clr build. (Anyone
| > know why?)
| >
| > How did you get that to compile? I tried again, even created an empty
| > class lib, and I consistently get the compile-time error message:
| >
| > "Command Line Error D8016: 'MTd' and '/clr' command line options are
| > incompatible."
| >
| > That would apply to /clr:pure and :safe as well.
|
| Using the static version of the CRT is *not* supported with /clr. There is
| not that much more to say about it.
|
|
Sorry, you are right, my mistake.
Can't remember what I was tinking about.

Willy.
 
Back
Top