.NET Different References List for Debug / Release - vb.net

In my debug build I have a reference to a DLL that is only required in the Debug configuration (the reference is for CodeSite, a logging tool).
Is it possible to exclude this reference in the Release build (my logging class only uses this reference when built in the Debug configuration).
Using VB.NET and VS2008.

Yes this is possible but it will require you to manually edit the .vbproj file. Once you have the file open you'll an XML reference tag for the DLL's you've referenced and it will look like the following
<Reference Include="SomeDllName" />
You need to add a condition property which species it should only be done during debug time
<Reference Include="SomeDllName" Condition="'$(Configuration)'=='Debug'" />

It's possible to do this, but you'll need to mess with the project file manually.
We do this in MiscUtil so we can have a .NET 2.0 build and a .NET 3.5 build. For instance:
<ItemGroup Condition=" '$(Configuration)' != 'Release 2.0' ">
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
<Aliases>global</Aliases>
</Reference>
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
</ItemGroup>
That should be enough to get you started :) Basically take the current reference out of where it is in your normal project file, and put it in its own ItemGroup with an appropriate condition.

Related

Can't figure out how to include the source code into the nuget package that gets generated

I have several projects in a solution that i want to be packaged to be used as libraries in other solutions. The goal is to make development and debugging seamless, as if it was all in the same solution.
Specifically, I want to be able to ctrl + click on something from the library and be able to view the original source code and not the decompiled code.
I am using PackageReference to include the libraries to the application. What I have noticed is that when I unzip either the nupkg or snupkg, there is no source files anywhere. On that note, I have searched all over the internet and found conflicting things about where the source files go in the nupkg. I have seen mentions of the following folders in the nupkg: lib, src, content, and contentFiles. Which one should actually contain the source code?
When I unzip the nupkg (or snupkg) the only things I have in it are _rels, lib, package, [Content_Types].xml, and PROJECTNAME.nuspec.
I see that the lib folder contains the dll and the pdb file but no source code.
Furthermore, I noticed that the snupkg file is considerably smaller than the nupkg file which I find to be counter intuitive.
I have tried packaging using
msbuild -t:pack
msbuild -t:pack -IncludeSource=true
nuget pack
nuget pack -IncludeSource=true
and also building with visual studio but to no avail.
Here is my vbproj file
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{C64FB67B-64D0-4607-AE35-A21888FE79A2}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>ROOTNAMESPACE_HERE</RootNamespace>
<AssemblyName>PACKAGE_NAME_HERE.ROOTNAMESPACE_HERE</AssemblyName>
<FileAlignment>512</FileAlignment>
<MyType>Windows</MyType>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<Deterministic>true</Deterministic>
<SccProjectName>SAK</SccProjectName>
<SccLocalPath>SAK</SccLocalPath>
<SccAuxPath>SAK</SccAuxPath>
<SccProvider>SAK</SccProvider>
<TargetFrameworkProfile />
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<version>1.0.0</version>
<RepositoryType>git</RepositoryType>
<Authors>COMPANY_HERE</Authors>
<BuildInParallel>false</BuildInParallel>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<IncludeSource>true</IncludeSource>
<PackageId>PACKAGE_NAME_HERE.ROOTNAMESPACE_HERE</PackageId>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
</PropertyGroup>
...
...
...
<ItemGroup>
<PackageReference Include="NuGet.Build.Tasks.Pack" Version="6.4.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
</ItemGroup>
I have also tried using a nuspec file as well but still no success.
I am using .net framework 4.8
I have spent the last 3 days banging my head against the wall over this and haven't been able to figure it out. I have googling non-stop and have even been using ChatGPT to help me try and trouble shoot and no matter what I try I cant get it to work.
Any help would be greatly appreciated!
It sounds like you want to publish nuget packages with SourceLink activated.
SourceLink will add metadata to the packaged assemblies that contains hints about where the original code from which the package was build can be found, e. g. a GIT repository URL and the particular commit SHA. The Visual Studio Debugger during debugging will read the metadata and thus be able to download the source from the repository and show it to you.
This will be the original source like you wanted.
See the docs at https://learn.microsoft.com/en-us/dotnet/standard/library-guidance/sourcelink.
What you have to do is add SourceLink as a package dependency to the project from which the package will be built.
For github and an SDK-style project it looks like this:
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All"/>
<!-- alternatively, using the new GlobalPackageReference element -->
<GlobalPackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" />
Since you seem to be using the old project format, you may need to do it differently. Visual Studio will most likely do the right thing for you when adding the package through the package manager UI.
Note that this is a build-time dependency only and will not add any libraries.
SourceLink by default will only do its job when some MSBuild properties are set. More on that below.
This is a snippet I use (again, SDK-style) to have SourceLink active on every release build:
<PropertyGroup>
<!-- ugly workaround because MSBuild apparently cannot set a bool property from the result of an evaluated expression -->
<TreatAsOfficialBuild>false</TreatAsOfficialBuild>
<!-- Abuse "Release" config as trigger for SourceLink, because I don't want to type -p:ContinuousIntegrationBuild every time
This should work as long as we do not locally debug release builds from commits that have not been pushed to github yet -->
<TreatAsOfficialBuild Condition="'$(Configuration)' == 'Release'">true</TreatAsOfficialBuild>
<PublishRepositoryUrl>$(TreatAsOfficialBuild)</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<ContinuousIntegrationBuild>$(TreatAsOfficialBuild)</ContinuousIntegrationBuild>
<DeterministicSourcePaths>$(TreatAsOfficialBuild)</DeterministicSourcePaths>
</PropertyGroup>
For the debugger to be able to download the source, the package must have been built from a commit that is available on the remote repo.
I trust you already know that you may not be able to debug into that source with breakpoints if the build you are debugging is optimized like in a "Release" build.
If you want to be able to debug through every line of the package's original source, you would have to build that package without optimization (like in a "Debug" build). For SourceLink to be active on debug builds too, you would need to adapt the criteria for the TreatAsOfficialBuild property accordingly.

