8
votes

I have a C++ 'Control Library Project' compiled using /CLR. Inside this project there is a User Control that makes a call to a native DLL. This user control appears in the designer toolbox as it should, but I cannot then drag it onto a form. Without the reference to the DLL the user control can be used fine, but with the reference I just get the message "Failed to load toolbox item" when trying to use it.

The native call is functional and not harming the User Control in anyway. The User Control can be viewed fine in the designer by itself with the DLL call included. Also if the control is added manually to a form and executed as a program, it will also display fine.

This makes me suspect that the problem is just a matter of Visual Studio Designer needing to know where that native DLL is located. But I'm not sure how to tell it, or where to put the DLL so that it can find it. As far as I known there is no way in the project settings to reference a native DLL. So it makes sense to me that designer is just complaining because it can't fine it.

Is there a way to make this work?

7
Is the issue with VS 2010 or also with VS 2008? We have a similar, paralysing problem, which has led us to go back to VS 2008...Joel in Gö
I am getting this problem with VS 2008. So VS 2010 is no better in this regard?Nicholas
I thought adding the native DLL to the C:\Windows\System32 path might succeed, but unfortunately it is not so.Nicholas
Same problem here. I can create a user control without adding any controls or code. But I can't site it on a form. My user control is in the same project as the form.Jonathan Wood
That's the 3rd complaint I've seen about this in the past week. It rains it pours, nothing before that. To anybody affected: mention what kind of software or updates were installed recently on your machine.Hans Passant

7 Answers

10
votes

Unfortunately, you've encountered a "bug by design" in VS (or in other words, a "feature").

Your suspicion that the problem is a matter of the Visual Studio designer needing to know where the native DLL is located is partially right. It's not a matter of ignorance to it's location, but rather the fact that the designer cannot reflect over mixed-mode assemblies (those that contain both managed and native code) in order to instantiate the control. This is causing the toolbox to show the error you noted.

The workaround is to compile the C++ source files using /clr:pure to create a purely managed EXE.


Another possibility (also a "bug by design" in VS) is that the control you're trying to add has been compiled as a 64-bit component. Because Visual Studio is a 32-bit process, it can only execute 32-bit modules. While it allows you to add a reference to a 64-bit assembly, it cannot actually JIT compile that 64-bit assembly and execute it within process.

The workaround here is to compile your user control assembly using the "AnyCPU" setting, which will cause it to execute as a 32-bit process in a 32-bit environment, and a 64-bit process in a 64-bit environment. Really, this is the best of both worlds, assuming you've written your code correctly.


Finally, if none of those work, there's always the option of bypassing the designer. You can still write the code necessary to instantiate your user control and set its properties in the form's initializer. All that you would be losing is the ability to use the control inside of the designer inside Visual Studio. Everything would work as expected at run-time.

3
votes

Link your library with /DELAYLOAD:"your_native.dll" option. This solved the same problem for me.

1
votes

I found this that looks like a similar problem?

https://connect.microsoft.com/VisualStudio/feedback/details/388107/winforms-designer-fails-to-load-managed-dll-having-unmanaged-dependencies#details

So MS seem to officially be saying upgrade from VS2008 to VS2010 as a workaround.

Did you ever find a different workaround?

This is a problem I am experiencing right now in VS2008 with a C# .net managed project using a managed C++ wrapper project using an unmanaged C++ project.

It certainly looks to me like the designer temporary assemblies that Visual Studio is using is a problem - it loads the detected dependency wrapper assembly into the temporary folder but not that wrapper assembly's unmanaged dependencies. I can see this is in C:\Users\Username\AppData\Local\Microsoft\VisualStudio\9.0\ProjectAssemblies. When I attempt to load the designer a new folder is created in there with the managed DLL in it but not the unmanaged dependencies. Unfortunately I can't understand what the person in the question from the Microsoft link above is saying is the workaround using $(TargetDir).

0
votes

Things to try:

VS2010: copy the dll to the Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PublicAssemblies folder.

VS2008, VS2010: copy the dll to the AppData\Local\Microsoft\VisualStudio\<version>\ProjectAssemblies\ folder.

0
votes

It seems to me that control with the reference to the native DLL fails because Visual Studio cannot load it. Try setting PATH environment variable either globally or for Visual Studio executable when you run it. If that doesn't help, try to debug your control's design time behavior and you should be able to locate the problem.

0
votes

I had a problem similar to this that may be the same one as yours (who knows how many things could be causing it?), basically that I couldn't drop controls on to a designer, but existing controls worked fine in both production and testing.

For the record, here was my solution:

1) Change your solution settings to x86. This allowed me to put the control on the designer, move it around, etc. 2) When finished, you can move back to AnyCPU or x64. I'm really only using the designer to simplify setting a few values, and it appears the whole 32/64 bit thing causes problems.

0
votes

You can create a base class in .Net and inherit your cli class from this base class. The form can now reference to this base class rather than directly to the cli type. It tricks the designer.