I have a Biztalk project that has the following settings:
General > Redeploy > True
Local Machine > Install to Global Assembly Cache > True
All projects involved have an SNK file generated. However, I removed a reference and it hasn't been cleaned out of the GAC according to biztalk documentation. When I attempt to locate my installed assembly in c:\windows\assembly, I cannot find my BiztalkProject.DLL or the BiztalkLibraries.DLL project there. Is it possible this is a permissions issue, or am I dealing with a different issue?
C:\Windows\Assembly is the CLR 2.0 GAC (.Net 2.0 through 3.5).
If you are using BizTalk Server 2010 or later, you will find the GAC'd Assemblies in the CLR 4.0 GAC at C:\Windows\Microsoft.NET\assembly\GAC_MSIL
You can also use gacutil.exe. Open the Developer Command Prompt, and type
gacutil /l | find "AssemblyName"
to check if it's in the GAC and
gacutil /u AssemblyName
to remove it. Note that AssemblyName can just be the first part of the Fully Qualified Name.
Related
I have a strange behavior with msbuild on my Azure Pipeline.
I'm using Azure Pipeline with Self-hosted Windows agents.
Configuration:
My Visual Studio .sln contains two C# projects:
WebService (Rest API)
Business layer
In addition, the Business layer has dependencies on 2 others projects.
Kernel.DataModel
Kernel.DataAccess
The Kernel.DataAcess layer is using the NuGet package "Microsoft.SqlServer.Types" (14.0.314.76)
The Reference "Microsoft.SqlServer.Types" in the project Kernel.DataAccess has "Copy Local = True". Therefore the DLL file should be copied in the output (release) directory.
The problem:
When I run the Azure Build pipeline, the file "Microsoft.SqlServer.Types.dll" is not copied in the "_PublishedWebsites" directory.
To convince myself, I decided to run the same Pipeline on another build machine by changing the Agent Pool. At my surprise the DLL was present in the "_PublishedWebsites" on the second build machine.
Furthermore, I decided to manually run the msbuild command on my local computer and the the DLL was also present in the "_PublishedWebsites...\bin" on my local machine.
Log files:
I also looked at log files on the Build machines and on my local computer.
First build machine -> The DLL file is simply not copied !
Second build machine -> The DLL file is copied from this location.
Copying file from "C:\Program Files (x86)\Microsoft SQL Server\140\SDK\Assemblies\Microsoft.SqlServer.Types.dll" to "F:\AgentLatestBuild\A1\_work\28\b\_PublishedWebsites\ApiProject\bin\Microsoft.SqlServer.Types.dll".
Local machine ->
_CopyFilesMarkedCopyLocal:
Copying file from "C:\TFS\Repos\Src\Project\**packages**\Microsoft.SqlServer.Types.14.0.314.76\lib\net40\Microsoft.SqlServer.Types.dll" to "E:\tfs\build\Microsoft.SqlServer.Types.dll".
Copying file from "E:\tfs\build\Microsoft.SqlServer.Types.dll" to "E:\tfs\build\_PublishedWebsites\ApiProject\bin\Microsoft.SqlServer.Types.dll".
As you can see:
On the second build machine, msbuild is not using the NuGet packages folder but it's using "C:\Program Files (x86)\Microsoft SQL Server\140\SDK\Assemblies\Microsoft.SqlServer.Types.dll"
On my local machine, the DLL is copied from the NuGet packages folder.
Here are my questions:
How msbuild.exe is selecting the source/location of the DLL ?
Is there a way to force msbuild to first use the NuGet packages instead of any others folders ?
I think msbuild should first look in the NuGet packages folder and if the DLL is not found, then it should try to find it from somewhere else. (C:\Program Files (x86), GAC, etc..)
Finally, do you have any idea why the "Microsoft.SqlServer.Types.dll" is not copied at all on the first build machine. The DLL is present in at least three locations. (ie: NuGet packages folder, C:\Program files\ and it is also in the GAC).
It looks like msbuild is lost in the dependency tracking and can't find the file or it won't copy it for some other reasons.
Thanks for your help.
Is it possible that your *.csproj is targetting the wrong HintPath?
Could you check if you have something like this:
<Reference Include="Microsoft.SqlServer.Types">
<HintPath>..\packages\Microsoft.SqlServer.Types.YOURVERSION\lib\net40\Microsoft.SqlServer.Types.dll</HintPath>
</Reference>
thanks
I have a solution, which consists out of 2 projects: regular class library for .NET 4.5 + website (not web application) project.
When I build this solution with Visual Studio - all referenced assemblies from Nuget packages and local references are copied to bin folder of website project.
If I try to build solution with MsBuild - bin folder of website project does not receive any assemblies.
Website project is not selected to be built in VS configuration (which is reported by message in both cases)
Edit - here is additional explanation.
When I clone a project from git - bin folder of website contains only 4 assemblies already checked in:
If I will run msbuild command with /t:Build or /t:Rebuild and /p:Configuration=Release;Platform="Any CPU" - I'll receive just an output of postbuild event in my other project, included in solution:
However, if I execute build from VS (Ctrl + Shift + b) in Release/Debug config - bin have all required assemblies for running web application.
Edit 2: Link to example solution - https://github.com/akuryan/csharp-website-test
When one builds it with msbuild TestApp.sln /t:Rebuild /p:Configuration=Release;Platform="Any CPU" - this results in only Test.Core.* and LetsEncrypt.Umbraco.dll (initially checked in) found at ~\Test.Web\bin\ (where Test.Web is website project). If one builds TestApp.sln with VisualStudion 2015 (I suppose, 2013 and 2017 will be the same) - ~\Test.Web\bin\ gets whole amount of assemblies.
Different results with MsBuild and Visual Studio
That because the all dll.refresh file in bin folder alongside the binary file are ignored by .gitignore.
Since Web Site projects do not have any project file (.csproj) to put the assembly references, the *.dll.refresh files are used by MSBuild to understand the assembly references. The contents of the file is the relative path to the .dll via the packages folder for the solution. When you ignore all those .dll.refresh by .gitignore, MSBuild could not understand how to handle the dll files.
To test this, I created a website project, add a nuget package to it, then delete the dll files but keep the .dll.refresh files in the bin folder. Build the website project by MSBuild command line:
msbuild.exe TestWebsite.sln /t:Rebuild
After this command complete, the dll files are copy to the bin folder.
So build and package restore to work it looks like you need to keep the .dll.refresh files in the bin folder. You can remove the other binaries from your version control system.
Note: If you want to get those .dll.refresh back, you can use the command line in the Package Manager Console:
update-package -reinstall
Hope this helps.
Attempting to build a Visual Studio 2010 solution with 132 projects which do not use any file references (only project references). When I build the entire solution, I get many build errors like this:
The type or namespace name 'xxxx' does not exist in the namespace '<namespace name>' (are you missing an assembly reference?)
The target framework version for ALL projects in the solution is v3.5.
Hence I started building projects one by one based on the Project Build Order. And on one of the projects (say project A), I get the below info in the Build Output (note the framework version). This project A builds successfully.
When I build the next project, say project B, which references project A through a project reference (not file reference), then it throws the above build error. Hence it seems project B is the culprit.
Compile complete -- 0 errors, 54 warnings
<ProjectName> -> <filepath>\<filename>.dll
Microsoft (R) .NET Global Assembly Cache Utility. Version 4.0.30319.1
Copyright (c) Microsoft Corporation. All rights reserved.
Details of project B
Solution configuration is Debug.
In the References tree of project B, the properties of the project A reference shows
1) "Runtime Version" as v2.0.50727.
2) "Copy local" as True.
3) "Strong Name" as True.
4) "Version" as 1.0.xxxx.xx (as specified in the AssemblyInfo.cs of project A)
5) There is no "Specific Version" key (because it is a project reference)
the AssemblyInfo.cs of project B has the following:
1) [assembly: ComVisible(false)]
2) [assembly:Guid("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")]
3) [assembly:AssemblyVersion("1.0.xxxx.xx")]
4) [assembly:AssemblyFileVersion("9.0.xxxx.xx")]
the project B properties has the following:
1) "Target Framework" as ".NET Framework 3.5"
2) "Output Type" as "Class Library"
3) "Treat warnings as errors" as "None"
My Question(s)
Now, the target framework specified in the properties of ALL my projects is .NET Framework 3.5.
How does the build engine use a GAC Utility of v4.0 when my target framework is v3.5?
Searched all files to see if .NET 4.0 is configured somewhere but could not find it.
This seems to be potentially the root cause of the above issue. Or am I missing something else? I believe I have covered the usual suspects.
Also why does the Runtime Version of project A reference in project B say v2.0.50727 when the target framework version for both projects is v3.5?
PS:
I tried removing the project reference and adding its file reference instead, still gives the same build error. (This usually used to work before when it was a long name issue but its not in this case).
UPDATE 1:
The build output for the above build error is:
Compile complete -- 13 errors, 0 warnings
C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(1360,9):
warning MSB3258: The primary reference "<project A reference name>" could not be resolved
because it has an indirect dependency on the .NET Framework assembly
"mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxxxxx"
which has a higher version "4.0.0.0" than the version "2.0.0.0" in the current target framework.
UPDATE 2:
The Post-build event command-line for project A has the following which explains why the build uses the GAC Utility of v4.0! Now I need to figure how to get the v3.5 Gacutil in there.
My second question still stands though.
cd "$(ProjectDir)"
cd ..\..\..\Bin
gacutil.exe /if "$(TargetPath)"
To answer your second question:
.Net 3.0 and .Net 3.5 are simply new DLLs that run on the existing CLR 2.0.
There are no runtime versions between 2.0 and 4.0.
I am using Bamboo [from Altassian] and it uses the devenv.com builder to build solution files. Currently, I seem to be getting a "false" error in my builds - that I've tried to solve by myself but just can't - so I thought I would ask.
Each build succeeds normally - without errors stemming from code - but seems to instead give this error
Package 'Microsoft.VisualStudio.TestTools.TestCaseManagement.QualityToolsPackage, Microsoft.VisualStudio.QualityTools.TestCaseManagement, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' failed to load.
I've no idea why this is causing problems in the devenv.com environment and I can't figure out either how to "ignore" this error by some build command?
Try this ( from MSFT support )
Can you check if the dll is in the global assembly cache (open a VS 2010 command prompt
(Start | All Programs | Microsoft Visual Studio 10.0 | Visual Studio Tools))
Type in
Gacutil –l > list.txt
Notepad list.txt
Do you see an entry like
Microsoft.VisualStudio.QualityTools.TestCaseManagement, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL
If so, from the same command prompt, run fuslogvw, go to settings, select log bind failures to disk, select ok
Run your command line
C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\devenv.com /Build "Release|Mixed Platforms" "D:\Builds\19\Test VizXView\VizXView v1.8 Test Release Build - Weekly\Sources\VizXView v1.8\VizXView 1.8.sln"
Click on the refresh button in fuslogvw. Do we get any bind errors?
I had a similar issue related to running unit tests on a build server that was using devenv.exe (not devenv.com). I had a premium VS installed on the build server but I'd written the unit tests with ultimate (which 'has' load testing, even tho I'd not used it). I used fusion viewer to work out that the missing dll was LoadTest.dll which I copied from my laptop to the buildserver, I also removed references in my solution that were in version control to: *.vsmdi and *.testsettings (they're deprecated) and I removed from the build def a reference to a .testsettings file.
My guess would be that even though I wasn't running a load unit test the build agent was trying to load the LoadTest libs just in case. Hope that helps
edit ---
ok, my own problem here was that I've got both vs2010 and vs2013 on my laptop. When I added the first test project to my VS2010 solution, the project added actually has a dependency on the 2013 version of the UnitTestFramework.dll. My build server only has vs2010 on it so I got the missing assembly error. Switching the reference to the 2010 version fixed this.
I've just upgraded a project from VS2008 to VS2010 but I'm still targeting the 3.5 framework.
In my project file I have a custom task to run SGEN to generate my XmlSerializers.dll. However the version of sgen being run targets the 4.0 framework. As a result, when I run my application I get the error message:
"Could not load file or assembly 'XXXX.XXXX.XmlSerializers' or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded."
The Sgen task looks like this:
<Target Name="AfterBuild" DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource" Inputs="$(MSBuildAllProjects);#(IntermediateAssembly)" Outputs="$(OutputPath)$(_SGenDllName)">
<!-- Delete the file because I can't figure out how to force the SGen task. -->
<Delete Files="$(TargetDir)$(TargetName).XmlSerializers.dll" ContinueOnError="true" />
<SGen BuildAssemblyName="$(TargetFileName)" BuildAssemblyPath="$(OutputPath)" References="#(ReferencePath)" ShouldGenerateSerializer="true" UseProxyTypes="false" KeyContainer="$(KeyContainerName)" KeyFile="$(KeyOriginatorFile)" DelaySign="$(DelaySign)" ToolPath="$(SGenToolPath)">
<Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly" />
</SGen>
</Target>
There's the ToolPath="$(SGenToolPath)". How do I make it run the version that targets 3.5?
There's a similar question here but it doesn't help me much.
I have solved this by manually configuring the ToolPath to point to the old (version 2.0.50727.3038) version of sgen.exe
On my machine, this is in: C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin
I changed the ToolPath attribute to be:
ToolPath="C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin"
and this solved the problem.
It seems, by default, it's running the new 4.0 framework version in: C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools
Hope this helps somebody else.
MSBuild uses the registry to get the path to the v3.5 tools. The MSBuild tasks that require v3.5 SDK tools will fall back to the v4.0 path if the path to the 3.5 tools can't be identified - look at the logic used to set the TargetFrameworkSDKToolsDirectory property in C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.NETFramework.props if you're really interested.
You can diagnose and fix this problem as follows:
Install Process Monitor and set up a filter to monitor registry access by msbuild (Event class: Registry, Process Name: msbuild.exe, all types of result).
Run your build.
Search Process Monitor for a RegQueryValue access matching "MSBuild\ToolsVersions\4.0\SDK35ToolsPath". Note that this could be be under either "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft" or "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft".
If you have a look at this key in the registry, you'll see that it aliases another registry value, e.g. "$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1\WinSDK-NetFx35Tools-x86#InstallationFolder)"
Shortly after this, you'll probably see a "NAME NOT FOUND" result. If you look at where the expected key should be, you'll see that they don't match the key being requested (missing hyphens and possibly no key ending with "-86").
It should be clear what you need to correct. I chose to export the incorrect keys, edit the .reg file and run it to create the correct keys.
One cause of invalid registry entries could be a bug with the Microsoft SDK v7.1 installation:
http://connect.microsoft.com/VisualStudio/feedback/details/594338/tfs-2010-build-agent-and-windows-7-1-sdk-targeting-net-3-5-generates-wrong-embedded-resources
I found this to be the easiest way and it works with: <GenerateSerializationAssemblies>On</ GenerateSerializationAssemblies>
<SGenToolPath>C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin</SGenToolPath>
The problem is $(SGenToolPath) isn't set by MSBuild. If you use $(TargetFrameworkSDKToolsDirectory) then it will attempt to resolve the path based on $(TargetFrameworkVersion).
Its helpful to make use of tags for printf() style debugging. Add the following temporally.
<Target Name="AfterBuild" DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource" Inputs="$(MSBuildAllProjects);#(IntermediateAssembly)" Outputs="$(OutputPath)$(_SGenDllName)">
<Message Text="SGenPath: $(SGenPath)" Importance="high"/>
<Message Text="TargetFrameworkVersion: $(TargetFrameworkVersion)" Importance="high"/>
<Message Text="TargetFrameworkSDKToolsDirectory : $(TargetFrameworkSDKToolsDirectory )" Importance="high"/>
#Craig - Did you manually install the 7.0A framework on your build machine. If so, your problem may be your registry settings and not msbuild. Take a look at LocalMachine -> Software -> Microsoft -> MSBuild -> ToolsVersions -> 4.0 -> SDK35ToolsPath and make sure the reg key that is referenced there is valid. (Hint: Make sure the -x86 is there only if the -x86 key exists.)