I know I can reference an assembly depending on the project configuration, but can I do it based on the solution configuration? I'm thinking of something like this:
<ItemGroup Condition="'$(SolutionConfiguration)' == 'Debug1'>
<Reference Include="Library1">
<HintPath>C:\Path\To\Library1.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup Condition="'$(SolutionConfiguration)' == 'Debug2'>
<Reference Include="Library2">
<HintPath>C:\Path\To\Library2.dll</HintPath>
</Reference>
</ItemGroup>
If not like this, is there any other way I can reference one or another assembly depending on the solution configuration?
Solution configurations are linked to project configurations. For each solution configuration, we specifiy which project configurations to use. For example, when we select solution Release, projects Release are typically selected.
So create two project configurations matching the two solution configurations you want for the dll you want. When you select a solution configuration, different project configurations will be selected and the correct dll will de referenced.
Related
I need to have a single place to define variables for a solution that has about 13 projects, each having a varying combination of external dependencies from the same few locations. Right now, it's easy enough to include these as a variable in a PropertyGroup, but if something changes (like a version number), we don't want to have to update each project file with that change.
I tried creating a targets file that has the variables that get used from project to project and included it into the csproj file, just before the assembly references. This appears to have worked beautifully in a website project, but not in a class library project. The references are not found.
How am I supposed to do this in a way that's safe and usable across project types? (No, Nuget is not an option in this case.)
Example of the Global Targets file:
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Product1Version>02.01.01</Product1Version>
<Product2Version>03.02.01</Product2Version>
<ReferencesPath>..\..\References</ReferencesPath>
<Product1ReferencePath>$(ReferencesPath)\Product1\$(Product1Version)</Product1ReferencePath>
<Product2ReferencePath>$(ReferencesPath)\Product2\$(Product2Version)</Product2ReferencePath>
</PropertyGroup>
</Project>
Here is an example of how I intend to use this in a csproj file:
<Import Project="..\..\Build\SolutionReferences.targets" Condition="false" />
<ItemGroup>
<Reference Include="Product1">
<SpecificVersion>False</SpecificVersion>
<HintPath>$(Product1ReferencePath)\Product1.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Product2">
<SpecificVersion>False</SpecificVersion>
<HintPath>$(Product2ReferencePath)\Product2.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
Ugh... All I had to do was remove Condition="false" from the Import command. :(
I have a .csproj for the .NetCore platform with classic references. I'm using the hintpath attribute for the development environment. But I should build csproj on the CI-environment where referenced assemblies are placed in the different directory.
On the classic net4 I've used the /p:ReferencePath argument for the MSBuild tool.
But the "dotnet build" has no similar argument.
As a fallback I found the "dotnet msbuild" command but this tool is ignores the /p:ReferencePath=xxx argument and shows me
warning MSB3245: Could not resolve this reference. Could not locate the assembly "AssemblyName". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors.
Please guide me, what can I check, where dotnet-build/dotnet-msbuild tools are searching the referenced assemblies and how to specify that directory?
Problem is coused by Microsoft.NET.Sdk.props: AssemblySearchPaths has no ReferencePath.
Fixed by adding to csproj:
<PropertyGroup>
<AssemblySearchPaths>
$(AssemblySearchPaths);
$(ReferencePath);
</AssemblySearchPaths>
</PropertyGroup>
You can still build .net CORE/Standard projects in solution using MSBUILD.
It is seem to be a bug which I reported to Microsoft that (and this is not about core/standard but rather new project file format) referencePath is ignored with new project file format.
Supply add /t:restore to msbuild command along with build target, so it will restore and build at same time.
The work-around for your CI/Build server situation is to create a special solution configuration, and add similar to following into your project file
<Choose>
<When Condition="'$(Configuration)|$(Platform)'=='YourSpecialConfiguration|x64'"><!-- attention here -->
<ItemGroup>
<Reference Include="your.dllname">
<HintPath>yourSpecialPath\your.dllname.dll</HintPath><!-- attention here -->
<Private>true</Private>
</Reference>
<!-- more references here -->
</When>
<Otherwise>
<ItemGroup>
<Reference Include="your.dllname">
<HintPath>yourRegularPath\your.dllname.dll</HintPath><!-- attention here -->
<Private>true</Private>
</Reference>
<!-- AND more references here -->
</Otherwise>
</Choose>
This will allow you to just change configuration name in CI/Build and will do the job.
But the "dotnet build" has no similar argument.
Why are you saying that?
The dotnet cli still support "property injection" with -p instead of /p. Link (Search for "-p")
For your question, the build command will look like this command:
dotnet build -p:ReferencePath=xxx
I have a third party DLL which I need to reference in multiple c# projects in a solution.
It is presently referenced as follows.
<Reference Include="Contoso.App, Version=4.0.5.0, Culture=neutral, PublicKeyToken=xxxxxxxx, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\ThirdParty\Contoso\4.0.5.0\Contoso.App.dll</HintPath>
</Reference>
I have around 40 projects in my solution which reference the Contoso.App.Dll
Whenever the DLL version changes a new folder is created as follows
..\ThirdParty\Contoso\5.0\
I have to go and update all my 40 projects as follows.
<Reference Include="Contoso.App, Culture=neutral, PublicKeyToken=xxxxxxxx, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\ThirdParty\Contoso\5.0\Contoso.App.dll</HintPath>
</Reference>
Is there a better way to manage the version change of the DLL?
Can I create single variable in the solution and reuse it across all the projects?
Private NuGet repository is prefect, but requires too many changes. A simpler way is to create a common project and let other projects reference this common project.
common.props. It's better to use solution relative path instead of ...
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Reference Include="Contoso.App, Culture=neutral, PublicKeyToken=xxxxxxxx, processorArchitecture=MSIL">
<HintPath>..\ThirdParty\Contoso\5.0\Contoso.App.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
Import it in other project.
<Import Project="<MySolutionPath>\common.props"/>
There may be build errors in VS after changes are made in common.props because the reference is updated instantly. Verify it via command line msbuild.exe first.
Setup a Private Nuget Repository that the rest of your team can access.
See Scott's answer.
tl;dr
Open Visual Studios
Create a new Empty Web Project
Add the Nuget.Server Package
Package manager console: install-package nuget.server
Overwrite web.config: Yes
Open Web.config
Set appSettings
packagesPath: where the nuget is going to sit
Init:
nuget init c:\source c:\localnuget
Push:
nuget push {package file} -s http://localhost:51217/nuget {apikey}
Alternate hosting
Just to add flexibility to TriV's comment, you can define an environment variable (e.g. CONTOSO_VERSION) and use it in the pre-build event command to copy the DLL into your bin folder (or wherever you're referencing from) using $CONTOSO_VERSION. This way you can change the referenced DLL version back and forth via env variable. Make sure it's pre-build event for a project others depend on (or create a dummy project with others depending on it for a solution-wide pre-build event).
In visual studio when you add a reference to an existing project in your solution in the .csproj file it ends up like so:
<ProjectReference Include="..\TestProject2\TestProject2.csproj">
<Project>{15EC8369-B0C5-4F71-A366-19042F450A2D}</Project>
<Name>TestProject2</Name>
</ProjectReference>
If I add a reference to an assembly DLL via EnvDTE:
var p = _project as VsProject;
p.References.Add(<path to assembly DLL>);
it ends like this:
<Reference Include="TestProject2.csproj">
<HintPath>..\TestProject2\bin\Debug\TestProject2.csproj.dll</HintPath>
</Reference>
This is not so great because if I switch to a Release build it will still reference the debug assembly. Another problem is that I have to build the referenced assembly before I can add it as a reference. With Visual Studio UI I can add a reference to an unbuilt project.
Is it possible via the EnvDTE API to add a project reference?
I know I can manipulate the .csproj file as an XML document and do whatever I want, but since I started on the path on EnvDTE I would prefer to stick to it.
It looks like the References interface has an AddProject method which handles project-to-project refrences.
What worked for me is to formulate references this way:
<Reference
Include="MyDll"
Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<HintPath>..\..\somePath\Debug\myDll.dll</HintPath>
</Reference>
<Reference
Include="MyDll"
Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<HintPath>..\..\somePath\Release\myDll.dll</HintPath>
</Reference>
This way, the release build references release dependency, and debug build references Debug.
Of course, x86/x64 can also be handled if necessary. This was for a 32-bit app.
Is it possible to add to my C# project a reference to a different dll versions in x86 and x64 (and switch automatically between them, while changing Configuration Mode)?
I don't think there's anything in the IDE that will do this, but you can accomplish this by manually editing the C# project file.
Something that looks like: <Reference Include="ThirdPartyAssembly" />
Could be changed to:
<Reference Include="ThirdPartyAssembly.x86" Condition="'$(Platform)' == 'x86'" />
<Reference Include="ThirdPartyAssembly.x64" Condition="'$(Platform)' == 'x64'" />