MSBuild does not build the PDB files - asp.net

I have a solution converted from VS2010 to VS2012. In the Release build, I want it to produce PDB files and full debug symbols because I need to run remote debugging in a production environment.
So I set Debug Info to full for Release configuration. I also confirmed the followings are in the project manifest file:
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimized>true</Optimized>
But when I run MSBuild, the package it creates doesn't include the PDB files. However, if I use Visual Studio's Publish feature with Release configuration, I end up with PDB files on the target web server. What could be wrong with the Build command?
C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe "C:\MyWebApp.csproj"
/t:rebuild;package
/p:OutPath="C:\MyWebApp\obj"
/p:OutputPath="C:\MyWebApp\bin"
/p:Configuration=Release
/p:Platform=AnyCPU
I tried turning off the Optimized bit, but that didn't help.

Try adding
/p:DebugSymbols=true
/p:DebugType=full
If you are publishing a web application then you should also add:
/p:ExcludeGeneratedDebugSymbol=false

You can access this straight from the command line:
msbuild.exe "C:\\MyWebApp.csproj"
/t:rebuild;package
/p:OutPath="C:\\MyWebApp\\obj"
/p:OutputPath="C:\\MyWebApp\\bin"
/p:Configuration=Release
/p:Platform=AnyCPU
/p:DebugType=pdbonly

Related

AssemblyInfo ingrored when building from GitLab-Runner

On a Windows machine there is a GitLab-Runner run from a domain user with admin rights. When I log as this user and call dotnet build -c release to build an ASP.NET Core app, the dll has all the information from the AssemblyInfo.cs file. When I do the same as part of a CI job, the produced dll is missing all this information (for example the version number).
The AssemblyInfo.cs file is not part of the repository, instead, it is produced by a prebuild event (using gitWCRev.exe tool). However after running some tests I can see that the AssemblyInfo.cs is actually generated when the job is run by the runner.
Any help as to why the file is ignored and how to overcome this issue would be appreciated.
At first I thought that this might be related to Pre-build task of Visual Studio project fails in GitLab Runner issue, but I don't get any build errors.
On the same machine, I build a .Net Framework app which has the same AssemblyInfo setup, but is compiled using msbuild /property:Configuration=Release by the runner and the produced dll file has all the expected information.
It turns out the problem was partially related to the AssemblyInfo.cs file not being part of the repository.
SDK-style csproj normally don't list the files in the project, but figure them out based on the folder contents. When dotnet build was run, AssemblyInfo.cs wasn't present in the project directory (GitLab-Runner usually clears out files not present in the repository before starting a job/pipeline), so build tools had no idea they needed to load it. It made no difference that the file was being created by the build tools.
The solution proved to be creating an empty AssemblyInfo.cs file before running dotnet build. This way build tools knew they needed to compile it. Actual compilation still happened after prebuild events, so all the needed information was there.
I created the empty AssemblyInfo.cs file using PowerShell:
New-Item -Path "Properties/AssemblyInfo.cs" -ItemType File
Also, checking the build logs helped me finally figure it out. To get the build logs I've called build tools like this:
dotnet build -c release /flp:v=diag
The .Net Framework app didn't have this problem because it wasn't an SDK-style project. All the files needed for compilation were listed in the project file and build tools knew to load them, even if they were created during the prebuild event.

MSBuild publish dotnet core application

