conditional references in visual studio - how to define the customized variable - c#

I have a project which should reference other projects
done it this way:
<Reference Include="referencedDll" Condition=" '$(Configuration)' == 'Debug' ">
<HintPath>..\Resources\External DLLs\referencedDll.dll</HintPath>
</Reference>
this works fine and copies the dll just in case it is in debug.
but I want it not to depend on debug/ release but some other variable definition
something like:
<Reference Include="referencedDll" Condition=" '$(ReleaseType)' == 'INTERNAL_RELEASE' ">
<HintPath>..\Resources\External DLLs\referencedDll.dll</HintPath>
</Reference>
I did not find how to define the ReleaseType variable?
+ is there any way to use the same variable for both #if in the code and for conditional referencing?
I saw the option to use use
Condition=" $(DefineConstants.Contains('INTERNAL_RELEASE'))"
but it did not work as I'd expect

I'm not completely sure if there is a way to do that in Visual studio.
If you are running the build from msbuild directly you can use /P:ReleaseType=INTERNAL_RELEASE.
In my project I ended up changing Configuration property and instead of having it as Debug and Release I have more values like , DEV,QA,STAGE, etc...

Related

Adding programmatically in C# a project reference (as opposed to an assembly reference) via EnvDTE

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.

Any tool that can change all the References in the Solution for us?

When we have a solution with more than one project and some of these projects are using references to the project in the same solution, for debugging purposes we change the reference to point to the Project , not to the DLL ... well we do it with hand! I was wondering if there is tool that does this for us automatically? so when I have a solution and I run this tool, it should be able to point the references to their project references?
Maybe using a code generation tool using CodeSmith or T4 templates. There you could setup the mappings once, and recreate it automatically. You got to then figure out the deployment part of the genned code.
You might be able to use MSBuild to help you. If you edit your csprog file so that you have 2 ItemGroup blocks with your references...
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<Reference Include="System" />
...
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
...
</ItemGroup>
... then you would get different references in different builds. Note, VS.NET might not refresh the list of references, but you'll see the difference when you build.
This may mean you need to update your csproj by hand, or run some tool to create these two sets of references, but from then on your builds will take care of things automatically.

Conditional references in .NET project, possible to get rid of warning?

