.NET 6 outputs far larger executable than CSC - c#

When I compile a executable with csc, it takes 4KB. On the other hand, with publish option in visual studio 2022 I get 9.91 MB. Both files can be run on a pc independetly. "Release" version of file in visual studio is much smaller, however isn't standalone. How to get same file size with dotnet?
.pubxml:
<?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>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<PublishDir>bin\Release\net6.0\publish\win-x86\</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<TargetFramework>net6.0</TargetFramework>
<SelfContained>true</SelfContained>
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
<PublishSingleFile>True</PublishSingleFile>
<PublishReadyToRun>False</PublishReadyToRun>
<PublishTrimmed>True</PublishTrimmed>
</PropertyGroup>
</Project>

Related

Producing Executable for a C# project in linux

I want to know how to produce a c# executable file on Linux as when I build all I get is a DLL file in the bin folder that I don't know how to execute.
Note: I'm using vscode as my code editor and Manjaro is my Linux distro.
Did you try command?
dotnet app_name.dll
I guess a Publish Profile is What You are looking for.
Add a file named MyPublishProfile.pubxml to your project with this content:
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
<PropertyGroup>
<DeleteExistingFiles>false</DeleteExistingFiles>
<ExcludeApp_Data>false</ExcludeApp_Data>
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<PublishProvider>FileSystem</PublishProvider>
<PublishUrl>bin\Release\net6.0\publish\</PublishUrl>
<WebPublishMethod>FileSystem</WebPublishMethod>
<_TargetId>Folder</_TargetId>
<SiteUrlToLaunchAfterPublish />
<TargetFramework>net6.0</TargetFramework>
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
<ProjectGuid>c21872b8-42b3-418a-ab47-103a60e7cd6c</ProjectGuid>
<SelfContained>true</SelfContained>
</PropertyGroup>
</Project>
save it and edit it (follow the provided links). then you can run
dotnet publish -p:publishProfile=MyPublishProfile
then you should have your excecutable. maybe you have to chmode it. you can read more here

How to build a single .exe file, with static .NET runtime, from a C# WPF project?

