How to make SQL projects load version from props file? - visual-studio

I have created several SQL projects in visual studio, I want to manage the version of the dacpac in a centralized way. In order to fulfill that I want to reuse a props file using the answer this post :
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="$(MSBuildProjectExtension) == '.csproj'">
<CommonPlatform>$(Platform)</CommonPlatform>
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)myfile.snk</AssemblyOriginatorKeyFile>
<LinkKeyFile>$(MSBuildThisFileDirectory)myfile.snk</LinkKeyFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup Condition="$(MSBuildProjectExtension) == '.csproj'">
<Compile Include="$(MSBuildThisFileDirectory)CommonAssemblyInfo.cs">
<Link>Properties\CommonAssemblyInfo.cs</Link>
</Compile>
</ItemGroup>
<Import Project="StyleCop\StyleCop.Targets" Condition="$(MSBuildProjectExtension) == '.csproj'"/>
<!--Version management for DACPAC projects -->
<PropertyGroup Condition="$(MSBuildProjectExtension) == '.sqlproj'">
<DacVersion>15.1.0.0</DacVersion>
<DacDescription>Release 15.1</DacDescription>
</PropertyGroup>
</Project>
in the sql project I add the following import sentence:
<Import Project="..\..\Environment\MyPropsFile.props" />
If I check the properties of the project in visual studio I got this:
I build the project and unpack the dacpac file, I check the DacMetadata.xml and got this:
<?xml version="1.0" encoding="utf-8"?>
<DacType xmlns="http://schemas.microsoft.com/sqlserver/dac/Serialization/2012/02">
<Name>MyDB</Name>
<Version>1.0.0.0</Version>
</DacType>
If I build the MSBuild for the sql project and unpack the dacpac file, I check the DacMetadata.xml and got this:
<?xml version="1.0" encoding="utf-8"?>
<DacType xmlns="http://schemas.microsoft.com/sqlserver/dac/Serialization/2012/02">
<Name>MyDB</Name>
<Version>15.1.0.0</Version>
<Description>Release 15.1</Description>
</DacType>
What should I do to see the changes in the version and description from Visual Studio?

