How to set OS condition for TargetFramework in MSBuild - xamarin.forms

I have few projects in my solution - few for mobile (Xamarin.Forms) and one xUnit. xUnit is build with .NET5 and references mobile project.
There are 2 pipelines on Azure DevOps to build mobile app. One is for Android and runs on Windows, another for iOS and runs on OSX.
xUnit project build started to fail after I added new NuGet to mobile project (Rg.Plugins.Popup).
Initially, setting the TargetFramework for xUnit project looked like this
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
That setup worked on OSX, but did not work on Windows with error message Error NETSDK1136: The target platform must be set to Windows (usually by including '-windows' in the TargetFramework property) when using Windows Forms or WPF, or referencing projects or packages that do so.
Changing it to
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
fixes Windows problem, but it starts failing on OSX (with same error message, which is weird, as we are no longer on Windows).
I tried few other options, but could not make it to succeed on both machines.
<PropertyGroup>
<TargetFramework Condition=" '$(OS)' == 'Windows_NT' ">net5.0-windows</TargetFramework>
<TargetFramework Condition=" '$(OS)' != 'Windows_NT' ">net5.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<PropertyGroup>
<TargetFrameworks>net5.0;net5.0-windows</TargetFrameworks>
<IsPackable>false</IsPackable>
</PropertyGroup>
I also tried with Choose, When and Otherwise, but it looks like you cannot wrap TargetFramework into that at all.
Am I doing it completely wrong or it it just some coincidence that correct code does not work in my case?

Try to place Condition inside PropertyGroup not TargetFramework .
Try the code below
<PropertyGroup Condition=" '$(OS)' != 'Windows_NT' ">
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition=" '$(OS)' == 'Windows_NT' ">
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
</PropertyGroup>

Related

how to convert framework 4.6.1 class library to core 3.1?

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$...." Condition="Exists('$.....')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{DE7456FD-4BE4-4C9A-BA8C-9148EA6793A0}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Lynx.Core</RootNamespace>
<AssemblyName>Lynx.Core</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
i used
<TargetFramework>netcoreapp3.1</TargetFramework>
and also used
<TargetFrameworks>netstandard1.6;dnxcore50</TargetFrameworks>
<DefineConstants>$(DefineConstants);CORE</DefineConstants>
<NetStandardImplicitPackageVersion>1.6.0</NetStandardImplicitPackageVersion>
<TargetFrameworkIdentifiers>.NEtStandard;.NETCoreApp</TargetFrameworkIdentifiers>
<TargetFrameworkVersion>v1.6</TargetFrameworkVersion>
this lines of code but it didn't worked. because whenever i build this code my system were hanging can anyone help me to solve this problem
The .NET Core 2.0 and later (including the latest version of .NET Core 3.1 and the upcoming .NET 5.0) has the project model of SDK project. These csproj/vbproj/fsproj files (depends on what language you used) always have this XML on its first line:
<Project Sdk="Microsoft.NET.Sdk">
These are the other notable differences in SDK project:
The SDK project doesn't have project GUID embedded, like the one you have: <ProjectGuid>...</ProjectGuid>. Also other XML elements are ignored, such as AppDesignerFolder, RootNamespace.
The SDK project cannot use TargetFrameworkVersion because this element is intended to be used by .NET Framework projects created within Visual Studio, this is whythe value in this element always refer to .NET Framework version.
The SDK project doesn't require separate debug/release condition by default.
There is no tool to automate/help converting non-SDK project to SDK project. Therefore manual editing is required.
The detailed step-by-step instruction is available on this doc link:
https://learn.microsoft.com/en-us/dotnet/core/migration/#migration-from-earlier-net-core-csproj-formats-to-rtm-csproj

How to show message box on .net core Console application?

