C# .NET standard 1.6 with excessive dependencies in published application - c#

I am trying out Visual Studio 2017 and .NET Core in what is my first attempt at C#/.NET in a few years (returning from Golang). I tried to create a small hello world style networking application that just listens and echos the input from tcp clients:
using System;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Text;
namespace TaskSockets
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
TcpListener server = new TcpListener(IPAddress.Any, 5555);
server.Start();
while (true)
{
TcpClient newClient = server.AcceptTcpClientAsync().Result;
Task.Run(async () => {
StreamWriter sWriter = new StreamWriter(newClient.GetStream(), Encoding.ASCII);
StreamReader sReader = new StreamReader(newClient.GetStream(), Encoding.ASCII);
Boolean bClientConnected = true;
String sData = null;
while (bClientConnected)
{
sData = await sReader.ReadLineAsync();
Console.WriteLine("Client: " + sData);
}
});
}
}
}
}
My project/build config looks like the following:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netstandard1.6</TargetFramework>
<RuntimeIdentifiers>win7-x64</RuntimeIdentifiers>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NETCore.Runtime.CoreCLR" Version="1.1.1" />
<PackageReference Include="Microsoft.NETCore.DotNetHostPolicy" Version="1.1.0" />
</ItemGroup>
</Project>
After publishing the application (dotnet publish) I get a folder with the executable I need. The problem I encounter, however, is that the folder contains 205 files (mostly .NET related DLL files) and is more than 30 MB in size. This includes dll files with reference to .NET libraries I don't even use such as System.Xml and Linq.
Is there any way to reduce the number of files and size of the published application so that just what I need is included?
UPDATE:
Tried to re-create the project from scratch using the dotnet tool rather than visual studio:
dotnet new console --language C# --name Socket --output Socket
--framework netcoreapp1.0
This created this project (which for some reason compiles to a dll despite the exe output type and console application target):
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.0</TargetFramework>
</PropertyGroup>
</Project>
Then manually modify the csproj file so it looks like this:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.0</TargetFramework>
<RuntimeIdentifiers>win7-x64</RuntimeIdentifiers>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NETCore.Runtime.CoreCLR" Version="1.0.6" />
</ItemGroup>
</Project>
Now publish with:
dotnet publish --runtime win7-x64 --configuration Release
And go to:
./bin/Release/netcoreapp1.0/win7-x64
Now suddenly there is a working exe-file and just a few DLL files that is approximately 1 MB in size. By deleting the subfolder called "publish" I now have something that works without most of the bloat. No idea why this worked and if its considered expected behavior. No idea what the publish folder is for either or whether or not its needed for deployment on a computer without .NET installed. Microsoft have some work to do on its documentation.

Have a look at https://learn.microsoft.com/en-us/dotnet/articles/core/deploying/index
In the 1st case, your publish command generates output for a Framework-dependent deployment that is relying on the presence of the .NET Core framework on the target machine. Your code (in the form of dll(s)) will be executed by the runtime.
In the 2nd case, when you specify the target runtime using the --runtime option, publish generates output for a Self-contained deployment in which the used version of the .NET Core framework is included. There's a way to reduce the total size of the output as described in the above mention article in the Deploying a self-contained deployment with a smaller footprintsection.
As for why <OutputType>Exe</OutputType> didn't generate a exe-file, check out https://learn.microsoft.com/en-us/dotnet/articles/core/tools/dotnet-build
It basically says the generated
binaries include the project's code in Intermediate Language (IL)
files with a .dll extension
and that the difference between specifying and not specifying <OutputType>Exe</OutputType>
is that the IL DLL for a library doesn't contain entry points and
can't be executed.

Related

Powershell package missing/not working on release

