F# "Visual Studio Code" XmlProvider not defined - f#

Compile error:
FSharp.Data.XmlProvider not defined
Windows 10
Visual Studio Code 1.19 64bit
F# 4.0
f# console app targeting framework .netcoreapp2.0
I get an error when trying to use the XmlProvider. Documentation indicates FSharp.Core.dll should support it. Build log indicates fsharp.core.dll being used
is C:\Users\KAUBUCHON.nuget\packages\fsharp.core\4.2.3\lib\netstandard1.6\FSharp.Core.dll
instead of C:\Program Files (x86)\Microsoft SDKs\F#\4.1\Framework\v4.0\FSharp.Core.dll.
My fsproj does not refernce the .nuget\packages... - any ideas? Did configure my environment incorrectly?
sample code below - type definition of XmlProvider fails
open System
open System.Xml.Linq
open FSharp.Data
module main =
[<Literal>]
let xmlsample = """
<Customers>
<Customer name="ACME">
<Order Number="123">
<OrderLine Item="widget"/>
</Order>
</Customer>
</Customers>"""
type inputXml = XmlProvider<xmlsample>
[<EntryPoint>]
let main argv =
printfn "Hello World from F#!"
0 // return an integer exit code

Follow this one: https://github.com/Microsoft/visualfsharp/issues/3303
1) Add fsc.props
<?xml version="1.0" encoding="utf-8"?>
<Project>
<!-- Type providers currently can't run inside the .NET Core 2.0 hosted compiler, see https://github.com/Microsoft/visualfsharp/pull/3658#issuecomment-334773415 -->
<PropertyGroup>
<IsWindows Condition="'$(OS)' == 'Windows_NT'">true</IsWindows>
<IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</IsOSX>
<IsLinux Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">true</IsLinux>
</PropertyGroup>
<PropertyGroup Condition="'$(IsWindows)' == 'true' AND Exists('C:\Program Files (x86)\Microsoft SDKs\F#\4.1\Framework\v4.0\fsc.exe')">
<FscToolPath>C:\Program Files (x86)\Microsoft SDKs\F#\4.1\Framework\v4.0</FscToolPath>
<FscToolExe>fsc.exe</FscToolExe>
</PropertyGroup>
<PropertyGroup Condition="'$(IsOSX)' == 'true' AND Exists('/Library/Frameworks/Mono.framework/Versions/Current/Commands/fsharpc')">
<FscToolPath>/Library/Frameworks/Mono.framework/Versions/Current/Commands</FscToolPath>
<FscToolExe>fsharpc</FscToolExe>
</PropertyGroup>
<PropertyGroup Condition="'$(IsLinux)' == 'true' AND Exists('/usr/bin/fsharpc')">
<FscToolPath>/usr/bin</FscToolPath>
<FscToolExe>fsharpc</FscToolExe>
</PropertyGroup>
</Project>
2) Add <Import Project="fsc.props" /> to your fsproj as subnode of the Project element:
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<Import Project="fsc.props" />
<ItemGroup>
<Compile Include="Program.fs" />
</ItemGroup>

Related

Publish Website Does not Use Transformed web.config