I'm developing .net core console application. I want to alert to user when want to exit application. Like below;
MessageBox.Show("Contiue or not", "Question", MessageBoxButtons.YesNo, MessageBoxIcon.None, MessageBoxDefaultButton.Button1) == DialogResult.No)
Application.Exit();
But I can't add System.Windows.Forms referance to the my project. I'm getting this error.
Error CS0234 The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?)
Is that possible to show Message Box on .net core Console Application?
In order to use Windows Forms you need to modify .csproj:
set UseWindowsForms to true
append -windows to TargetFramework (e.g. net6.0-windows)
ConsoleApp.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
</Project>
Program.cs:
System.Console.WriteLine("Hello, Console!");
System.Windows.Forms.MessageBox.Show("Hello, Popup!");
Result:
Notes:
I checked this solution on .NET Core 3.1, .NET 5 and .NET 6 on Windows x64.
If you don't want console window to be shown, set OutputType in .csproj to WinExe instead of Exe.
Windows Forms works only on Windows, so as this solution.
On .NET Core 3.1 there is no requirement to change target framework to Windows, however it is still impossible to publish executable for Linux OS.
If you need cross-platform solution that shows popups on Windows and only use console on Linux – you can create custom build configuration and use preprocessor directives as in the example below.
Cross-platform ConsoleApp.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<Configurations>Debug;Release;WindowsDebug;WindowsRelease</Configurations>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'WindowsDebug' Or '$(Configuration)' == 'WindowsRelease'">
<DefineConstants>WindowsRuntime</DefineConstants>
<TargetFramework>net6.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
</Project>
Cross-platform Program.cs
System.Console.WriteLine("Hello, Console!");
#if WindowsRuntime
System.Windows.Forms.MessageBox.Show("Hello, Popup!");
#endif
Some console apps need this line added to the project as well...
<DisableWinExeOutputInference>true</DisableWinExeOutputInference>
Adding this to the example in Daniil's post would give you this...
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<!--Insert DisableWinExeOutputInference here -->
<DisableWinExeOutputInference>true</DisableWinExeOutputInference>
</PropertyGroup>
</Project>

How to specify ASP.NET Core target framework imports in .csproj file (instead of project.json)?

I'm building an ASP.NET Core app, and am trying to install the Azure Storage package.
From the Azure Storage github page, it says I need to place the following in my project.json file - but since this is using the latest ASP.NET Core version, we don't have a project.json file, just a .csproj file.
"imports": [
"dnxcore50",
"portable-net451+win8"
]
Is there a way to do this in .csproj file? I assume the place might be somewhere around this:
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
<PreserveCompilationContext>true</PreserveCompilationContext>
</PropertyGroup>
Thanks very much!
After migrating one of my projects to the new model, this is what it generated:
<PropertyGroup>
<TargetFramework>netcoreapp1.6</TargetFramework>
<PreserveCompilationContext>true</PreserveCompilationContext>
<AssemblyName>TestApp</AssemblyName>
<OutputType>Exe</OutputType>
<PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.6' ">$(PackageTargetFallback);dotnet5.6;portable-net45+win8</PackageTargetFallback>
</PropertyGroup>
Try adding dnxcore50 and portable-net451+win8 in a similar fashion, something like this:
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
<PreserveCompilationContext>true</PreserveCompilationContext>
<PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.1' ">$(PackageTargetFallback);dnxcore50;portable-net451+win8</PackageTargetFallback>
</PropertyGroup>

How to use Sqlite in WP8 project wihout referencing the Sqlite extension

I have a problem with Sqlite in my Windows Phone 8 app. I followed the ususal guides, where you have to add sqlite-net and sqlite-net-wp8 NuGet package, then add compilation parameter USE_WP8_NATIVE_SQLITE and then add link to Sqlite for Windows Phone Visual Studio Extension.
I have a problem with the last step because it requires specific Visual Studio extension to be installed and therefore it's not compatible with our requirement to have all source files and libraries in Git repository, without need to install any additional plugins when running Continuous integration or setting a machine for a new developer.
When I tried to add reference to the sqlite3.dll located in
C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v8.0\ExtensionSDKs\SQLite.WP80\3.8.7.4 \Redist\Retail\x86\sqlite3.dll
I got error "A reference to a higher version or incompatible assembly cannot be added to the project."
Is there a way how to overcome this problem and have all necessary Sqlite libraries in my Git repository, without referencing VS Extensions that need to be installed?
I know this is old, but I recently did something similar. Here is the approach I took:
Install the extension, and copy the files from C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v8.0\ExtensionSDKs\SQLite.WP80 and copy to your $(SolutionDir)packages directory
Edit the $(SolutionDir)packages\DesignTime\CommonConfiguration\neutral\SQLite.WP80.props file that is included in the package and change the path of IncludePath and LibraryPath:
<IncludePath>$(SolutionDir)packages\SQLite.WP80\latest\DesignTime\CommonConfiguration\Neutral;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)packages\SQLite.WP80\latest\DesignTime\$(PackageConfiguration)\$(PlatformTarget);$(LibraryPath)</LibraryPath>
Modify the SQLite.vcxproj file
A. Add Property groups to add location of sqlite3.dll
`
<PropertyGroup>
<SQLiteBase>$(SolutionDir)packages\SQLite.WP80\latest\Redist</SQLiteBase>
<SQLiteWin32Debug>$(SQLiteBase)\Debug\x86</SQLiteWin32Debug>
<SQLiteWin32Release>$(SQLiteBase)\Retail\x86</SQLiteWin32Release>
<SQLiteArmDebug>$(SQLiteBase)\Debug\ARM</SQLiteArmDebug>
<SQLiteArmRelease>$(SQLiteBase)\Retail\ARM</SQLiteArmRelease>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<SQLiteBinPath>$(SQLiteWin32Debug)</SQLiteBinPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<SQLiteBinPath>$(SQLiteWin32Release)</SQLiteBinPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|Win32' ">
<SQLiteBinPath>$(SQLiteWin32Debug)</SQLiteBinPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|Win32' ">
<SQLiteBinPath>$(SQLiteWin32Release)</SQLiteBinPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|ARM' ">
<SQLiteBinPath>$(SQLiteArmDebug)</SQLiteBinPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|ARM' ">
<SQLiteBinPath>$(SQLiteArmRelease)</SQLiteBinPath>
</PropertyGroup>
`
B. Change the ImportGroup for the props file to reference the path in solution:
<ImportGroup Label="PropertySheets">
<Import Project="$(SolutionDir)packages\SQLite.WP80\version\DesignTime\CommonConfiguration\Neutral\SQLite.WP80.props" />
</ImportGroup>
C. Change the ItemGroup where the it references the SDK and change it to add the sqlite3.dll
<ItemGroup>
<CustomBuild Include="$(SQLiteBinPath)\sqlite3.dll">
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
</CustomBuild>
</ItemGroup>
This copying the SQLite SDK files "locally" with this extension https://visualstudiogallery.msdn.microsoft.com/1f027247-1e01-4ec6-8f5b-70dabb375217.

