C# using statement inside #if DEBUG but not ship assembly - c#

I have a feature that I only want to happen on Debug, but do not want to ship the dll's that this feature requires. Is that possible to do?
I have:
#if DEBUG
using MyAssembly;
#endif
Of course MyAssembly is being referenced by the project. I would like MyAssembly.dll to not be shipped on a release mode. Can that be achieved? Will using Conditional("DEBUG") help in this regard?

References that aren't required are usually removed automatically by the compiler, however: you can be more explicit by changing the csproj to include a Condition on the PropertyGroup. Something like:
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<Reference Include="YourReference" />
</PropertyGroup>
(it could also be a <PackageReference> etc)

It's perfectly fine to put a using directive in an #if DEBUG section, and it will remove that directive when compiled for debug.
However, that's only part of the story; it won't accomplish your objective by itself. The Solution Explorer in Visual Studio also has a References section. You would need to remove the reference for the assembly, as well, or it will still be included when you build.
I don't recall anything in the Visual Studio user interface that will let you do this, but I expect it should be possible somehow if you manually edit the Project file (it's just an MSBuild file). Personally, I try very hard to avoid doing things that require manual edits to the project files. Visual Studio wants to be able to own these files, and you can end up creating conflicts, where you and Visual Studio overwrite each other's changes.

Related

Visual Studio 2013 DEBUG preprocessor directive always defined

