I'm working in a team that has created a solution. In the solution we have 4 projects (data access, business logic and unit tests and common things).
BL references DA and CT
CT references DA
UT references BL and CT
Now whenever I rebuild it brings no errors. On my collegues PC it works without a hitch but on my PC whenever I try to run an unit test I get the following error (translated manually into english so any typos are my fault while writing this question):
{"The file or assembly \"MyWorkspaceName.MySolutionname.CT,
version=0.2.0.0, Culture=neutral, PublicKeyToken=null\" or a reference
of it was not found. The system cannot find the given
file.":"MyWorkspaceName.MySolutionname.CT, version=0.2.0.0,
Culture=neutral, PublicKeyToken=null"}
As that version and name exists (it is the common things part I manually checked if it exists) and I also checked the refernces inside of the CT if they are correct.....I'm not sure what could be a possible reason for it not working for me (but working on my collegues PC).
Thus my question would be: What could be possible reasons for that error message?
Update:
CT is now found but when I try to access the DA from BL it says the same error as before just with DA instead of the CT (ran from the UT part).
When I run the SAME methods from a console application project created within the same solution, they work without throwing any error.
There are three possibilities,
Different CPU architectures, if your colleague's PC is x64 and yours is x86 then DLL reference setup in projects might differ and that could give this error.
Different folder structures.
Different third party references, see the details below.
Are you sure you have installed every third party tools/libraries that are there on your colleague's PC?
Most probably third party references should be added as NuGet packages but if your project references third party assembly which in turn references another assembly installed via some installer and which is absent on your machine, you may get similar error. I had similar problems and some native libraries do not show up in error as dependencies unless you turn on assembly log and investigate.
Did you try to delete /obj and /bin folder before rebuilding? Sometimes there are old assembly reference caches which mess the build process.
Here is a PowerShell script for recursive erase of /bin and /obj folders. Just run it in the main solution folder.
Get-ChildItem .\ -include bin,obj -Recurse | foreach ($_) { remove-item $_.fullname -Force -Recurse }
Another possible problem that I have encountered is when there is a difference between assemblies installed in the GAC and locally downloaded NuGet packages. - Your VS gets the DLL from GAC but on your team mates computers the DLL comes from NuGet and it is different version.
To get the assembly binding information in VS : Tools -> Options -> Projects And Solutions -> Build And Run -> MS Build project build output verbosity -> Set to Diagnostic and when you build Copy-Paste the diagnostic info into notepad++ and search for 'error' and 'conflict' then resolve.
Usually if I can't solve such issues in a meaningful amount of time I go for help to Process Monitor
In your case I would add a not too restrictive filter such as: Path contains .dll and look for failure results during application launch. This might reveal what actual dll files could not be found and places were they were looked for.
Visual Studio works on a trust system, meaning you have to explicitly trust network drives. have you tried to copy the project to your local hard drive to see if it works?
Here is the article from microsoft on how to change the trusts using the CasPool.exe tool.
Caspol.exe (Code Access Security Policy Tool)
Just a few notes about this so you don't miss anything. There is different trusts for both 32-bit and 64-bit applications, so make sure you apply the trust to both to avoid any issues.
Before you go through the trouble of this tool, I would highly recommend that you copy to your local hard drive first and see if that is indeed the problem.
Related
I am using a C# application to try to connect to a SQLite database. The application uses the library System.Data.Sqlite, version 108. In Visual Studio 2017, my Solution Configuration is Debug, and my Solution Platform is Any CPU. Whenever I build and run the application, I get the following runtime exception:
The exception is unhandled, and the application terminates.
There is, of course, a SQLite.Interop.dll file in my bin\Debug directory. (If there wasn't, the exception would be different.) Specifically, there are two, each in their own subdirectories named x64 and x86. My assumption is that the file in the x86 directory is being used, since the Solution Platform is set to Any CPU. The version of the SQLite.Interop.dll assembly matches that of System.Data.SQLite.dll, being 1.0.108.0.
When I use the following command to interrogate the assemblies:
dumpbin /exports SQLite.Interop.dll
I do find the following line in the output for the x64 version of the assembly:
175 AE 00040750 sqlite3_open_interop
but in the output for the x86 version I do not. Instead, I find this line:
175 26 00037F10 _sqlite3_open_interop#20
which is close, but not a match. So there is indeed no such method as sqlite3_open_interop exposed by the assembly.
I have tried the obvious solution of changing the Solution Platform to x64, but that change leads to another exception (BadImageFormatException) which I don't much want to contend with.
I have tried dropping the reference to System.Data.SQLite and using Nuget to add the most recent version, 1.0.111.0, then cleaning and rebuilding the solution, but all to no effect. The same issue recurs.
Could anyone suggest a solution to this issue? SQLite is widely used, I believe, so I have to think there's a way to work through it.
*Edit1: I tried this project on my home computer, and observed the same difference between the two SQLite.Interop.dll files. The x64 version had a sqlite3_open_interop, while the x86 version had a _sqlite3_open_interop#20. However, the problem did not occur there. So apparently this mangled name "issue" is a red herring. I am still very interested in solving this problem, and would appreciate the assistance of someone who works on System.Data.Sqlite!
Delete your x64 and x86 directory then do a build. It will put the correct version in the folder when the installer does the NuGet check. For some reason, when you upgrade to a newer version, the x64 and x86 folders do not update the interop file in those folders if one already exists.
It turned out the issue was that the assembly was being blocked or disrupted somehow by McAfee Host Intrusion Prevention. The Activity log had the following message:
Attack type: DISA McAfee - Prevent unexpected DLL files from Running
in User AppData and ProgramData folders (Sig Id = 7020)
Which is odd because I don't think my program was executing in either such folder; in fact, there are no such folders, as I am looking at the matter. I was able to fix the issue by moving the program to My Documents.
It's also notable that the exception made no hint of interference by a security scanner.
Sigh. I don't know how generally useful this answer is, but I will leave it here. It might help someone. The admins can remove it if they deem appropriate.
Though its an old thread but nevertheless someone else may face similar issue again. In my case, this error occurs when I try to make connection string with password, since in the latest version of sqlite, ecnryption has been a paid feature that's why it doesn't work in free version. So, to circumvant this issue I restored old version of sqlite (picked from my old project) and it worked ok.
Add following reference in your project:
System.Data.SQLite.dll
Copy following files in binary folder:
System.Data.SQLite.dll.config (Optional)
System.Data.SQLite.xml (Optional)
x64\SQLite.Interop.dll
x86\SQLite.Interop.dll
Where 'x64' and 'x86' are folders
Packages available on nuget have same issue so you need old dll
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.
Say I have a Visual Studio Project that references a libary XYZ.dll. I am not able to distribute that dll but I know that many people have a license for it.
What can I do to connect my project to XYZ.dll on the target computer? To be more precise, I want to do the following things:
Reference XYZ.dll in a project in Visual Studio.
Distribute a compiled version of the solution/project without XYZ.dll
Let the customer, who installs my program, link the program to his copy of XYZ.dll so that the program can use it.
(This may be an easy question, but I was not able to find the answer, maybe due to wrong search terms).
If the XYZ.dll is installed with a third-party product, you may check whether it is registered in GAC.
If so, then you - in your VS project - reference the XYZ.dll pointing to it in GAC and then setting the copy local to false, so that it will not be copied to your program's bin directory and used from there.
It becomes more problematic in case the dll is not in GAC - in such case you would need to ask user for the assebly's location (or read it from registry if you know what product to search for) and then resolve this assembly dynamiccaly using that path with the use of AssemblyResolve event (https://msdn.microsoft.com/en-us/library/system.appdomain.assemblyresolve%28v=vs.110%29.aspx)
There is also a way in which you create a "proxy" class in your project that loads the third-party assembly dynamiccaly from the path on the customer's computer, and then create a set of proxy methods that would call loaded third -party assembly using reflection.
I found several problems while using MsBuild from command line and I think they are all related. There are also separated threads for them. The problem occurs for MVC project, created in VS2013.
First - what is the problem.
My bin folder contains several "*.npl" files + some extra dlls
When project A references project B, which references some 3rd party dll, the dll is not present in the package (or at least not on the server after deploy), however log4net is also not referenced in project A, but only in project B, but it IS being copied to bin (and package).
Environment and settings
My run command is like this:
msbuild projectA.csproj /p:Configuration=Release /p:Platform=AnyCpu /p:VisualStudioVersion=12.0 /T:Build
My machine is running Win 8.1 with latest updates, VS2012 MSBuild(4.0.30319.33440) installed. Server runs Windows Server 2008 RC2 with installed VS2013 and slightly updated MSBuild(4.0.30319.34209).
How it behaves
On my local machine, when I run this command, the build runs OK. When I open the bin folder I can see my 3rd party dlls (including log4net) with no extra files. All was built ok.
When I run this command on server, the same bin folder is now missing my 3rd party dlls (but log4net is there!) and there are also some *.nlp files and mscorlib.dll. The build itself returns 9 warning, mostly this one:
There was a mismatch between the processor architecture of the project
being built "MSIL" and the processor architecture of the reference
"{Several_System_Dll_Are_There}", "AMD64".
And one warning complains about missing SDK. Important to note, that I can resolve these warnings and solving the problem number 1 above (npl files..) by appending this line to the command.
/p:FrameworkPathOverride="C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0"
Probably the wierdest thing is the fact, that log4net works ok, but my 3rd party dlls are not. I checked csproj files. ProjectA has no reference to log4net. Only projectB references it. And they are referenced exactly the same (I checked the csproj in notepad). Only two differences are, that log4net was installed using nuget and also, log4 net is configuret in projectA's web.config.
As I was searching trough internet, I found these issues in separated threads and solutions were usualy by adding some extra settings to projects, editing csproj, sln, registry, etc. I don't like these solutions. Especialy, when the build works perfectly on my local machine.
The question is - why the server need frameworkPath to be specified? And why it is still not copying some 3rd party dlls? Why log4net works? And most important - Why is it working on my local machine, but not on the server?
Update - solution of 2. problem
So, it looks like I have a solution for the number 2 problem. The third party dll was referenced in GAC. And based on this Include GAC Assemblies in Bin, it looks like that msbuild can't handle that. adding True to the reference itself (MSBuild doesn't copy references (DLL files) if using project dependencies in solution) was not helping. I finaly had to add the reference on the third party dll to the projectA as well and add the Private tag. Now it works.
This is more like a hot-fix than solution. I don't have time for this.. if someone find a really solid solution, that would be awesome! :-)
I have a weird situation with some code that I inherited at work. Their application is a multi-project solution, with several of the solutions being (code) pieces of the MS Enterprise Library (not sure which version).
They also have an existing C++ (unmanaged) application which has a bunch of DLLs. One of these DLLs is built in a separate solution, both in 64-bit and 32-bit flavours.
The main application has a reference to this DLL, and calls a couple of static functions (I can see intellisense, even). I can compile and build the main application EXEs, but when I run it, I get an exception that this DLL from the unmanaged code (lets call it CPlusPlusCode.dll cannot be found:
FileNotFound Exception was unhandled: Could not load file or assembly 'CPlusPlusCode.dll' or one of its dependencies. The specified module could not be found.
I'm quite stumped, because I can compile the code, see intellisense for the imported classes, and dig into the DLL in the object browser. I even made sure there's a copy in the \bin\Debug folder (although I don't see why that would make a difference). This is for a Windows Forms application.
Also, if it matters, I had some build issues related to x86 vs. x64 for different projects; I think (hope?) that this is not related to that, but I solved that by using the Configuration Manager to build everything as x64.
Check the GAC, and if necessary you might need to add it or register the DLL there.
I had this problem with a project, it all works ok from Visual Studio and most of my times running the project locally on my machine. But because of the unmanaged code I needed specifically allow the project to be executed with correct permission levels.
So have a look in the manifest file, that enough permissions etc exist.