My setup is: I have a solution that had different dotnet4.6 applications (services) in it. Now we added a dotnet core project inside this solution. I can build and debug it, but this doesn't create an executable. In Visual Studio I can rightclick -> Publish... it. I created two profiles (x86 and x64) that should create nice binaries in /bin/Publish/x86 or /x64. In VS this works. The application is self-contained and works on different unprepared machines.
But now I Need to move that process to the buildserver. I messed around with dotnet publish but in the end i get stuck because other components of the solution are not clean dotnet core and so the build fails.
So I need to stick with MSBuild.
The current attempt is:
"C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\MSBuild.exe" NewProject\NewProject.csproj /p:DeployOnBuild=true /p:UsePublishProfile=true /p:PublishProfile=x64Profile.
This says it finished building successfully, but I don't see any results. Also it doesn't make any difference, if I remove all properties and just call msbuild and *.csproj. It just builds the new project in bin/Debug, as dll, not exe.
I also messed around with p:PublishProfile="NewProject\Properties\PublishProfiles\x64Profile.pubxml" and /p:PublishUrl="NewProject\bin\Publish\x64" but it doesn't change anything.
I read a few articles on SO, telling that VS doesn't just call msbuild with parameters but does internal API calls. Still, I need a solution. I need the build server to create an executable. Is there a way to trigger msbuild to create thath?
Oh man, I searched for 2-3 days now. And - as always on StackOverflow - shortly after asking I found a working answer myself.
tl;dr:
Project.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp2.1</TargetFrameworks>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RootNamespace>Company.Toolset.Exporter</RootNamespace>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
<RuntimeIdentifiers>win-x86;win-x64</RuntimeIdentifiers>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v15.0\WebApplications\Microsoft.WebApplication.targets" />
...
MSBuild command:
msbuild Project\Project.csproj -t:restore /t:Build;Publish /p:Configuration=Release /p:Platform=x86 /p:PublishProfile=x86Profile /p:OutputPath=bin/Publish/x86 (and the same for x64)
Explanation:
I think it was the dotnet build/publish command that wanted me to change TargetFrameworks to TargetFramework. But for MSBuild this is wrong. And dotnet wasn't working here, as the solution is mixing dotnet core and dotnet framework. So that had to be fixed.
The <RuntimeIdentifiers>win-x86;win-x64</RuntimeIdentifiers> was needed by the command. I added it to the *.csproj because I know that I build for windows only (at the moment) and that I need both versions.
I don't really know why I needed this line <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v15.0\WebApplications\Microsoft.WebApplication.targets" /> but without this publishing and using the PublishProfiles didn't work as expected.
Links that helped me to get here: (not sorted)
https://github.com/Microsoft/msbuild/issues/1901
https://github.com/aspnet/vsweb-publish/issues/22
How to Publish Web with msbuild?
ASP.NET Core Application (.NET Framework) for Windows x64 only error in project.assets.json
Configure MSBuild output path
I too had a nightmare with inconsistencies between builds from Visual Studio IDE and the dotnet publish command, that were only fixed by doing it using msbuild.exe instead. Also, using /p:PublishProfiles=theXMLthatVSgenerates.xml never worked, so I had to break out every option into the msbuild command line.
Here's what worked for me:
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\msbuild.exe" C:\Users\xxxx\Source\Repos\netcore-agent1\CoreAgent1\CoreAgent1.csproj /t:Restore;Rebuild;Publish /p:PublishSingleFile=True /p:SelfContained=True /p:PublishProtocol=FileSystem /p:Configuration=Release /p:Platform=x64 /p:TargetFrameworks=netcoreapp3.1 /p:PublishDir=bin\Release\netcoreapp3.1\publish\win-x64 /p:RuntimeIdentifier=win-x64 /p:PublishReadyToRun=False /p:PublishTrimmed=False

Compile a .NET Core application as an EXE file using Visual Studio 2017