I created a solution containing a website (not WebApp) with VS Express 2013. I use a web.Release.config file for the publish process. That worked well with VS 2013.
Now that I changed to VS 2019 Community, web.Debug.config was used for the web.config transformation though the publish was done for "Release". I suppose that is because in the configuration manager only "Debug" is possible for any configuration.
In another thread I found that I had to change website.publishproj from Debug to Release:
<Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
Now, web.Release.config is used for the transformation:
"web.config" wurde mithilfe von "C:\Users\<project path>\Web.Release.config" in "C:\Users\<some temporary path>\obj\Release\TransformWebConfig\transformed\web.config" transformiert.
This file actually has the changes applied that are needed for Release.
However, in the destination directory web.config does not contain these changes. It seems to be the original web.config without transformation.
What must I do to make Publish copy the transformed web.config?
This is my .pubxml file:
<?xml version="1.0" encoding="utf-8"?>
<!--
Auto generated comment...
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<PublishProvider>FileSystem</PublishProvider>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<publishUrl>C:\Inetpub\vhosts\<website name>.com\httpdocs</publishUrl>
<DeleteExistingFiles>True</DeleteExistingFiles>
</PropertyGroup>
and here is website.publishproj:
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>10.0.30319</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{45ff7195-6038-4b17-91ce-611a467ac837}</ProjectGuid>
<SourceWebPhysicalPath>$(MSBuildThisFileDirectory)</SourceWebPhysicalPath>
<SourceWebVirtualPath>/(Source Path Name)</SourceWebVirtualPath>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<SourceWebProject>http://localhost:56406</SourceWebProject>
<SourceWebMetabasePath>/IISExpress/7.5/LM/W3SVC/2/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>
<ItemGroup>
<ProjectReference Include="..\Accessories\Lib\Runtime\BaseLib\BaseLib.csproj">
<Project>{8A827F3E-CA83-4765-988D-937B0B608201}</Project>
<Name>BaseLib</Name>
</ProjectReference>
<ProjectReference Include="..\Accessories\Lib\Runtime\Config\Config.csproj">
<Project>{1B78D777-B4F8-4CEA-9A4F-554807D1E5BF}</Project>
<Name>Config</Name>
</ProjectReference>
<ProjectReference Include="..\Accessories\Lib\Runtime\GardenLib\GardenLib.csproj">
<Project>{30B09928-B911-4803-982F-519C4CDB8860}</Project>
<Name>GardenLib</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(_WebPublishTargetsPath)\Web\Microsoft.WebSite.Publishing.targets" />
</Project>
After I got some more problems publishing my website, I switched back to VS2013 Express where my publish process works well as it did before.
Maybe it's a bug in Visual Studio?

Add .net-Core F# File to F# project in vscode

I am currently trying to add an F# file to an F# project in VSCode using .NET core. I have ionide installed and tried using the "Add Current File to Project" command, after creating a new file with the .fs extension, but this did not work.
Is there some setup for Ionide that I am missing? Or is there another tool I should be using?
Thanks!
To add the file to the project by hand you can:
1- create you file, myfile.fs
2- add the file to the myproject.fsproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>client_api</RootNamespace>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Complie Include="myfile.fs"/>
<Compile Include="Program.fs" />
</ItemGroup>
</Project>
Open the file namespace on the main project and run the project.
Suppose we have the following directory tree:
.
├── MyFSharpApp.fsproj
└── Program.fs
Add we want to add the file DB.fs to get the following tree:
.
├── DB.fs
├── MyFSharpApp.fsproj
└── Program.fs
To do that we need to perform the following steps:
Create the file DB.fs
module DB
type Repository(databaseUrl: string) =
let databaseUrl = databaseUrl
member this.xxx() = 3
Reference DB.fs in MyFSharpApp.fsproj. We need to reference DB.fs before Program.fs
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="DB.fs" />
<Compile Include="Program.fs" />
</ItemGroup>
</Project>
Use our new module in Program.fs
open System
[<EntryPoint>]
let main argv =
let repository = DB.Repository("someUrl")
printfn "A string: %i" (repository.xxx())
0 // return an integer exit code

Include Files to be deployed not in project through msdeploy / F# Fake script