I have two references to a SQLite assembly, one for 32-bit and one for 64-bit, which looks like this (this is a test project to try to get rid of the warning, don't get hung up on the paths):
<Reference Condition=" '$(Platform)' == 'x64' " Include="System.Data.SQLite, Version=1.0.61.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=AMD64">
<SpecificVersion>True</SpecificVersion>
<HintPath>..\..\LVK Libraries\SQLite3\version_1.0.65.0\64-bit\System.Data.SQLite.DLL</HintPath>
</Reference>
<Reference Condition=" '$(Platform)' == 'x86' " Include="System.Data.SQLite, Version=1.0.65.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x86">
<SpecificVersion>True</SpecificVersion>
<HintPath>..\..\LVK Libraries\SQLite3\version_1.0.65.0\32-bit\System.Data.SQLite.DLL</HintPath>
</Reference>
This produces the following warning:
Warning 1 The referenced component 'System.Data.SQLite' could not be found.
Is it possible for me to get rid of this warning?
One way I've looked at it to just configure my project to be 32-bit when I develop, and let the build machine fix the reference when building for 64-bit, but this seems a bit awkward and probably prone to errors.
Any other options?
The reason I want to get rid of it is that the warning is apparently being picked up by TeamCity and periodically flagged as something I need to look into, so I'd like to get completely rid of it.
Edit: Per the answer, I tried this:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
...
<SqlitePath>..\..\LVK Libraries\SQLite3\version_1.0.65.0\32-bit</SqlitePath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
...
<SqlitePath>..\..\LVK Libraries\SQLite3\version_1.0.65.0\32-bit</SqlitePath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
...
<SqlitePath>..\..\LVK Libraries\SQLite3\version_1.0.65.0\64-bit</SqlitePath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
...
<SqlitePath>..\..\LVK Libraries\SQLite3\version_1.0.65.0\64-bit</SqlitePath>
</PropertyGroup>
and then in my reference:
<Reference Include="System.Data.SQLite">
<SpecificVersion>False</SpecificVersion>
<HintPath>$(SqlitePath)\System.Data.SQLite.DLL</HintPath>
</Reference>
This got rid of the warning, but is it correct?
If there is no "AnyCPU" assembly for SQL Lite you are stuck with separate builds.
To do separate builds create a property that gives the correct path in a conditional property group and then use that property to have a single reference (i.e. move the conditional outside the references items group). There is an example of using such a property (for a custom FXCop extension) here, you can see lots of conditional properties being defined at the start of the .csproj file.
(Summary: VS doesn't handle all of the possibilities MSBuild does.)
As I see it, the problem with your original project was that you had <SpecificVersion>True</SpecificVersion> specifying System.Data.SQLite, Version=1.0.61.0, whereas the actual assembly was version 1.0.65. Fixing version in the assembly name in Reference ought to help.

Visual Studio Project: How to include a reference for one configuration only?

Env.: VS2008 C# project
I need to build my app for use in 2 different environments. In one of those environments, I need to use a 3rd party DLL assembly.
I could isolate the code that uses this DLL using #if blocks. But how do I conditionally include the reference to the DLL in the CS project file?
Edit: womp has a good point in his comment. I turned into a separate question: Will the referenced DLL be loaded at all if it's never called?
TIA,
Unload the project and open it as .XML
Locate the reference item tag and add a Condition attribute.
For instance:
<ItemGroup>
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xml" />
<Reference Include="MyUtilities.Debug"
Condition="'$(Configuration)'=='Debug'"/>
</ItemGroup>
Notice the last reference now has a condition.
I know this is an old post, but in case anyone else finds it before they find the answer, like I did, it's this: you need to use the "Choose" element in the project file:
link
You can define both conditional references and conditional compilation in one place, so you don't have to use #if's in your code.
It works in SharpDevelop, and since it's MS's documentation I assume it works in Visual Studio.
The following, in the csproj file references itemgroup works in vs 2008 for me:-
<Reference Include="DRLClasses, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL" Condition=" '$(Configuration)' == 'Debug' ">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\Visual Studio User Library\Debug\DRLClasses.dll</HintPath>
</Reference>
<Reference Include="DRLClasses, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL" Condition=" '$(Configuration)' == 'Release' ">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\Visual Studio User Library\Release\DRLClasses.dll</HintPath>
</Reference>
Inspired by the question and answer shown here, you can add <Choose> and <When Condition> commands around the part you want to be conditionally run. For example:
<Choose>
<When Condition="$(USEDLL) == true">
<ItemGroup>
<EmbeddedResource Include="test.dll">
<LogicalName>test.dll</LogicalName>
</EmbeddedResource>
</ItemGroup>
</When>
</Choose>
Then in the CLI, simply use the /p property in MSBuild like this:
MSBuild "C:\myproject\myproject.sln" /p:USEDLL=true
...or if you don't want the DLL, simply:
MSBuild "C:\myproject\myproject.sln" /p:USEDLL=false

want different icons with different builds in C#

We have a product but we are doing some rebranding so we need to be able to build and maintain two versions. I used resource files combined with some #if stuff to solve the strings, images, and whatever else, but the program icon is giving me trouble. I couldn't figure it out from msdn or a google search. Thanks!
Are you referring to the application icon? You can edit your project file manually and put in code similar to the following:
<PropertyGroup>
<ApplicationIcon Condition=" '$(Configuration)' == 'Version1' ">Icon1.ico</ApplicationIcon>
<ApplicationIcon Condition=" '$(Configuration)' == 'Version2' ">Icon2.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup Condition=" '$(Configuration)' == 'Version1' ">
<Content Include="Icon1.ico" />
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)' == 'Version2' ">
<Content Include="Icon2.ico" />
</ItemGroup>
Create icon files named after your config. (E.g. DebugOld.app.ico DebugBranded.app.ico, ReleaseBranded.app.ico)
Create a pre-build step:
copy "$(ProjectDir)$(ConfigurationName).app.ico" "$(ProjectDir)app.ico"
Set the icon in normal code, and you should be able to use the same techniques as you have elsewhere. You'll need both icons in the resources file (at least so I suspect) but it should work.
Alternatively, set a prebuild step to copy the appropriate icon into a common filename - e.g. copying debug.ico or release.ico into app.ico. A bit hacky, but I think it would work. That way you only end up with one icon in the finished binaries.
Yet another option: look into the build file and see how the icon is built in, then conditionalise it. Marc Gravell did this for references in MiscUtil - the project can be built targeting either .NET 2.0 or 3.5, depending on configuration. I suspect that resources could be conditionalised in a very similar way.

Categories