I have a console application project where i'm using the powershell SDK, it works perfectly fine in debug but on release, everything except powershell works.
The only settings i've found where it works is when releasing the project as framework dependent and portable. Or at least it works on my pc, on other computers it says the dotnet runtime is missing, even when installed via the link provided.
Using self contained, .net6-windows and win-x86 doesn't work. Not quite sure what could be wrong? I've tried cleaning the project, the solution, restarting visual studio and my PC. Everything works as expected in debug but when I publish, powershell just doesn't work.
<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>dotnet-SocketService-04A4D71F-C305-4A5B-BD0B-529C28B25DAD</UserSecretsId>
<PlatformTarget>AnyCPU</PlatformTarget>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.0" />
<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.2.1" />
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.2" />
<PackageReference Include="System.Management" Version="6.0.0" />
<PackageReference Include="System.Management.Automation" Version="7.2.1" />
</ItemGroup>
<ItemGroup>
<Folder Include="Speedtest\" />
</ItemGroup>
<ItemGroup>
<None Update="Speedtest\speedtest.exe">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
EDIT:
I changed my powershell handler to use .EndInvoke(), now I finally get a proper error! I found an issue mentioning the error https://github.com/PowerShell/PowerShell/issues/7909 but installing Microsoft.Management.Infrastructure didn't resolve the issue, I installed version 2.0.0. If i try installing version 1 I get an error stating that the System.Management.Automation package requires a higher version (2.0.0)
public static string CMD(string script)
{
string errorMsg = "";
string output;
ps.AddScript(script);
//Make sure return values are outputted to the stream captured by C#
ps.AddCommand("Out-String");
PSDataCollection<PSObject> outputCollection = new PSDataCollection<PSObject>();
ps.Streams.Error.DataAdded += (object sender, DataAddedEventArgs e) =>
{ errorMsg = ((PSDataCollection<ErrorRecord>)sender)[e.Index].ToString(); };
IAsyncResult result = ps.BeginInvoke<PSObject, PSObject>(null, outputCollection);
ps.EndInvoke(result);
//while (!result.IsCompleted)
// Thread.Sleep(300);
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject outputItem in outputCollection)
{
stringBuilder.AppendLine(outputItem.BaseObject.ToString());
}
output = stringBuilder.ToString();
//Clears commands added to runspace
ps.Commands.Clear();
if (!string.IsNullOrEmpty(errorMsg))
return string.Empty;
return output.Trim();
}
Here is the error message
Unhandled exception. System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Management.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. Den angivne fil blev ikke fundet.
File name: 'Microsoft.Management.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
at System.Management.Automation.Runspaces.AsyncResult.EndInvoke()
at System.Management.Automation.PowerShell.EndInvoke(IAsyncResult asyncResult)
at SocketService.PowerShellHandler.CMD(String script) in C:\Users\Blue\source\repos\SocketClientProject\Clientside\Handlers\PowershellHandler.cs:line 35
at SocketService.Classes.SystemInfo..ctor() in C:\Users\Blue\source\repos\SocketClientProject\Clientside\Classes\SystemInfo.cs:line 21
at SocketService.CommandHandler.Initialize() in C:\Users\Blue\source\repos\SocketClientProject\Clientside\Handlers\CommandHandler.cs:line 31
at SocketService.SocketService..ctor() in C:\Users\Blue\source\repos\SocketClientProject\Clientside\SocketService.cs:line 27
at SocketService.WindowsBackgroundService.StartAsync(CancellationToken cancellationToken) in C:\Users\Blue\source\repos\SocketClientProject\Clientside\WindowsBackgroundService.cs:line 17
at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
at Program.<Main>$(String[] args) in C:\Users\Blue\source\repos\SocketClientProject\Clientside\Program.cs:line 14
at Program.<Main>(String[] args)
[process exited with code 3762504530]
Line 14 is me calling PowerShell.Create();
What ended up solving my issue was this answer: Dotnet publish not publishing DLL to publish directory
I changed the target runtime to win10-x86 and that worked!
<TargetFramework>net6.0-windows</TargetFramework>
<RuntimeIdentifier>win10-x86</RuntimeIdentifier>
Without showing actual code and giving a more descriptive detailing about what's going on aside from "it doesn't work" it's difficult to say exactly what is occurring here but I'll do my best.
Thankfully, according to Microsoft's documentation you most certainly can run the Powershell SDK in a self-contained .Net application.
A self-contained .NET application can use Microsoft.PowerShell.SDK to run arbitrary PowerShell functionality without depending on any external PowerShell installations or libraries.
This leads me to believe that you may not be having an issue with the SDK itself but rather with the compiler.
Single-File deployments
I noticed in your screenshot that you are attempting to perform a single-file deployment. You could potentially be having a few issues here. One is to ensure that you're not using an incompatible API. If you are calling any of these within your application, that could be a factor:
Assembly.CodeBase
Assembly.EscapedCodeBase
Assembly.GetFile
Assembly.GetFiles
Assembly.Location
AssemblyName.CodeBase
AssemblyName.EscapedCodeBase
Module.FullyQualifiedName
Module.Name
As none of these are compatible with single-file deployments.
Trimming
Another issue you may be experiencing is referred to as trimming. This is where the compiler will 'trim' unused assemblies from the project at compile time and tends to happen on release runs. While I believe this is off by default you can add the following to your .csproj file to ensure that trimming is disabled:
<PropertyGroup>
<PublishTrimmed>false</PublishTrimmed>
</PropertyGroup>
Optimizing
The JIT compiler tends to try to optimize code on release builds. When we run an application in debug mode the application is optimized for debugging the code. It tries to leave everything almost exactly as you wrote it with maybe some minor differences. When an application is run in release mode the actual code that is being run can be drastically different while maintianing the same logic. This is usually to try and make the final assembly as small and fast as possible. You can disable this optimization by the following steps:
Right click on project
Click "properties"
Go to "Build"
Under the section "general" deactivate "Optimize Code"
Other than the above mentioned possible causes I can't think of much more I can offer without seeing code, or error messages, or further details.

