At work, we have a VB6 project (ActiveX DLL) that we need to be able to add as a reference to another VS2008 C# project.
A developer there tells me that in the past, they have been able to do so but now we made a change to the VB6 DLL and had to recompile it.
As such, we need to update the reference in the VS2008 project but when we try to add the reference to the VB6 DLL back (after removing the old reference) to the VS2008 project, we get a yellow "!" icon on the newly added reference and then when we build, VS2008 says the reference cannot be found.
I tried the "Browse" and "COM" tabs where you can add reference, no luck.
Do we need some kind of TLB to be able to add it or something ?
Thanks.
You need to do the following from a command prompt:
#CD to wherever the dll is located
regsrv32 /u foo.dll
regsrv32 foo.dll
This will unregister the old com object and register the new one.
He's right, you could do that from command prompt.
Remember though, your Active-X control DLL could be 16-bit, so use
regsrv /u foo.dll
regsrv foo.dll
from command prompt. But 32-bit works fine for regsrv32!
I used OLE/COM object viewer (included in Windows SDK 6.0A) then I saw a bunch of COM entries in "All objects" ie: MyDLLName.className and some were pointing to a DLL file which did not exist anymore. Deleted all the relevant COM entries in the Windows registry that pointed to the deleted DLL and left all the ones which pointed to the existing DLL and then I could import it successfully in my VC# project.
Related
I created a managed VC++ class library, and now I created a new C# console application. I added the DLL from the class library as a reference. Now, when I try to run my program from VS, VS complains that it cannot find the DLL. When I check the output folder bin\Debug, however, the DLL is there.
Is there anything I forgot to configure?
The correct answer was in Hans passant's comment: The DLL which could not be loaded referenced another DLL which was not present in the output directory. That's why I got the exception.
I now added a post-build step which copies the DLL to the output directory after a successful build, and voilĂ , it works.
I was creating a set up project for a COM class. So users can install the dll and get additional features as an option. However i labelled the COM Class so i renamed the dll. However when i changed the dll from class.dll to comclass.dll, and ran regAsm again, when i added the comclass.dll to the project the .tlb was class.tlb listed in the Detected Dependencies folder, keeping the old name.
So i decided to create a new project with new GUIDs to just fix it and named it comclass.dll. Everything tested and compiled but once i got to the set up portion of and added the comclass.dll, nothing was showing up in detected dependencies only .net framework. Before the old .dll use to get the .tlb to show up. Now i can't get the .tlb to show up.
If i add the .tlb directly to the project it gives an error at set up time regarding the setup not being able to register the .tlb file.
I created a COM object with C# yesterday which resulted in three files in the bin/release directory of my VS 2010 project (comclass.dll, comclass.pdb and comclass.tlb). Now, when I build the solution in the project, VS registers the class for me automatically on the development PC and I have no problem accessing the COM object and its methods from, let's say, Powershell. However, when I copy the three files onto a different machine and try to register the dll with regsvr32, it tells me that
the module "comclass.dll" was loaded but the entry-point DllRegisterServer was not found.
Make sure that "comclass.dll" is a valid DLL or OCX file and then try again.
Using regasm with the /tlb parameter on the .tlb file gives me a similar message. So I am a little bit stumped. Anyone knows how I should proceed from here?
Just copy the dll (and optionally the pdb if you want file paths and line numbers in your stack traces). This is how you register it, and the tlb is created:
"%WINDIR%\Microsoft.NET\Framework\v2.0.50727\regasm.exe" comclass.dll /tlb /nologo /codebase
Since Visual Studio successfully registers it, that might just work. If not, you could also open the Output panel while doing a Rebuild and see how Visual Studio calls regasm.
One solution (the.sln)
One C++ project (mycppproject.vcxproj in 2010or mycppproject.vcproj in 2008) which compiles a native DLL exporting some function(s). In debug this builds c:\output\Debug\mycppproject_d.dll and in release this builds c:\output\Release\mycppproject.dll.
One C# console application (mycsharpconsole.csproj) containing PInvoke calls into the DLL.
All compiles fine.
When I build, I would like to be able to add a reference from the csharp project to the cpp DLL project so that it can copy the appropriate file from the appropriate directory into the \bin\Debug directory the csharp project is built into.
This should be possible, since the IDE knows everything there is to know about where the DLL gets built, and where the C# application gets built.
In Visual Studio 2010:
I've tried "Dependencies..." on the csharp project and adding a dependency on mycppproject, but that has no effect.
I've tried "Add Reference..." on the csharp project and adding a reference to the cpp project, but I get a warning message 'The Target Framework version for the project "mycppproject" is higher than the current project Target Framework version. Would you like to add this reference to your project anyway?' (Yes/No/Cancel).
Clicking "Yes" produces the error message "A reference to mycppproject" could not be added."
You cannot add a reference to an unmanaged DLL.
Instead, you should make a post-build task to copy the file.
Alternatively, you can add a link to the unmanaged DLL as a file in the C# project, and set Build Action to None and Copy to Output Directory to Copy If Newer.
Visual Studio doesn't support referencing an unmanaged C++ project from a managed C# one, but MSBuild supports referencing any project from any other project.
You can manually add a reference to your project by editing the .csproj file by hand. In the file, find your existing set of ProjectReference elements (or add a new ItemGroup if you don't have one) and add the following reference:
<ProjectReference Include="..\mycpproject.csproj">
<Project>{b402782f-de0a-41fa-b364-60612a786fb2}</Project>
<Name>mycppproject</Name>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<OutputItemType>Content</OutputItemType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</ProjectReference>
When you perform the build, the reference will cause MSBuild to build the referenced project first. The ReferenceOutputAssembly value tells MSBuild not to copy the output assembly of the build (since the C++ project does not produce one), but the OutputItemType and CopyToOutputDirectory values instruct it to copy the output content to the referencing project's output folder.
You will be able to see the reference in Visual Studio, but you can't do much with it there.
This answer is based on a similar problem solved by Kirill Osenkov on his MSDN blog: https://blogs.msdn.microsoft.com/kirillosenkov/2015/04/04/how-to-have-a-project-reference-without-referencing-the-actual-binary/
I would follow Slaks' second answer...
[...] you can add a link to the unmanaged DLL as a file in the C# project, and set Build Action to None and Copy to Output Directory to Copy If Newer.
... followed by my comment, to differentiate between Debug and Release builds (even if is a little bit "hackish", since it requires you to manually edit the C# project file)
open your C# project's csproj file with a text editor and search for all "YourNativeCppProject.dll" occurrences (without the ".dll" subfix, so if you added pdb files as a link too, you'll find more than one occurrence), and change the Include path using macros, for example: Include="$(SolutionDir)$(ConfigurationName)\YourNativeCppProject.dll
PS: if you look at the properties (F4), VS shows you the Debug's path even if you switch to the Release configuration, but if you compile, you'll see that the dll copied to output is the release version*
Add Rederences only works for .NET assemblies, .net projects in the same solution or for COM components ( for which a manager wrapper will be created anyway... ).
the fact that in your C# code you access the C++ dll with DLLImport does not mean that Visual Studio will know from where to where the external dll should be copied.
Imagine that DLLImport is a runtime option, the path you puth in there is used at runtime to look for the dll, so you have to deploy the c++ dll yourself and make it available for the .net application, usually in the same bin folder.
Similar to coryr (see this question), I am referencing a dll within a C# project. The DLL often changes but I the C# project does not recognize this. Unlike coryr, the DLL is a VB6 ActiveX DLL. Any suggestions for how to reload the reference other than removing and adding it?
The problem here is that when you add a reference to a COM DLL, you don't actually add a reference to the DLL. Instead a primary interop assembly is generated for the DLL and a reference is added to that. When the main DLL is changed a new PIA (primary interop assembly) is not generated.
You can verify this by doing the following
Expand the references collection
Hit F4. This will bring up the properties page
Look at the path property
The path will be the path to the PIA.
The problem is that VS is watching the PIA and not the original DLL. So when the original DLL changes it doesn't actually reload the reference. The best way to get this to work is to unfortunately delete and re-add the reference.
Another solution is to manually generate the PIA and place it over the referenced PIA on disk. This will force VS to reload the DLL reference.