This approach can work in Visual Studio, but the DAC version metadata is unfortunately cached when the solution is loaded. This means that if you want the metadata to be reloaded from the props file, you must close and re-open the entire solution. (Unloading and reloading the database project isn't sufficient).

Related

Why am I getting warning NU1507 with Central Package Management even with Package Source Mapping set?

I'm trying out the new Central Package Management feature in NuGet.
As stated in the documentation, if you use multiple NuGet sources (which I use), it is now required to configure the Package Source Mapping in a nuget.config file, otherwise you should get a NU1507 warning.
My simplified file tree is this:
MySolution.sln
Proj1.csproj
MyLibrary\ (this is an external repository with all my shared projects)
Directory.Packages.props
nuget.config
Proj2\ (an example library project)
Proj2.csproj
Here is the Proj1.csproj content:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<PropertyGroup>
<DefaultItemExcludes>$(DefaultItemExcludes);MyLibrary\**\*</DefaultItemExcludes>
</PropertyGroup>
</Project>
Here is Directory.Packages.props:
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="JetBrains.Annotations" Version="2022.1.0" />
</ItemGroup>
</Project>
Here is nuget.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear/>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json"/>
<add key="Custom NuGet" value="https://nuget.mydomain.net/"/>
</packageSources>
<packageSourceMapping>
<packageSource key="nuget.org">
<package pattern="*"/>
</packageSource>
<packageSource key="Custom NuGet">
<package pattern="MyNamespace.*"/>
</packageSource>
</packageSourceMapping>
</configuration>
and Proj2.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>
In the official documentation the MyLibrary\nuget.config should be used when restoring the packages because it is in the parent directory of Proj2.csproj, and actually it works when I build the solution via dotnet build, but when I build it in Visual Studio I still get the NU1507 warning.
I know that I could work around the issue by copying the nuget.config file in the same directory as the solution file (the warning goes away), but I have hundreds of projects that include the MyLibrary directory and I'd like to keep all the configuration centralized.
Moreover it works as expected when it's built from the command line, so what am I doing wrong?
Everything seems like correct from your configure file.But MS doc has mentioned this note:Central package management is in active development. You can provide any feedback you may have at Nuget/Home
Here’re suggestions you can have a try to check :
1 check your visual studio version and this feature is available for Visual Studio 2022.17.2 and later.Because older tooling will ignore central package management configurations and features.See more information please refer to doc:CPM
2 If you are unable to onboard to Package Source Mapping but want to use central package management, can suppress the warning. Please refer to doc:
<PropertyGroup>
<NoWarn>$(NoWarn);NU1507</NoWarn>
</PropertyGroup>
3 use dotnet nuget list source to get package source list and check whether they are enabled.

Visual Studio publish generates .pdb file despite using DebugType=None

I'm publishing a console app from within Visual Studio using the following publish profile:
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishProtocol>FileSystem</PublishProtocol>
<Configuration>Release</Configuration>
<Platform>x64</Platform>
<TargetFramework>netcoreapp5.0</TargetFramework>
<PublishDir>bin\Release\netcoreapp5.0\publish\</PublishDir>
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
<SelfContained>False</SelfContained>
<PublishSingleFile>True</PublishSingleFile>
<PublishReadyToRun>True</PublishReadyToRun>
<IncludeNativeLibrariesForSelfExtract>True</IncludeNativeLibrariesForSelfExtract>
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>
</Project>
My goal is to not emit any .pdb files (debug symbols) in the publish output folder.
This doesn't completely work as intended.
The .pdb file of the console app project is not generated - as expected, but the debug symbols for the business logic project it references is for some reason generated. Is this a bug?
I can hack this by adding a conditional statement to the project file of the business logic library, but that it something I'd like to avoid as I think all the relevant information for publishing the app should reside in the publish profile.
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>
<DebugType>none</DebugType><DebugSymbols>false</DebugSymbols> will only prevent the generation of the current project's pdb file. And if your main project referenced a second project, these nodes will not prevent the the second project's pdb file in the main project. This is designed by that.
And if you want to prevent the referenced project's pdb file being generated into the publish folder of the main project, you should use this node additionally:
<AllowedReferenceRelatedFileExtensions>*.pdb</AllowedReferenceRelatedFileExtensions>
Solution
Add these in your pubxml file:
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
<AllowedReferenceRelatedFileExtensions>*.pdb</AllowedReferenceRelatedFileExtensions>

Why doesn't Directory.Build.props work when building a solution using Visual Studio 2017?

I have a Directory.Build.props file located in the same directory as the .sln file.
<Project>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DocumentationFile>bin\Debug\$(MSBuildProjectName).xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DocumentationFile>bin\Release\$(MSBuildProjectName).xml</DocumentationFile>
</PropertyGroup>
</Project>
When I build the solution using MSBuild, I am able to generate the XML files properly. However, using a Build -> Rebuild Solution task in Visual Studio doesn't generate the XML file.
Is there a difference in how Visual Studio 2017 builds and uses Directory.Build.props as opposed to MSbuild?
I had added the directory.build.props as a solution item. This somehow prevented Visual Studio from picking it up and using it in the build process. Once I removed it as a solution item, this worked fine.
You also might have to delete your .vs directory (or portion of) as it seems to be cached there as well.
https://developercommunity.visualstudio.com/content/problem/248037/defaultbuildprops-with-langversion-is-not-used-by.html
You need to check that your project file contains next row in the beginning of file
<?xml version="1.0" encoding="utf-8"?>
<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')" />
Without row Import 'magic' doesn't happen. So, you need to insert this row to all your old projects

Visual Studio Publish Profile Publishes Wrong Build Configuration

I'm trying to automate deploying a Web Api 2 project with Visual Studio 2013. I've made a publish profile named "Test" shown below
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit http://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>x86</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<publishUrl>C:\DbServiceDeploy</publishUrl>
<DeleteExistingFiles>True</DeleteExistingFiles>
</PropertyGroup>
</Project>
Even though it has the line <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration> it seems like Visual Studio is publishing my debug build. I'm calling msbuild like so
"C:\Program Files (x86)\MSBuild\12.0\Bin\MSBuild.exe" C:\somefolder\Myproj.csproj /p:
DeployOnBuild=true /p:PublishProfile=Test
This excellent blog post led me to find the answer http://sedodream.com/2012/10/27/MSBuildHowToSetTheConfigurationProperty.aspx . I'll summarize in case the link dies: when a build is kicked off MsBuild evaluates the properties once and uses that value for the remainder of the build. Since the Configuration property was resolving to Debug MsBuild was using that as the Configuration to publish.
TLDR;
Pass the configuration on the command line, add
/p:Configuration=Release
to the command line call

How can I use a single Visual Studio solution to build both x86 and x64 at the same time?

I've got an x86 Visual Studio solution with many project files in it. Some of the DLL files are designed to work as plug-ins to other applications on a user's system.
We're expanding some of the DLL files to be able to support 64-bit applications. I'd like to set up the solution/projects so that just hitting "Build" will build both the x86 and x64 versions of those DLL
files. The solution contains both C++ and C# projects.
I realize that "Batch Build" is capable of building both, though it would be more convenient if developers could just click the same button as they have previously and have all of the output DLL files generated.
Here are a couple of the modifications that I've tried to a test project, but that I haven't gotten to work:
I've tried modifying the <Target Name="AfterBuild"> to try:
<Target Name="AfterBuild" Condition=" '$(Platform)' == 'x86' ">
<PropertyGroup>
<Platform>x64</Platform>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<CallTarget Targets="Build"/>
</Target>
But that results in the following error:
C:\Windows\Microsoft.NET\Framework\v3.5\Microsoft.Common.targets(565,5): error MSB4006: There is a circular dependency in the target dependency graph involving target "Build".
I think my conditions will prevent infinite recursion, but I understand how MSBuild could not see it that way.
I've also tried:
<Project DefaultTargets="MyBuild86;MyBuild64" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
...
<Target Name="MyBuild86">
<PropertyGroup>
<Platform>x86</Platform>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<CallTarget Targets="Build"/>
</Target>
<Target Name="MyBuild64">
<PropertyGroup>
<Platform>x64</Platform>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<CallTarget Targets="Build"/>
</Target>
But my DefaultTargets appears to be ignored from within the Visual Studio IDE.
Last, I've tried creating a separate project that imports the first project:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform>x64</Platform>
<PlatformTarget>x64</PlatformTarget>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<OutputPath>..\$(Configuration)\x64\</OutputPath>
<ProjectGuid>{A885CAC3-2BBE-4808-B470-5B8D482CFF0A}</ProjectGuid>
</PropertyGroup>
<Import Project="BuildTest.csproj" />
</Project>
And this so far has shown the most promise. However, Visual Studio seems to ignore my OutputPath setting from this new project and instead outputs the EXE/DLL file to the path specified in the original project. There isn't any PropertyGroup block that I can see that is being executed in the original project to override this, so I'm not sure what's happening.
We do something similar to build core assemblies for .NET Compact Framework.
Try this:
<Target Name="AfterBuild">
<MSBuild Condition=" '$(Platform)' == 'x86' " Projects="$(MSBuildProjectFile)" Properties="Platform=x64;PlatFormTarget=x64" RunEachTargetSeparately="true" />
</Target>
Importing a project in such manner works for me in Visual Studio 2010:
TestProject64.vcxproj
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="TestProject.vcxproj" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{B7D61F1C-B413-4768-8BDB-31FD464AD053}</ProjectGuid>
</PropertyGroup>
</Project>
TestProject64.vcxproj.filters
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="TestProject.vcxproj.filters" />
</Project>
TestProject.vcxproj has two configurations defined inside: Release|x86 and Release|x64. As you can see, TestProject64.vcxproj has only the Release|x64 configuration. Defining of at least one configuration in TestProject64.vcxproj is necessary, otherwise Visual Studio will not be able to add TestProject64.vcxproj to a solution.
Now it's possible to include both TestProject.vcxproj and TestProject64.vcxproj to the same solution and build Release|x86 and Release|x64 at the same time.
I think the best way of doing this is to invoke MSBuild from the command line. It shouldn't need editing of MSBuild files. Just run
msbuild myproj.sln /p:Configuration="Debug|Win32"
msbuild myproj.sln /p:Configuration="Debug|x64"
I assume that if a developer is using Visual Studio then they'll only be generating the DLL files so they can debug with them, and that you have a separate build process if you're actually deploying the DLL files.
For C++, and if it's a project whose files/settings don't change often, one way to do it is create two projects within the solution, with both projects referring to the same source files. Then, in x64 builds, set one project to build 64-bit and the other 32-bit. (In x86 builds, set one as 32-bit and turn off the other.)
We've been using this for a while and it works fine.
Of course, you have to be careful that any changes you make to one are also made to its copy. i.e. if you add/remove a file or change its build setting, you have to do it in two places. Source-code changes still only need to be done once, because there's still only one copy of each source file.
And, of course, you may decide that doing this is more complex/risky than switching away from using the IDE. In our case it's worked really well, though.
You are not going to be able to do this with the UI of Visual Studio. For this you will need to hack the MSBuild files.
Try this link from MSDN for MSBuild Overview
I would suggest to create a dummy C++ Makefile project and then invoke MSBuild twice from it:
msbuild myproj.sln /p:Configuration="Debug|Win32"
msbuild myproj.sln /p:Configuration="Debug|x64"
Perhaps I've missed the point of this discussion.
Using Visual Studio, go to menu Build → Configuration Manager. In the Active Solution Platform drop down, select "New...", and a New Solution Platform dialog appears. Select x64 and accept the default Copy From. Close the dialog and the Configuration Manager.
Now open menu Build → Batch Build. Check those configurations you want to build and build them. You will find the x64 build executables separate from the Win32 executable files.
You can verify that these are what was intended by right clicking on the executable files, selecting Properties, and select the Compatibility tab. In the dropdown window you can check to see what operating systems the executable file can be run in.
Obviously, there may be some other tweaking you might have to do to get all the output files in their proper places, but this method seem somewhat simpler than fooling with build than those described above.
I ran into this problem with a project running in Visual Studio 2008 (on Windows XP) (32-bit) and also Visual Studio 2010 (on Windows 7) (64-bit).
The solution I used was to use the $(PROGRAMFILES) variable. It resolved correctly on both machines.

Resources