Visual Studio 2022
C# WPF Project
I want to distribute a single .exe file, without requiring the target computer to install .NET 6.0 runtimes.
I can only find solutions for C/C++ code generation in the project's property window, but what I see in VS 2022 is totally different and there's no settings for static linking.
How to Deploy a single-file .NET 6 WPF app:
Right-click on the WPF application project in the Solution Explorer and select Edit Project File
Add the following line to the <PropertyGroup> element in the .csproj file:
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
Right-click on the project in the Solution Explorer and select Publish
Set the Deployment mode to Self-contained under the Target Runtime settings
Select win-* as the Target runtime
Check the Produce single file option under File publish options
Click on Save and then on Publish
Copy the contents of the Target location to the target machine and run the app`
.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
<IncludeNativeLibrariesForSelfExtract >true</IncludeNativeLibrariesForSelfExtract>
</PropertyGroup>
</Project>
FolderProfile.pubxml:
<?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>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<PublishDir>bin\Release\net6.0-windows\publish\win-x64\</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<TargetFramework>net6.0-windows</TargetFramework>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<SelfContained>true</SelfContained>
<PublishSingleFile>True</PublishSingleFile>
<PublishReadyToRun>False</PublishReadyToRun>
</PropertyGroup>
</Project>

Do i need <ProjectGuid> and <ProjectTypeGuids> in the new 2017 cps based project files?

In the old format you'd see code like this:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<ProjectGuid>{AF007959-0830-4E90-9087-0B413BF83277}</ProjectGuid>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
...
I'm in the process of migrating to the new CPS based project files.
Should i keep these tags or can i safely remove them?
Do i need and in the new 2017 cps
based project files?
The new sdk format project does not need to define the property ProjectGuid and ProjectTypeGuids.
It actually automatically generated and retrieved ProjectGuidand ProjectTypeGuids by the new project format <Project Sdk="Microsoft.NET.Sdk"></Project>.
So you can just remove them and it is redundant to define them again.
The xxx.csproj file of the new sdk project format is like this:
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net461</TargetFramework>
</PropertyGroup>
</Project>

How to execute msbuild /t:updateuid for all projects in a solution?

is there an easy way to execute msbuild /t:updateuid <project file> for all projects in a solution?
I have a huge solution with more than 150 projects and want to set Uids to all *.xaml files in all projects in the solution. I don't want to add this line to every project, but execute it from one place. Thus I can easilly control the execution of the command.
For example during the development phase I would like to disable the command to make the build process faster and just before the test phase i would like to enable it from one place. Any suggestions are wellcomed.
Regards
I managed to solve my problem using the information on the this blog.
The idea is to inject a custom .targets file, which will be processed by msbuild for every project. Imagine we have the following solution structure:
SolutionFolder
MySolution.sln
after.MySolution.sln.targets
UpdateAutomationIds.targets
The after.MySolution.sln.targets file will be processed by the msbuild. It will inject our UpdateAutomationIds.targets file to be executed for every project in the solution. Just replace MySolution with the name of your solution.
after.MySolution.sln.targets
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<CustomAfterMicrosoftCommonTargets>$(MSBuildThisFileFullPath)</CustomAfterMicrosoftCommonTargets>
<SolutionPath>$(SolutionPath);CustomAfterMicrosoftCommonTargets=$(MSBuildThisFileDirectory)UpdateAutomationIds.targets</SolutionPath>
</PropertyGroup>
</Project>
UpdateAutomationIds.targets
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="UpdateAutomationIds" Condition="'$(MSBuildProjectExtension)'=='.csproj'" BeforeTargets="Build">
<Message Text="Updates automation ids. Project: $(MSBuildProjectFullPath)" Importance="high"/>
<Exec Command=""$(MSBuildToolsPath)\msbuild.exe" /t:updateuid "$(MSBuildProjectFullPath)""/>
<Exec Command=""$(MSBuildToolsPath)\msbuild.exe" /t:checkuid "$(MSBuildProjectFullPath)""/>
</Target>
</Project>

adding extra files to published MVC API project

I am trying to add an extra XML file to a publishing process. I have a MVC API project which also has another project (V1.0) for controllers. We are using the self documenting help functionality which creates the .XML files for each project. When building on the local machine it all works but when publishing (with wizard) it will not include this file.
I have been trying to update the publish profile (.pubxml) file as described here:
http://www.asp.net/mvc/tutorials/deployment/visual-studio-web-deployment/deploying-extra-files
but without success. I can see the following is happening:
I do a clean to ensure nothing hanging around.
I publish with wizard
I can see in apiproject\bin\ there are all the files including the apiprojectv1 xml and dll files
I can see in apiproject\obj\x86\Release\AspnetCompileMerge\Source\bin it has the apiprojectv1 dll but not the xml file
I can see the same as above in apiprojet\obj\x86\Release\AspnetCompileMerge\TempBuildDir\bin
I can see the same as above in apiproject\obj\x86\Release\Package\PackageTmp\bin
I am not sure why the file is not being copied across. This is my full pubxml file:
<?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>
<SiteUrlToLaunchAfterPublish />
<publishUrl>\\myserver\wwwroot\apiproject</publishUrl>
<DeleteExistingFiles>False</DeleteExistingFiles>
</PropertyGroup>
<Target Name="CustomCollectFiles">
<ItemGroup>
<_CustomFiles Include="..\bin\apiprojectv1.XML" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>%(RecursiveDir)%(Filename)%(Extension) </DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
</Project>
EDIT
I had forgot one major part, to put the below at the bottom of the pubxml file:
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
</PropertyGroup>
I do not get the file, but now get an error regarding the file not being found, (which I can now debug).
I had missed two things:
The second property group to actually tell it to perform the action.
The path was not right, had to use project directory path
Now looks like this and works:
<?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>
<SiteUrlToLaunchAfterPublish />
<publishUrl>\\myserver\wwwroot\apiproject</publishUrl>
<DeleteExistingFiles>False</DeleteExistingFiles>
</PropertyGroup>
<Target Name="CustomCollectFiles">
<ItemGroup>
<_CustomFiles Include="$(MSBuildProjectDirectory)\bin\apiprojectv1.XML" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>bin\%(RecursiveDir)%(Filename)%(Extension) </DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
</PropertyGroup>
</Project>

Categories