I'm working on a C# project that is nearing release. As part of this, I have started building the project and testing it on another machine. This has revealed some odd problems. My biggest concern, though, is that my project is failing to run. I can do some basic things, but when I try to use my projects primary functionality it crashes. Using Visual Studio, I was able to determine the exception that was causing the crash.
Essentially, I'm getting a FileNotFoundException on the dll that contains most of my project's functional code. I'm not sure if I've made an error in adding the dll to my project, or if there's a problem in one of the files in the dll.
The dll was added as a reference using the Project -> Add Reerences feature of the user interface.
The dll contains three files which contain absolute file paths (these are for #import statements). Example follows.
#import "C:\Users\Me\Documents\Projects\MyProject\Delegates\bin\MyDelegate.tlb" raw_interfaces_only
My hang up is I'm not exactly sure what I'm doing wrong here. I suspect that those import statements are causing problems, but I'm not exactly sure how to fix them if they in fact are the problem. This is my first c#/c++ project so any help would be appreciated.
Adding the dll as a reference DOES NOT include the dll with your project--you are simply telling your project to use the library for your code. The dll will need to be installed on all computers that run your application, for your application to use the dll.
If the dll also uses three files (as you specified), then those files must also be included, and be installed in the expected path.
Presuming you have redistribution rights on the dll you mention, you can include the dll in your project. Be sure to set the "copy" property as "copy always" or "copy if newer" and change the reference to use the copy that ends up in you bin folder. Then you only need to be sure to include that dll and install it in the same folder as your application.
Related
I downloaded a package from SourceForge, PlanEph, which has 64 and 32 bit DLLs for C#. I got the 32 bit included C# demo to work by putting the DLL in my bin/Debug directory (I'm using Visual Studio 2015 Community) and adding the DLL as a reference.
Then I tried to make my own version of the demo in a separate solution, and got the System.DllNotFoundException. Various experimentation lead me to believe I can't have two identical namespace names anywhere in my Visual Studio installation, so I erased everything and started over.
I made a directory C\GJAbin, put the DLL in it, and added it to the system Path variable. I also put a helloWorld type program in that dir and executed it from the command line to verify the directory really was in the path. Then I recreated the demo solution, added the DLL as a resource, and built the solution "successfully". Then I ran it and got the System.DllNotFoundException.
So I can't understand why the DLL is being found when compiling but not at run time.
Go to project settings, go to "publish" tab and on the top most button (labeled something like "application files"). Chose "Show all files" checkbox if you don't see your DLL. Set the DLL's publish status to "Include" (NOT "Include (Auto)"!!) and publish it again.
Now the DLL should be inside the publish folder.
So I can't understand why the DLL is being found when compiling but not at run time.
Locating the assembly at compile time is done differently (by MSBuild) than at runtime (by the CLR).
At compile time, MSBuild has specific search paths that it knows about, or in most cases like this, there will be something in your project file telling MSBuild where to look for the file. Usually the <Reference> has a <HintPath>.
At runtime, the CLR will attempt to find the assembly from its own set of well-known paths. It will look in your app's config file (if applicable), then in the Global Assembly Cache (GAC), then in your app's root directory. Much more detail on this is available here.
You can tell MSBuild to copy the reference to your build output directory (usually the same as your app root directory when running). In VS, you can do this by selecting the reference and looking at the Properties tool window (or press F4 by default). Set the CopyLocal state to True. In the project file, this will add a <Private>True</Private> on the <Reference>.
You can also add the assembly to the GAC using the gacutil tool, but this does make it harder if you want to share your app with others. Usually it's preferable to keep a copy in your app root directory.
If it's still not working, you can also see the log for how the runtime is trying to find this assembly. The fuslogvw.exe tool in the Windows SDK (you can run it from the VS command prompt and it will be on the %PATH%) allows you to enable logging for assembly loads. You do need to be able to run this as an administrator to configure the setting.
As you can see in the screenshot, you can either log the results in the exception (so that you can see it while debugging), or you can log it to a file on disk (so you can see it whenenver).
The problem turned out to be an unfortunate interaction among the way the author chose names and the way Visual Studio displays information and error messages. The author created a c# dll Astronomy.PlanEph32.dll containing a namespace PlanEph32, which which was really just a wrapper for the c dll PlanEph32.dll. So all the error messages about not being able to load PlanEph32.dll were referring to not finding the c dll; the c# dll was being found just fine.
I have included some native DLLs that my project depends on into the project and set in their properties Build Action to content and Copy to Directory to Copy if newer.
I am now having the annoying behavior that the DLLs are sometimes not being copied to the output directory, when I build a project. The behavior appears to be, that when I select Build they are not being copied, but they are being copied when I select Rebuild. To make matters worse they are sometimes removed and I am not sure when (I believe before performing a normal Build).
So my question is: What am I doing wrong? I have also found people using the Post-Build event to copy the DLLs, so is my way not the correct way to do it?
Edit:
I forgot to mention that I have two projects (on which the project that I am building depends) with the same Dlls included, since they both depend on EmguCV, which uses the native OpenCV Dlls, which are the ones causing the trouble.
I have a solution in Visual Studio with three projects added to it. The first project is a C# WinForms project with it's dependency set to the second project. The second project is a VC++ project which compiles to a DLL.
This VC++ project is dependent on another VC++ project which is a static library. I am able to run the executable from the debug/release folder directly on the development system.
But when I try to test on a different computer, I get an error after UI loads saying "Could not find file or assembly "mydll.dll" or one of its dependencies. The specified module could not be found."
Both the VC++ projects have their output set to a specific folder. When I right click in the references and check path, it looks fine.
What must I do?
I would try opening the csproj file in a test editor like Notepad or Notepad++ and figure out if the references are pointing to the right dll(s). Also pay attention as some of the references might include signatures, and it might not be the right signature either.
What shows up on the IDE might not be exactly the same that you have on the csproj file.
You need to unload the project from VS to be able to edit it in a text editor.
Also do this for all the projects on the solution.
Did the other computer have the Microsoft C++ Redistributable installed, of the appropriate version (year) and architecture? Also you can investigate dependencies with dumpbin.
I'm on a C# project, and since it uses Sharepoint I'm working on a MS Server 2008.
The project compiles and runs fine on server, so I thought it was time for deployment, and created a Installer Project, provided by Visual Studio itself.
When I run the installer then the program on server, it works flawlessly. But when I do that on my local machine, it says a COM reference is missing or something.
The fact is that this project indeed references a Visual Basic DLL provided by my company, and I just don't understand why the installer won't copy/register it by itself. It managed to get some other needed DLL well and copied it to the installation folder (like Microsoft.IdentityModel.dll, Microsoft.SharePoint.Client.dll...).
Any hint on what I should do to have it working? I do not have access to the "copy local" property of the referenced DLL (it's greyed).
Edit: some pictures, maybe it'll help:
http://hpics.li/2f6acc4
http://hpics.li/86e8b11
http://hpics.li/6697314
Edit 2: So it's a bit more complicated that I thought. In fact, when I simply reference the original DLL (which is GestionClevb6.dll), I end up getting the "unregistered class" error in my program.
But if I reference the generated Interop.GestionClevb6.dll, I notice another DLL being added to the deployment project (a dependency I guess). Oh yeah. So I have two DLL in the end, GestionClevb6.dll and the new one, DLL_Licence.dll, and a brand new bug: "Exception de HRESULT : 0x800AC352."
The error about a COM reference missing means that your project references a COM class, but on the system you're trying to run the program that COM class is not registered.
You need to make the setup register the COM-DLL in the course of the setup process. It will not be done automatically! Otherwise, if the COM-DLL has not been registered, you'll get this error. I suppose that on the server where it works, the DLL has been registered before.
don't understand why the installer won't copy/register it by itself.
How should the installer know that it is a COM DLL that must be registered?
It managed to get some other needed DLL well and copied it to the installation folder (like Microsoft.IdentityModel.dll, Microsoft.SharePoint.Client.dll...
These are managed DLLs directly referenced by your project. They don't have to be registered. Also, as these are managed referenced DLLs they will be copied as part of the "Project Output" if the "Copy Local" property for the reference is configured accordingly.
This, however, does not work for COM-DLLs. There's no "Copy Local" property for COM-references as it wouldn't help anyway - DLLs containing COM classes need to be registered. Copying alone doesn't register them.
I've downloaded and compiled Amazon's .NET SDK for Mechanical Turk, producing two DLLs: Amazon.WebServices.MechanicalTurk.dll and Amazon.WebServices.MechanicalTurk.Domain.dll .
I then created a new WPF project and added the two DLLs as references. When I create objects from their space, Intellisense has no trouble browsing the assemblies- I can see the classes inside.
When I compile, however, I get an "type not found" error from the compiler. Intellisense no longer works for the Amazon namespace, and the DLLs have vanished from the Object Browser window inside Visual Studio, though they're still listed as references in Solution Explorer.
What's going on? I think I'm missing something obvious. I can see, for example, MTConfig, but when I try to instantiate it, it fails and I need to re-add the DLLs to try again.
Thanks!
How have you added the references? Did you copy the DLLs into your new project's output folder and add references to them there? I can imagine that giving the behaviour you describe, if VS wipes the output folder before a build. If that's what's happening, simply move the DLLs to a different directory (I typically create a "lib" directory) and point the reference there.
What I did to solve this same problem was to recompile the DLLs changing the .NET version from 2.0 to 4.0 in the project properties. Not sure why that works, but in my case it solved the issue.