How can I mimic the VS 2012 "publish webSite" from command line (or in tfs automated build)?

I have a WebSite which is locally in a folder on my computer. It doesn't have a .csproj - just all the files in a folder. I want to do the publish website in the automated build which is basically as doing it in command line using msbuild.exe and\or msdeploy.exe and\or aspnet_compiler.exe and/or anything else.
If you want to create a project like so you can create an empty solution, add -> new website (select filesystem on the buttom in the combobox), add an empty class file, right click on the website line in the solution explorer, under the solution line, Publish website, there you need to create a new profile- really easy- basically choosing "file-system" and then publish.
I'm running on VS2012, update 4.
if you pass in an MSbuild argument of
/p:DeployOnBuild=true;PublishProfile=PROFILENAME
it should do the same as publishing from VS if your profile is set up correctly
EDIT
Sorry just had to run one of these through to see what happens
when you check in a Website to TFS it creates a websites folder.
you can then map your build to this folder.
instead of mapping the build to a sln file you can point to the publishproj file, this gets created when you create the publish profile. this tells the build what to do
in this i had set the publish location to be c:\publish and after the build i had the output in a folder called c:\publish.
the generated publishproj file looks like this
<?xml version="1.0" encoding="utf-8"?>
<!--
***********************************************************************************************
website.publishproj
WARNING: DO NOT MODIFY this file, it is used for the web publish process.
Copyright (C) Microsoft Corporation. All rights reserved.
***********************************************************************************************
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>10.0.30319</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{f17a9da4-9b68-41e4-ab73-5ac72898b384}</ProjectGuid>
<SourceWebPhysicalPath>$(MSBuildThisFileDirectory)</SourceWebPhysicalPath>
<SourceWebVirtualPath>/WebSite1</SourceWebVirtualPath>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<SourceWebProject>http://localhost:61874</SourceWebProject>
<SourceWebMetabasePath>/IISExpress/7.5/LM/W3SVC/15/ROOT</SourceWebMetabasePath>
</PropertyGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<!-- for VS2010 we need to use 10.5 but for VS2012+ we should use VisualStudioVersion -->
<WebPublishTargetsVersion Condition=" '$(WebPublishTargetsVersion)' =='' and '$(VisualStudioVersion)' == 10.0 ">10.5</WebPublishTargetsVersion>
<WebPublishTargetsVersion Condition=" '$(WebPublishTargetsVersion)'=='' ">$(VisualStudioVersion)</WebPublishTargetsVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(WebPublishTargetsVersion)</VSToolsPath>
<_WebPublishTargetsPath Condition=" '$(_WebPublishTargetsPath)'=='' ">$(VSToolsPath)</_WebPublishTargetsPath>
<AssemblyFileVersion Condition="'$(AssemblyFileVersion)' == ''">1.0.0.0</AssemblyFileVersion>
<AssemblyVersion Condition="'$(AssemblyVersion)' == ''">1.0.0.0</AssemblyVersion>
</PropertyGroup>
<ItemGroup>
<AssemblyAttributes Include="AssemblyFileVersion">
<Value>$(AssemblyFileVersion)</Value>
</AssemblyAttributes>
<AssemblyAttributes Include="AssemblyVersion">
<Value>$(AssemblyVersion)</Value>
</AssemblyAttributes>
</ItemGroup>
<Import Project="$(_WebPublishTargetsPath)\Web\Microsoft.WebSite.Publishing.targets" />
</Project>

Resources