Why does Gembox spreadsheet crash when calling Excelfile.save: FileNotFoundException Could not load file or assembly System.Security.Permissions

I am using Gembox to open, modify and save a xlsx file. Calling Save on the Excelfile causes a System.IO.FileNotFoundException.
The problem happens with our company serial key and with the free key.
Sample Code
using GemBox.Spreadsheet;
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
var path = #"C:\code\GemboxTest\App.xlsx";
SpreadsheetInfo.SetLicense("FREE-LIMITED-KEY");
ExcelFile ef = ExcelFile.Load(path);
ExcelWorksheet ws = ef.Worksheets[0];
//ws.Columns[0].Cells[0].Value = 42;
ef.Save(path); // <--------------------------------- Crash!
}
}
}
Error message
Could not load file or assembly 'System.Security.Permissions, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'.
System.Security.Permissions, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
Stacktrace
at   .(Stream , Byte[] , Int32 , Int32 , String )
at   .(Stream )
at   .(Stream )
at   . ()
at   .(Stream )
at    .Dispose()
at   .   ​ (Boolean )
at   .Dispose()
at    .    ​ ()
at    .(Boolean )
at    .Dispose()
at GemBox.Spreadsheet.XlsxSaveOptions.(ExcelFile , Stream ,     )
at GemBox.Spreadsheet.XlsxSaveOptions.Save(ExcelFile excelFile, Stream stream, String path)
at GemBox.Spreadsheet.SaveOptions.(ExcelFile , String )
at GemBox.Spreadsheet.ExcelFile.Save(String path, SaveOptions options)
at GemBox.Spreadsheet.ExcelFile.Save(String path)
at ConsoleApp.Program.Main(String[] args) in C:\code\GemboxTest\ConsoleApp\Program.cs:line 14
Versions
.NET Core 3.1 (also fails with 3.0)
GemBox.Spreadsheet Version=45.0.1131
Visual Studio 2019 (VisualStudioVersion = 16.0.29905.134)
Windows 10 pro 64bit
Sample csproj file
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="GemBox.Spreadsheet" Version="45.0.1131" />
</ItemGroup>
</Project>
Here the reply from Gembox support
Try adding "System.Security.Permissions" package reference to your ".csproj" file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="GemBox.Spreadsheet" Version="45.0.1131" />
<PackageReference Include="System.Security.Permissions" Version="4.7.0" />
</ItemGroup>
</Project>
As an FYI, I believe that this package is only required for the
Console application on Windows. It's not required when you're saving
XLSX files with ASP.NET Core application on Windows or when you're
saving XLSX files with any .NET Core application on Linux.
It appears the package has a dependency on an assembly that isn't referenced or included.
Typically, a package author would reference their dependencies in their nuspec file for the Targetframework (each TargetFramework).
You can work around it by adding the latest System.Security.Permissions nuget package as a dependency to your project.
Update 1: Additionally
Looking at their example project github repo, I do see references to netcoreapp3.1 there.
I tested both netcoreapp3.1 and netcoreapp3.0, received the dependency package issue with Save, worked around it by adding it as a dependency (as this answer suggests). Gembox.Spreadsheet.Example
The example and usage of netcoreapp2.2 had no issues with missing dependencies of the package when attempting a Save.
Update 2
Removed reference to observed issue with Load mentioned in Update 1. It appears to be unrelated and probably a runtime and\or IDE issue I was experiencing.
Also, this issue was only tested and observed with a console application on windows platform.