How to include a local DLL reference in to a nuget package when calling msbuild pack?

We have several projects that need to include a few static DLL. Therefore the project files include code like this:
<ItemGroup>
<Reference Include="..\_Solutions\dependencies\abc123.dll" />
<Reference Include="..\_Solutions\dependencies\def456.dll" />
<Reference Include="System.Web" />
</ItemGroup>
Expected:
We expected that the two dlls; abc123.dll and def456.dll would befound in the nupkg file.
Actual:
However, the nupkg doesn't include the abc123.dll nor the def456.dll files.
One can always include custom content in the nuget-package. Like this:
<ItemGroup>
<Content Include="$(OutputPath)\ReferencedLib.dll">
<Pack>true</Pack>
<PackagePath>lib\$(TargetFramework)</PackagePath>
</Content>
</ItemGroup>
If you target multiple frameworks:
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard1.6</TargetFrameworks>
<TargetsForTfmSpecificContentInPackage>$(TargetsForTfmSpecificContentInPackage);IncludeReferencedProjectInPackage</TargetsForTfmSpecificContentInPackage>
</PropertyGroup>
<Target Name="IncludeReferencedProjectInPackage" Condition="'$(IncludeBuildOutput)' != 'false'">
<ItemGroup>
<TfmSpecificPackageFile Include="$(OutputPath)\ReferencedLib.dll" PackagePath="lib/$(TargetFramework)" />
</ItemGroup>
</Target>
How to include a local DLL reference in to a nuget package when calling msbuild pack?
According the issue on the GitHub, this is currently not directly supported by NuGet.
The workaround I suggest is using the .nuspec file:
NuGet allows you to disable the automatic generation of the resulting
.nuspec file and automatic collection of files by setting the
property in your project, along with a
property that allows you to pass replacement tokens for parsing the
.nuspec file.
See Martin`s answer for details.

Msbuild add reference path

I am using TeamCity to build my solutions remotely and one of my projects has a reference path which is different from the build server. Is there anyway that I can change or add the reference hintpath in the command line of the Visual Studio Runner before the project builds so that the dependency is resolved?
<ItemGroup>
<Reference Include="FeedOSAPI_vc10, Version=2.5.2.1, Culture=neutral>
<SpecificVersion>False</SpecificVersion>
<HintPath>path</HintPath>
</Reference>
<Reference Include="FeedOS_Managed_vc10, Version=0.0.0.0, Culture=neutral>
<SpecificVersion>False</SpecificVersion>
<HintPath>"path</HintPath>
</Reference>
</ItemGroup>
One way you can accomplish this is to use environment variables, both on Build Servers and developer workstations. You can create a binary repository, it can be VCS repository or simlpe file server, and after that you can have one source code for projects which will be able to build anywhere, where the prerequisite conditions are met.
Create environment variable, for example BinRepo, both on Build Server and on dev machine.
Use it in the project like this:
<Reference Include="FeedOSAPI_vc10, Version=2.5.2.1, Culture=neutral>
<SpecificVersion>False</SpecificVersion>
<HintPath>$(BinRepo)FeedOS\FeedOSAPI_vc10.dll</HintPath>
</Reference>
<Reference Include="FeedOS_Managed_vc10, Version=0.0.0.0, Culture=neutral>
<SpecificVersion>False</SpecificVersion>
<HintPath>$(BinRepo)FeedOS\FeedOS_Managed_vc10.dll</HintPath>
</Reference>
Thus you have single code base, and you do not need to specify it elsewhere in the project or from the command line (but you have the ability to do so).

Visual Studio Add Reference - UAC path

I have read the following webpage: http://msdn.microsoft.com/en-us/library/ee817675.aspx and I am interested in the section: 'Use File References Only Where Necessary'
The section seems to suggest that you can add a reference to a DLL on a server. I have version 11 of Oracle.DataAccess on my development PC and version 10 on the live server. It is a pain to deploy the application.
The web page says that a project file should contain a 'References' node, but when I right click on a project file and open with TextPad, there is only an ItemGroup (http://msdn.microsoft.com/en-us/library/646dk05y%28v=vs.90%29.aspx) node. Therefore I have two questions:
1) Where can I find the References node as stated on the webpage?
2) Is it possible to reference an assembly using the UAC path instead of a local path?
Referenced projects is placed in ItemGroup starting from MSBuild 2.0 first link is outdated it from Visual Studion .NET times .NET 1.0/1.1.
<ItemGroup>
<!-- ... -->
<Reference Include="System" />
<Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
</Reference>
<!-- ... -->
</ItemGroup>
For the second question I think yes if you mean UNC path.

Specifying assembly version of all projects within a web deployment wdproj script

I have a .wdproj Web Deployment Project created with VS2010 that contains references to other class libraries, like this:
<Project ToolsVersion="4.0" DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ProjectReference Include="..\Path\Proj1.csproj">
<Project>{GUID-HERE}</Project>
<Name>Proj1</Name>
</ProjectReference>
<ProjectReference Include="..\Path\Proj2.csproj">
<Project>{GUID-HERE}</Project>
<Name>Proj2</Name>
</ProjectReference>
There are lots of these. I want to be able to run msbuild /t:Rebuild /p:Configuration=Release and have all the assemblies of all the included projects compiled at a specified version. Nothing fancy just static like 2.5.6.0 and specified once in the wdproj file. I dont want to open 30 files manually.
I have looked at MSBuild Community Task and MSBuildExtension Pack and can not get anything to work. The build runs ok without errors.
Anyone have an example of how this can be done?
This is an attempt with MSBuild Extensions (adapted from the sample included) that doesn't work:
<Import Project="$(MSBuildExtensionsPath)\ExtensionPack\4.0\MSBuild.ExtensionPack.VersionNumber.targets"/>
<Target Name="Build">
<MSBuild.ExtensionPack.Framework.AssemblyInfo
ComVisible="true"
AssemblyInfoFiles="VersionInfo.cs"
AssemblyFileMajorVersion="2"
AssemblyFileMinorVersion="5"
AssemblyFileBuildNumber="6"
AssemblyFileRevision="0"
/>
</Target>
MSBuild is definately looking at the MSBuild.ExtensionPack.Framework.AssemblyInfo element because if the attribute names are incorrect the build will fail. This builds ok but none of the versions on the referenced assemblies are changed. The version numbers on the ASP.NET page assemblies from the website are all 0.0.0.0.
Are you maybe missing to specify the CodeLanguage and OutputFile attributes?
I think the AssemblyInfo task is intended to generate (replace) a source file prior to compiling.