So I have the following Fake script ...
// include Fake lib
#r #"packages\FAKE.4.29.2\tools\FakeLib.dll"
open Fake
RestorePackages()
// define directories
let binDir = "./ProjFileFolder/bin/"
let objDir = "./ProjFileFolder/obj/Debug/"
let buildConf = getBuildParamOrDefault "conf" "Debug"
let buildNumber = getBuildParamOrDefault "bn" "0"
let buildVersion = "1.0.0." + buildNumber
let publishProfile = getBuildParamOrDefault "pubprofile" ""
let publishPassword = getBuildParamOrDefault "pubpwd" ""
let setParamsWeb = [
"DebugSymbols", "True"
"Configuration", buildConf
"Platform", "Any CPU"
"PublishProfile", publishProfile
"DeployOnBuild", "true"
"Password", publishPassword
"AllowUntrustedCertificate", "true"
]
// Targets
Target "Clean" (fun _ ->
CleanDirs [binDir; objDir]
)
Target "Compile" (fun _ ->
!! #"**\*.csproj"
|> MSBuild binDir "Build" setParamsWeb
|> Log "AppBuild-Output: "
)
// Dependencies
"Clean"
==> "Compile"
// start build
RunTargetOrDefault "Compile"
I had some targets that I had created in the csproj file to include a generated /docs doxygen documentation folder. This worked when initially using my old msdeploy script, which was an msdeploy folder sync command. Here they are ...
<Target Name="CustomCollectFiles">
<ItemGroup>
<_CustomFiles Include=".\docs\**\*" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>docs\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
<Choose>
<When Condition="'$(Configuration)' == 'Debug'">
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
</PropertyGroup>
</When>
<When Condition="'$(Configuration)' == 'QA'">
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
</PropertyGroup>
</When>
</Choose>
How do I ensure that the Fake script does the same thing or that it executes those targets in the csproj file? It runs by passing the name of the azure publish profile in that you want to use to deploy which is in the project.
So in this case because I'm deploying to azure I was able to move the targets and property group to the publish profile instead of having them in the project file directly. So I ended up with the following in our publish profile.
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>MSDeploy</WebPublishMethod>
<ADUsesOwinOrOpenIdConnect>False</ADUsesOwinOrOpenIdConnect>
<PublishProvider>AzureWebSite</PublishProvider>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish>stuff</SiteUrlToLaunchAfterPublish>
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<MSDeployServiceURL>stuff</MSDeployServiceURL>
<DeployIisAppPath>more stuff</DeployIisAppPath>
<RemoteSitePhysicalPath />
<SkipExtraFilesOnServer>True</SkipExtraFilesOnServer>
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
<EnableMSDeployBackup>True</EnableMSDeployBackup>
<UserName>more stuff</UserName>
<_SavePWD>True</_SavePWD>
<_DestinationType>AzureWebSite</_DestinationType>
</PropertyGroup>
<Target Name="CustomCollectFiles" BeforeTargets="Compile">
<ItemGroup>
<_CustomFiles Include=".\docs\**\*" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>docs\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
</PropertyGroup>
<PropertyGroup>
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
</PropertyGroup>
</Project>
We import the publish profiles into the project so that the fake script just accepts the name of the publish profile and the publish password and then the doxygen documentation which I am trying to include and which is created upon pre/post build event is included automatically. I have added this to our dev / qa publish profiles but not to our production publish profile because we don't want this deployed to prod. But it is nice to have automatically deployed and available in our dev / qa environments for anyone to access. I have included the "docs" folder in the project. Not sure if that will have any impact upon how it works.
I followed this tutorial ... https://www.asp.net/mvc/overview/deployment/visual-studio-web-deployment/deploying-extra-files . Which I suppose is an extension of this tutorial ... http://sedodream.com/2010/05/01/WebDeploymentToolMSDeployBuildPackageIncludingExtraFilesOrExcludingSpecificFiles.aspx

Deploying native libraries with TFS deploy agent