Creating new blazor application throws an error when run

I am following Get started with Blazor. I have created the application and attempt to run it as is i have made no changes.
There are three things in my event log.
The directory specified for caching compressed content C:\inetpub\temp\IIS Temporary Compressed Files\Clr4IntegratedAppPool is invalid. Static compression is being disabled.
Application 'MACHINE/WEBROOT/APPHOST/WEBAPPLICATION1' with physical root 'C:\Users\LindaL\source\repos\Daimto.RazorTest.Tools\WebApplication1\' failed to start process with commandline 'c:\program files (x86)\microsoft visual studio\2017\professional\common7\ide\extensions\microsoft\web tools\projectsystem\VSIISExeLauncher.exe -argFile "C:\Users\LindaL\AppData\Local\Temp\tmpF272.tmp"', ErrorCode = '0x80004005' : 0.
Application 'MACHINE/WEBROOT/APPHOST/WEBAPPLICATION1' with physical root 'C:\Users\LindaL\source\repos\Daimto.RazorTest.Tools\WebApplication1\' failed to start process with commandline 'c:\program files (x86)\microsoft visual studio\2017\professional\common7\ide\extensions\microsoft\web tools\projectsystem\VSIISExeLauncher.exe -argFile "C:\Users\LindaL\AppData\Local\Temp\tmpF272.tmp"', ErrorCode = '0x80004005' : 0.
Note i just update to visual studio professional 2017 15.9.3. I have used blazor before this was working fine.
Update: This appears only in the "Blazor" project type.
Update2: hitting Cntrl-F5 as opposed to just F5 – No change.
Update3 Project file per request in comment in answer below
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RunCommand>dotnet</RunCommand>
<RunArguments>blazor serve</RunArguments>
<LangVersion>7.3</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Blazor.Browser" Version="0.6.0" />
<PackageReference Include="Microsoft.AspNetCore.Blazor.Build" Version="0.6.0" PrivateAssets="all" />
<DotNetCliToolReference Include="Microsoft.AspNetCore.Blazor.Cli" Version="0.6.0" />
</ItemGroup>
</Project>
Delete global.json and see if that helps.
https://github.com/aspnet/Blazor/issues/1342
If that doesn't help try adding global.json with content
{
"sdk": {
"version": "2.1.500"
}
}
If all fails, close all Visual Studio instances and reinstall Blazor templates with dotnet new -i Microsoft.AspNetCore.Blazor.Templates and create new Blazor solution with dotnet new and use Blazor template you want.

EF Core 2.0.0 and Redis.Core 1.0.3 don't work together