I created a .NET Core application (v1.1) in Visual Studio 2017. When I compile it, I get a DLL file produced instead of the expected EXE file for the built project. I did check the csproj file and confirmed the output type is set to exe, but no dice.
Why is Visual Studio 2017 is still producing a DLL file?
I'm sure it's a quick setting somewhere that I forgot...
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Core.EF.SqlServer\Core.EF.SqlServer.csproj" />
</ItemGroup>
</Project>
Update 2019:
.NET Core 3.0+ projects will now include an executable for the platform you build on by default. This is just a shim executable and your main logic is still inside a .dll file.
But .NET Core 3.0 also introduced single-file deployments so deploying with
dotnet publish -r win-x64 -p:PublishSingleFile=True --self-contained false
will create a single .exe file containing all your dependencies. You can change --self-contained to true to also include the .NET Core Runtime as well so .NET Core does not need to be installed globally on the target machine.
Original
.NET Core applications are supposed to be .dllfiles. OutputType set to Exe in this case means "executable" and does everything necessary to ensure that the output is runnable (entry point from Main() method, .runtimeconfig.json file). The resulting DLL file is meant to be run using:
dotnet yourapp.dll
This DLL file works across all platforms that are supported by the .NET Core runtime (Windows, Linux, and macOS). This is called a "portable" or "framework dependent" deployment.
If you want really a .exe file, consider self-contained deployments. This will create an output that contains its own copy of the .NET Core runtime and an yourapp.exe file - but it also increases the size of the published application and it needs to be updated when new versions of the runtime are released.
Also, the resulting application only works on the operating system published for.
Refer to .NET Core application deployment for more details on the deployment options and how to set them up.
In Visual Studio 2017:
Right click on your project and select Publish (In Visual Studio 2019, click on menu Build → Publish <projectName>)
Select 'Folder' and create a new profile
In tab 'Publish', click 'Configure...'
Select Deployment Mode: Self-contained, Target Runtime: win-x86 (or win-x64)
Save
Publish
In the folder <Your project>\bin\Debug\netcoreapp2.1\win-x86\ you will see the EXE file:
Starting with .NET Core 2.2 you can build framework-dependent executables
Although building a self-contained deployment can be a good solution, it has its own drawbacks. (See R.Titov and Martin Ullrichs' answers on SCD-s.)
Fortunately, .NET Core 2.2 supports the building of so called framework-dependent executable-s, that are essentially a wrapper binary (.exe on Windows) around the standard dll-s.
This way you have all the advantages (and disadvantages) of the standard framework-dependent deployment (again, see Martin's answer), but you have a convenient way to launch it, without having to call it through the dotnet CLI.
You can publish your app as a Framework-Dependent Executable using the following syntax:
dotnet publish -c Release -r <RID> --self-contained false
Where RID is the usual runtime identifier, e.g. win-x64 or whatever platform you wish to build for (see the catalog here).
That's how you do a self-contained publish with command-line in any OS:
dotnet publish C:\src\App\App.csproj -c release -r win-x64 -o output-win-x64
Besides, you might want to get the output decreased from typical ~60 MB for a simple Hello World app to ~30 MB by using ILLink.
Also, you might want to go further and get a single .exe file of a size at around 5 MB and use ILCompiler. See this reply.
The other answers are good, but what I find sometimes convenient is:
Not have it self-contained because the target machine is likely to have .NET Core of the correct version installed. This cuts on number of the DLL files I need to ship.
Not have to specify dotnet on the command line
For this, a bat file wrapper can be used, similar to these lines:
#ECHO OFF
REM see http://joshua.poehls.me/powershell-batch-file-wrapper/
SET SCRIPTNAME=%~d0%~p0%~n0.dll
SET ARGS=%*
dotnet "%SCRIPTNAME%" %ARGS%
EXIT /B %ERRORLEVEL%
If your application ends up in yourapp.dll, name the bat file yourapp.bat and place it along side the DLL file. Now instead of dotnet yourapp.dll params you can call yourapp params.
Note that the context of this answer is in-house tooling, so all the developers using the utility will have a pretty standard development machine setup. If this is to be distributed to an external customer who is running who knows what on their boxes, the self-contained option is far superior.

Deploy from command line using MSBUILD and or MSDEPLOY (.NET 3.5)

I'm trying to get my website deployed by a Jenkins job.
I'm using the following command line sentence, with no success:
"C:\Windows\Microsoft.NET\Framework\v3.5\msbuild.exe" myproj.csproj /p:DeployOnBuild=true
I've also tried:
"C:\Windows\Microsoft.NET\Framework\v3.5\msbuild.exe" myproj.csproj /p:Configuration=Debug /p:OutputPath="obj\debug" /p:DeployIisAppPath="Default Web Site/demo"
None works although my project is compiled properly.
WHen I go to C:\inetpub\wwwroot nothing new is there. I want my site to start running and be accesible from my browser in Localhost.
You can use MSDeploy to deploy your web app using the following MSBuild arguments
/p:Configuration=release
/p:DeployOnBuild=True
/p:DeployTarget=MSDeployPublish
/p:MsDeployServiceUrl=https://targetServer:8172/MsDeploy.axd
/p:DeployIisAppPath=MySite
/p:AllowUntrustedCertificate=True
/p:Username=
/p:AuthType=NTLM
MSDeploy, however, has proven to be better solution for us. We use MSBuild to create an MSDeploy package and then we can deploy that package to many environments using MSDeploy.exe. Build once, deploy many. Here is an overview of WebDeploy which may be helpful:
http://dotnetcatch.com/2016/02/25/the-anatomy-of-a-webdeploy-package/
Make sure that you are adding the correct parameters after the MSBuild command, such as /p:DeployOnBuild=true /p:PublishProfile="XXXProfile", but the most important is to add the MSBuild.exe path to your %PATH% environment variable.
Having the MSBuild.exe path added to your %PATH% system environment variable the only thing you need to do is call:
msbuild myproject.csproj /p:DeployOnBuild=true /p:PublishProfile="MyProfile", where MyProfile is the generated publishing profile with Visual Studio and can be found under MyProject\Properties\PublishProfiles folder.

ASP.NET Website Project auto deploy with TFS 2013 build

I have a ASP.NET Webforms Website project(note this is NOT WebApplication project i.e. there is no .csproj).
I want to do a auto deploy, file system to our network share.
I created a profile and so there is website.publishproj file and profile xml.
I tried adding this in MSBuild arguments in Build Definition:
website.publishproj /p:DeployOnBuild=true
/p:PublishProfile=MyDevProfile /p:VisualStudioVersion=12.0
I get this error:
MSBUILD : error MSB1008: Only one project can be specified. Switch:
website.publishproj
Any idea what am I doing wrong? I believe this has something to do with Website project type.
This is something I read: How to use command line msbuild to deploy VS2012 Web Site project without precompiling it?
Here is the command:
C:\Program Files (x86)\MSBuild\12.0\bin\amd64\MSBuild.exe /nologo
/noconsolelogger
"E:\Builds\1\TP1\MyWebsite_Dev\src\Websites\MyWebsite\MyWebsite.sln"
/nr:False /fl
/flp:"logfile=E:\Builds\1\TP1\MyWebsite_Dev\src\Websites\MyWebsite\MyWebsite.log;encoding=Unicode;verbosity=normal"
/p:SkipInvalidConfigurations=true website.publishproj
/p:DeployOnBuild=true /p:PublishProfile=DropToDemoProfile
/p:VisualStudioVersion=12.0 /m
/p:OutDir="E:\Builds\1\TP1\MyWebsite_Dev\bin\"
/p:VCBuildOverride="E:\Builds\1\TP1\MyWebsite_Dev\src\Websites\MyWebsite\MyWebsite.sln.vsprops"
/dl:WorkflowCentralLogger,"C:\Program Files\Microsoft Team Foundation
Server
12.0\Tools\Microsoft.TeamFoundation.Build.Server.Logger.dll";"Verbosity=Normal;BuildUri=vstfs:///Build/Build/35;IgnoreDuplicateProjects=False;InformationNodeId=13;TargetsNotLogged=GetNativeManifest,GetCopyToOutputDirectoryItems,GetTargetPath;LogWarnings=True;TFSUrl=http://mytfs:8080/tfs/colletionname;"*WorkflowForwardingLogger,"C:\Program
Files\Microsoft Team Foundation Server
12.0\Tools\Microsoft.TeamFoundation.Build.Server.Logger.dll";"Verbosity=Normal;"
/p:BuildId="7d23530d-7349-406f-98b7-5d4f0b9f4101,vstfs:///Build/Build/35"
/p:BuildLabel="MyWebsite_Dev_20141122.13" /p:BuildTimestamp="Sun, 23
Nov 2014 01:22:05 GMT"
/p:BuildSourceVersion="LMyWebsite_Dev_20141122.13#$/TP1"
/p:BuildDefinition="MyWebsite_Dev"
You're trying to build the solution (MyWebsite.sln) and the project (website.publishproj) simultaneously as part of the same MSBuild command at least according to the arguments being passed.
You can run msbuild website.publishproj /pp:website.pp.publishproj to see what targets you can call in website.pp.publishproj or what properties to override.
You can run set MSBUILDEMITSOLUTION=true && msbuild MyWebsite.sln to see what targets you can call in MyWebsite.sln.metaproj and MyWebsite.metaproj or what properties to override.
Your DeployOnBuild command is fine and should work, I'm guessing your TFS build config is pointing to the .sln and passing website.publishproj as an argument rather than the primary target of the build, so either repoint it to build the .publishproj directly or... well, there doesn't seem to be any alternative, you can try adding a new configuration and editing the .sln with new AspNetConfiguration and MyDevProfile.AspNetCompiler.TargetPath but then you're just asking for trouble.
You need to upgrade your Web Site to a Web Application in order for any of this to be automatic.
Its a fairly simple procedure and even on sites with thousands of pages I have completed the migration in only a few days of one persons time without impacting other devs.
Web Site functionality has been feature complete for over 10 years. While it still existing in the product for back-compat I would not recommend using it.

Resources