I'm using libgit2sharp in my project which uses Git2 library to work. Now, the last version used project properties files instead of custom build action. While this work fine when building or using the Publish action in Visual Studio 2013, it won't work at all using TFS build server.
Here are the imports instruction in the csproj file.
<Import Project="..\packages\LibGit2Sharp.0.20.0.0\build\net40\LibGit2Sharp.props" Condition="Exists('..\packages\LibGit2Sharp.0.20.0.0\build\net40\LibGit2Sharp.props')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\LibGit2Sharp.0.20.0.0\build\net40\LibGit2Sharp.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\LibGit2Sharp.0.20.0.0\build\net40\LibGit2Sharp.props'))" />
</Target>
And here is the props file in question:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)\..\..\lib\net40\NativeBinaries\amd64\git2-3f8d005.dll">
<Link>NativeBinaries\amd64\git2-3f8d005.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)\..\..\lib\net40\NativeBinaries\amd64\git2-3f8d005.pdb">
<Link>NativeBinaries\amd64\git2-3f8d005.pdb</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)\..\..\lib\net40\NativeBinaries\x86\git2-3f8d005.dll">
<Link>NativeBinaries\x86\git2-3f8d005.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)\..\..\lib\net40\NativeBinaries\x86\git2-3f8d005.pdb">
<Link>NativeBinaries\x86\git2-3f8d005.pdb</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
So, again, publishing or building the project with Visual Studio will copy the NativeBinaries folder to the bin folder which is perfectly fine. But, using a TFS build deployment setup, the folder is never transfered over the server using the RemoteAgent.
MSBuild arguments:
/p:DeployTarget=MsDeployPublish /p:Configuration=MEP-DEV /p:DeployOnBuild=True /p:CreatePackageOnPublish=False /p:MsDeployPublishMethod=RemoteAgent /p:AllowUntrustedCertificate=True
In the build log file, I can see that the Libgit2sharp NuGet package is being installed, but the libraries are not mentioned anywhere as if they are just ignored by the deployment process.

VCTargetsPath is wrong when building with MSBuild on build server

In my C++ project, Test.wcxproj, I have the following configurations defined:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
Then I have the problematic import of the default C++ properties:
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
When my build server builds my MSBuild project file (configuration is Release and platform is Any CPU), I get this error:
error MSB4019: The imported project "C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Microsoft.Cpp.Default.props" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.
The relevant parts of my MSBuild project file look like this:
<ItemGroup>
<ProjectFiles Include="$(MSBuildProjectDirectory)\**\*.csproj" />
<ProjectFiles Include="$(MSBuildProjectDirectory)\**\*.vcxproj" />
</ItemGroup>
<PropertyGroup>
<Configuration>Release</Configuration>
<Platform>x64</Platform>
<OutputFolder>$(MSBuildProjectDirectory)\BuildOutput\$(Configuration)</OutputFolder>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">$(MSBuildProjectDirectory)</SolutionDir>
</PropertyGroup>
...
<Target Name="Compile">
<MSBuild Projects="#(ProjectFiles)" Targets="Build" Properties="Configuration=$(Configuration);Platform=$(Platform);OutputPath=$(OutputFolder)\$(MSBuildProjectName);SolutionDir=$(SolutionDir)\" />
</Target>
The problem
In my MSBuild project file, I am using ToolsVersion="12.0". Visual Studio 2013 is indeed installed, so I don't understand why it chooses to use v4.0\v110. Are my project configurations for some reason skipped by MSBuild? I guess I could somehow override this folder using the /p switch, but I want my .proj file to be self-contained.
Try to set up environment variable
VisualStudioVersion=12.0
or pass it explicitly as property to msbuild on commandline
msbuild.exe <project or solution to build> /p:VisualStudioVersion=12.0
I think it is because Microsoft tries to keep compatibility with older Visual Studios.
see Visual Studio project compatibility and VisualStudioVersion
In my case, my build definition was configured to build my .sln file instead of my .proj file. I remember configuring it to build the MSBuild project, but somehow it seems to have reverted to the Solution.
Anyway, I found two solutions to the problem:
Make sure to build the .proj file (where the tools version is indeed set to 12.0).
Explicitly set the VCTargetsPath.

Resources