Visual Studio 2013 DEBUG preprocessor directive always defined - c#

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.

Related

Using VS Code to program C# against custom .DLL with Intellisense

In Visual Studio, I am able to add a custom reference to my C# project:
Solution Explorer -> Dependencies -> Add Project Reference -> ...RevitAPI.dll
After which the code editor supports auto-completion, syntax highlighting, etc. (Intellisense).
Is there a way to accomplish this in VS code? I am referencing the assembly like this in my .csproj-file:
<ItemGroup>
<Reference Include="RevitAPI">
<HintPath>C:\Program Files\Autodesk\Revit 2022\RevitAPI.dll</HintPath>
</Reference>
</ItemGroup>
Also in relation to this assembly reference, I am experiencing an issue when building my project. After using dotnet build, all the referenced assemblies are also included in the Debug folder, not just the .dll-file itself. There is an option --no-dependencies to dotnet build, but this didn't work for me.
Is there any way to exclude the referenced assemblies from my build?

How to set up and use separate folders and dependencies for Debug/Release binaries in Visual Studio

This question is about how to create dependencies in Visual Studio csproj files to different Debug and Release versions of DLL libraries. (I am under the impression that when working on a Release configuration of library54, it should depend on Release versions of libraries23, 24, and 25, not their Debug versions. I imagine that the different Debug/Release versions of libraries would be stored in different folders.
But Visual Studio only gives me one method for creating a single library dependency for a given library name (right click dependencies and browse to the DLL to reference). But I can't browse to separate Debug/Release versions using Visual Studio.
Context: I have more than 50 solutions that each create at least one library or (sometimes multiple) executable files and that have dependencies among the various libraries and executables. Currently, I use post-build events to copy DLLs and executables to a separate (and centralized) debug folder in the debug tree. Then I make all VStudio dependency references point to the DLLs in that debug folder.
An example post-build event script to copy build products to a single destination folder looks like this:
set bindir=%holding%\MyDebugBinaries
echo "Export folder is: %bindir%"
if not exist %bindir% mkdir %bindir%
copy "$(OutDir)$(TargetName).dll" %bindir%
copy "$(OutDir)$(TargetName).deps.json" %bindir%
This method works reasonably well as long as I only want to produce Debug versions of everything or Release versions of everything into that single destination folder so that other projects can reference the objects during the overall build. (Usually I only work on one or two solutions out of the 50 solutions, so they need to link to the libraries in the centralized storage folder.)
But there seems to be no easy way in Visual Studio to represent Debug and Release dependencies as references to objects in different Debug and Release folders. To work on any individual solution in Debug or Release mode, I need to build the whole world into the single destination folder in either Debug or Release mode.
This thread is pretty good, but it skirts around the issue I'm having. It talks about the value and use of separate Debug/Release output folders.
Why have separate Debug and Release folders in Visual Studio?. But I'm talking about something different, I think.
I imagine that MSBuild target elements are smart enough to contain/set/use different dependencies for their relative Debug/Release versions and to use different output folders as well, but is there a way to do all that through Visual Studio methods?
The only way I can think of doing it is to manually edit the VS csproj file to add in custom targets that contain ItemGroup/References like so:
<Target .. Configuration = Debug >
<ItemGroup>
<Reference Include="SomeLibrary">
<HintPath>..\..\DebugFolder\SomeLibrary.dll</Hintpath>
</Reference>
</ItemGroup>
</Target>
<Target .. Configuration = Release >
<ItemGroup>
<Reference Include="SomeLibrary">
<HintPath>..\..\ReleaseFolder\SomeLibrary.dll</Hintpath>
</Reference>
</ItemGroup>
</Target>
I imagine a similar set of Post-Build targets with Debug/Release conditions would do the copying of binaries into the proper centralized Debug/Release folder.
Am I on the right track? Is this kind of thing normally done with manual coding in the project files? Am I missing something obvious? Thank you.

Project works in Visual Studio. But vscode + Omnisharp fails with "You need to specify platform (x86, Win32 or x64)" for Nuget pkg: ScreenRecorderLib

I have C# .Net Framework Winforms project that I've created in Visual Studio. In Visual Studio, everything is fine, it compiles, debugs, runs etc.
But when I try to work on my project in vscode with the Omnisharp extension, Omnisharp can't even parse my project, it fails with error:
...\packages\ScreenRecorderLib.3.1.2\build\ScreenRecorderLib.targets(6,5): Error: ScreenRecorderLib does not work correctly on 'AnyCPU' platform. You need to specify platform (x86, Win32 or x64).
Question #1: Why is this only a problem for vscode/Omnisharp, when everything is fine in Visual Studio?
Question #2: How do I solve this?
I've tried looking at the project properties in Visual Studio, and I have everything set to x64 already as far as I can find for my project (see screenshot below). Although the error is about the Nuget package I'm using: ScreenRecorderLib... So is this even something I can fix within my own project files?
Same issue here. I am avoiding this issue by editing ScreenRecorderLib.targets file which is under C:\Users\<username>\.nuget\packages\screenrecorderlib\3.1.2\build folder.
My final file is like this:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="InjectReference" BeforeTargets="ResolveAssemblyReferences">
<ItemGroup>
<Reference Include="ScreenRecorderLib">
<HintPath>$(MSBuildThisFileDirectory)x64\ScreenRecorderLib.dll</HintPath>
</Reference>
</ItemGroup>
</Target>
</Project>
As you may notice, I am "forcing" in some way to use x64 dll because it is what I need. I cannot consider this as a solution to the problem but at least I can skip this issue and continue.

Using msbuild.exe to build a project with a dependency requiring a different Platform property

I have two fairly straightforward C# projects: An executable that can build as either x86 or AnyCPU, which references (via <ProjectReference>) a DLL project that only has an AnyCPU configuration. This all works as expected within Visual Studio.
I am trying to build the x86 version of the executable project (and its dependencies) from the command line, with /p:Platform="x86". This causes the build of the DLL project to fail. (Whereas /p:Platform="AnyCPU" works, presumably because it is valid for both projects.)
The full command line I am using is:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild MyProject\MyProject.csproj /t:Build /p:Configuration="Release" /p:Platform="x86"
What are my options for getting this build to work from the command line? Preferably without modifying the DLL project at all, or modifying the projects in ways that interfere with using them normally in Visual Studio.
(The ultimate goal here is a batch file that can build a clean version of the project for distribution.)
Additional info:
Both projects have "Debug" and "Release" configurations. The executable project has "x86" and "AnyCPU" available under Platform. The DLL project has only "AnyCPU" available under Platform. The "Platform target" option matches the "Platform" in all cases. (There is no "Prefer 32-bit" option, as I am on VS2010.)
The error seems to be a compilation-related error ("no unsafe code allowed") in the DLL, which -- although I am not 100% sure -- seems to be because none of the <PropertyGroup> elements in the DLL project are being matched (due to Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " etc) that would specify necessary parameters for compilation (eg AllowUnsafeBlocks and DefineConstants).
Answering my own question... First of all, MSBuild can build solution files. This does exactly what you'd expect:
msbuild MySolution.sln /p:Configuration="Release" /p:Platform="x86"
The result is an x86 executable with an AnyCPU DLL (as the solution specifies).
There are a few people out on the internet suggesting that its behaviour is not a perfect match for Visual Studio in some obscure cases. But it seems to work just fine for my purposes. (I think they were having issues with the order things get built in.)
I knew that MSBuild could build a solution file, but -- oops -- I neglected to test it on my simple reproduction case, after it failed on the more complex thing I'm working on.
The above, alone, isn't enough for a fully satisfying answer, particularly if there is a need to customise things. The way MSBuild builds solution files is to create a dummy project file, based on the solution file. This can be inspected by first setting an environment variable like so:
set MSBuildEmitSolution=true
This will emit the dummy project file next to the solution file, which can then be inspected.
I haven't completely analysed what it is doing, but it looks fairly straightforwardly like it is using the <MSBuild> task with the Projects parameter that is itself passing in the solution-specified Configuration and Platform appropriate for each project. According to the documentation it seems to be using the ones specified in AdditionalProperties. (This also seems useful to know.)
For reference, here is some relevant code extracted from the generated project file:
<Target Name="Build" Outputs="#(CollectedBuildOutput)">
<MSBuild Projects="#(ProjectReference)" BuildInParallel="True" Properties="BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" SkipNonexistentProjects="%(ProjectReference.SkipNonexistentProjects)">
<Output TaskParameter="TargetOutputs" ItemName="CollectedBuildOutput" />
</MSBuild>
</Target>
Where #(ProjectReference) is grabbing data from:
<ItemGroup>
<ProjectReference Include="X:\Solution\MyProject\MyProject.csproj">
<ToolsVersion>
</ToolsVersion>
<SkipNonexistentProjects>False</SkipNonexistentProjects>
<AdditionalProperties>Configuration=Release; Platform=x86; VisualStudioVersion=10.0</AdditionalProperties>
<Configuration>Release</Configuration>
<Platform>x86</Platform>
</ProjectReference>
<ProjectReference Include="X:\Solution\DLLProject\DLLProject.csproj">
<ToolsVersion>
</ToolsVersion>
<SkipNonexistentProjects>False</SkipNonexistentProjects>
<AdditionalProperties>Configuration=Release; Platform=AnyCPU; VisualStudioVersion=10.0</AdditionalProperties>
<Configuration>Release</Configuration>
<Platform>AnyCPU</Platform>
</ProjectReference>
</ItemGroup>
(Note the different AdditionalProperties.)

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

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.

Categories