I tried to setup a .net core console application which uses EF core 2.0.0 and Redis.Core 1.0.3 (both are the current latest version).
Unfortunately if you try to put both into one application it won't even start. Even if you try to set a breakpoint right at the beginning or start debugging with Step into or Step Over doesn't help. All you get is this:
I think there happens some kind of type load exception or something similar. So far to reproduce the problem is quite easy with this project:
Project File (MyProject.csproj)
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Redis.Core" Version="1.0.3" />
</ItemGroup>
</Project>
Application (Program.cs)
using Microsoft.Extensions.Caching.Redis;
using Microsoft.Extensions.Options;
namespace MyApplication
{
class Program
{
static void Main(string[] args)
{
var cache = new RedisCache(Options.Create(new RedisCacheOptions()));
}
}
}
Anybody an idea or solution?
The problem is that
Microsoft.Extensions.Caching.Redis.RedisCache 1.0.3 depends on Microsoft.Extensions.Caching.Abstractions 1.0.3
Microsoft.EntityFrameworkCore 2.0.0 depends on Microsoft.Extensions.Caching.Abstractions 2.0.0
If you look at the Output Window, you will get:
TypeLoadException: Method GetAsync in type
Microsoft.Extensions.Caching.Redis.RedisCache from assembly
'Microsoft.Extensions.Caching.Redis, Version=1.0.3.0, Culture=neutral,
PublicKeyToken=adb9793829ddae60' does not have an implementation.
So: either wait until RedisCache gets updated to 2.0.0 or use EntityFrameworkCore < 2.0.0

.NET Core 1.1 app with PCL, unable to build on Team services

I have following projects on solution and this works perfectly fine on my local.
However when I check code in Team service and create build it fails.
mainconsole.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
<PackageTargetFallback>portable-net45+win8</PackageTargetFallback>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NETCore.Portable.Compatibility" Version="1.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\business\business.csproj" />
<ProjectReference Include="..\portableextensibility\portableextensibility.csproj" />
<ProjectReference Include="..\portablelibrary\portablelibrary.csproj" />
</ItemGroup>
</Project>
Build tasks:
command line - tool dotnet, argument - restore
command line - tool dotnet, argument - build
Build fails:
d:\a\3\s\portablelibrary\portablelibrary.csproj(43,3): error MSB4019: The imported project "C:\Program Files\dotnet\sdk\1.0.4\Microsoft\Portable\v4.5\Microsoft.Portable.CSharp.targets" was not found. Confirm that the path in the declaration is correct, and that the file exists on disk.
d:\a\3\s\portableextensibility\portableextensibility.csproj(42,3): error MSB4019: The imported project "C:\Program Files\dotnet\sdk\1.0.4\Microsoft\Portable\v4.5\Microsoft.Portable.CSharp.targets" was not found. Confirm that the path in the declaration is correct, and that the file exists on disk.
C:\Program Files\dotnet\sdk\1.0.4\NuGet.targets(97,5): error : Unable to resolve 'd:\a\3\s\portableextensibility\portableextensibility.csproj' for '.NETCoreApp,Version=v1.1'. [d:\a\3\s\dotnetcompatibility.sln] C:\Program Files\dotnet\sdk\1.0.4\NuGet.targets(97,5): error : Unable to resolve 'd:\a\3\s\portablelibrary\portablelibrary.csproj' for '.NETCoreApp,Version=v1.1'. [d:\a\3\s\dotnetcompatibility.sln] Generating MSBuild file d:\a\3\s\mainconsole\obj\mainconsole.csproj.nuget.g.props. Generating MSBuild file d:\a\3\s\mainconsole\obj\mainconsole.csproj.nuget.g.targets. Writing lock file to disk. Path: d:\a\3\s\mainconsole\obj\project.assets.json Restore failed in 37.7 sec for d:\a\3\s\mainconsole\mainconsole.csproj.
Errors in d:\a\3\s\business\business.csproj
Unable to resolve 'd:\a\3\s\portablelibrary\portablelibrary.csproj' for '.NETStandard,Version=v1.1'.
Errors in d:\a\3\s\mainconsole\mainconsole.csproj
Unable to resolve 'd:\a\3\s\portableextensibility\portableextensibility.csproj' for '.NETCoreApp,Version=v1.1'.
Unable to resolve 'd:\a\3\s\portablelibrary\portablelibrary.csproj' for '.NETCoreApp,Version=v1.1'.
Since the solution contains PCL libraries which currently cannot be built using the dotnet cli, the project has to be built through msbuild instead of the dotnet based commands.
Here is the corrected configuration:
Build Definition
Queue options
Result

Categories

Resources