I added a new project to a Visual Studio 2013 (12.0.40629.00 Update 5) solution, and suddenly the #if DEBUG checks pass for compiled code, even in release. The 'define DEBUG constant' is disabled for the release build, and all projects are built as release (as seen in the configuration manager).
I find several things on Google that this is a known bug that can be worked around by unloading and reloading the project (like here, but that doesn't help).
I also tried undef DEBUG, but also no luck.
Existing projects in the solution works, but this new one doesn't. It's a Dotnet standard 4.5, but setting it to 3.5 doesn't help.
As an indication of what happens in a release build:
Visual studio thinks it's inactive code, but it's obviously compiled in and executed (and debugged).
This makes it impossible to make release builds.
Edit: to elaborate on the question below: it's not a unit test, but I am starting to suspect that debug DLLs are taken. To be able to release, I quickly deleted all the code in #if DEBUG, and even after compiling that, the software tried to open the debug DB. When I recompiled debug, it was OK.
I ran into this again. I don't know how I did it, but apparently I added references as links to debug DLL's, instead of to projects in the solution.
This diff of a csproj explains it:
- <Reference Include="Bla.Utils">
- <HintPath>..\BlaUtillLib\obj\Debug\Bla.Utils.dll</HintPath>
- </Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data.Entity" />
## -166,12 +163,19 ##
<Project>{e2bec86c-1c02-4182-8117-740612ed9330}</Project>
<Name>DbDAL</Name>
</ProjectReference>
+ <ProjectReference Include="..\BlaUtillLib\Bla.Utils.csproj">
+ <Project>{6de20344-62f7-45f7-92cd-dbeb19cdc4c5}</Project>
+ <Name>Bla.Utils</Name>
+ </ProjectReference>
I don't know how this happens. I don't go out of my way to browse to DLL's of the solution's own projects.

Visual Studio project reference that isn't version specific at runtime

We have a multi-project solution. The references between projects are done as Project References rather than Assembly Reference (as one would expect). This works fine for our deployment, but creates a runtime dependency that is version specific. The trouble is that we would like to start creating hot fix installers that only update the specific dlls that changed. Updating all dlls is not an option for our current customer situation.
The 'Specific Version' property on project references is disabled and i'm having trouble finding out a workaround other than switching to Assembly References and using Choose blocks in the csproj to switch between debug/release bins based on build config.
Is there another alternative to allow any version to be used at runtime?
MAINTENANCE FREE
The approach we went with was to set the Assembly version to be a fixed number and only update the File version when we build.(we used to keep both in sync with each other). We went with this approach since it was maintenance free and let us keep our references by Project.
The assembly version is what .net uses to find specific versions of a dependent dll. File version is what will display if you view property details on a file via windows explorer.
If you want to be able to hotfix any dll then you'll need to update all of your Assembly References to be versionSpecific=false and set all of your projects to have a fixed assembly version. If you only want to be able to hotfix specific project dlls then you need only fix the assembly version on those projects. The referencing projects could then keep whatever assembly version scheme you want.
Assembly version is set in ProjectFolder/Properties/AssemblyInfo.cs. We've now fixed ours to be 1.0.0.0 and only increment the file version when building.
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.2.3.45678")]
REQUIRES MAINTENANCE
If you are unable to set a fixed Assembly version then another approach can be to use a File reference. The trouble here is that the path your project dlls will vary based on your active build configuration (debug vs release). To get around this you can make your reference be conditional based on the config.
The major downside being that you'll need to maintain the build sequence manually. Also, if you add a new project then you'll need to remember to use these dynamic references again.
<Choose>
<When Condition="'$(Configuration)'=='Release'">
<ItemGroup>
<Reference Include="Your.AssemblyName">
<HintPath>..\Your.AssemblyName\bin\x86\release\Your.AssemblyName.dll</HintPath>
</Reference>
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<Reference Include="Your.AssemblyName">
<HintPath>..\Your.AssemblyName\bin\x86\debug\Your.AssemblyName.dll</HintPath>
</Reference>
</ItemGroup>
</Otherwise>
</Choose>
You can also leave Debug as being a project reference if so desired, this would allow you to see what build sequence visual studio automatically generates due to the project references. You would then be able to mimic that sequence for your release config.

Conditional compilation symbols not being defined for non asp.net project

I have a C# Library Project. I have defined a Conditional Compilation Symbol: SHOULDWORK
But the problem is that this symbol is NOT being defined. I have no idea why.
This is not an asp.net project. I am using VS 2013. I have used Preprocessor Definitions extensively in c++ so it is nothing new to me. But I just can't figure out what the problem is.
I tried rebuilding, restarting VS but to no avail.
I tried using the SHOULDWORK symbol on different source files in that same project but the symbol is not defined.
HELP!!!
Just as sidenote, the DEBUG symbol works as expected. It is defined for Debug builds and not defined for Release builds.
** EDIT
The symbol is correctly stored in the *.csproj file:
** SOLVED
The csproj had several PropertyGroup entries where DefineConstants was being defined.
I manually added the symbols I needed to define to those PropertyGroups and then it worked.
It seems the project file was edited manually in the past, which could have led to this. It will need to be cleaned up but at least for now I can move on.
If using properties panel doesn't work you can modify manually the project file.
Right-click on the file project from vs
Unload project
Right-click again
Edit project file
Now you can modify the project. Find all the propertygroup you are interested in: if you want to add the conditional compilation symbols far all compilation types, you should add the symbol in every single PropertyGroup related to compilation.
This is an example of a propertygroup for compilation:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
Inside the group you'll find the tag <DefineConstants> :
Add here your constant and reload the project.
Sure, you can simply modify le prj outside vs, as a simple text file.

How do I fix a corrupted build manager in vs2010?

I have a C# project in vs2010 that has several build options (Debug, Release, Debug x86, Debug I Just Got A New Hat, etc), because some people have gone a bit overboard in adding projects.
I want to revert all of that to just the four basic build types:
debug x86
release x86
debug x64
release x64
I remove a project, save the sln with that project apparently no longer in the solution, and then add it back, but apparently the settings for the project have been saved. Is there any way to remove these extraneous projects entirely from the build manager and start from scratch short of creating a new SLN file?
The impetus for fixing this problem is that one of the projects in the solution won't allow for an x64 build to be made. If I try to create an x64 build for that project, the build manager states that the x64 build already exists, even when though clearly does not. The build manager isn't allowing me to remove build modes, just add them, but then it doesn't let me add the x64, which is what I'm needing.
Quickest way is to manually edit the .proj files in notepad, removing all the
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'NewHat|x64' ">...</PropertyGroup>
elements for each configuration. Then finally remove the unwanted solution configurations by again editing the .sln file in notepad. They are easy to spot.
Once removed, you should be able to open up the solution in VS and set things right in the configuration manager
The alternatives are to use a macro or VS EnvDTE classes to automate the process but that's perhaps the sledgehammer for a nut.
Normally I don't recommend doing this but you may need to take Notepad or your favourite XML editor and change the contents of your csproj file. The reason I don't like to recommend this approach is that if you get the editing wrong you can end up with a broken project.
Obviously you should back everything up before you start so you can at least get back to your current state if everything goes pear shaped.
Ideally you can dig into your Source Code Control system and get a copy of the csproj file from back when it wasn't broken and use that as a rough guide to what a well formed csproj file for your project looks like.
You can also create a completely new C# project using the same template as your project and use that project's csproj file as another guide to what things should look like.
If you're lucky your csproj file will contain a number of PropertyGroup items, some of which will have a condition identifying the particular build combination the group applies to. For example...
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
If you delete the groups for configurations you no longer want and delete any that seem to apply to x64 you may find that the build manager will let you add an x64 configuration.

C# / VS2008: Add separate debug / release references to a project

When adding a user control or a project reference to a VS 2008 C# project, I can add only one configuration of the assembly. Is it possible to add separate configurations, depending on the configuration of the container project.
E.g. I am developing a user control, and I am working on a sample application. I want to add the user control so that a debug build of the sample will use the debug build of the user control, and the release build of the sample the release build of the user control.
Any suggestions?
<Reference Include="MyLibrary">
<HintPath>..\$(Configuration)\MyLibrary.dll</HintPath>
</Reference>
This add a reference "..\Debug\MyLibrary.dll" if compiled in debug mode or ..\Release\MyLibrary.dll" if compiled in release mode.
You can do this by editing the csproj file; add a "Condition" attribute to the reference.
<Reference Include="Foo" Condition="'$(Configuration)'=='Debug'"/>
<Reference Include="Bar" Condition="'$(Configuration)'=='Release'"/>
However, I would have concerns about what this means for unit testing.
While #Marc Gravell's suggestion will work, is there a reason that you don't want both projects in the same solution? If they are in the same solution, you can add a Project Reference when referencing the User Control project to the sample app's project. When a Project Reference is used, Visual Studio will automatically add the Debug version for a Debug build, and the Release version for the Release build.
Instead of adding reference to a .dll directly, which forces you to choose between the .dll from debug or release folder, you should add reference by choosing 'Project reference'. This link explains how to add reference through .dll vs project-project reference. For your purpose, you should choose the latter.
Also refer to my answer to know when to add reference as a .dll vs reference as a project.

Categories