Server SDK fails when the app is published as a Self Contained app

The platform specific adoption for different operating systems Windows, Linux, 32 and 64 bit, and different architectures x86, ARM, PPC, etc ...

Moderator: Support Team

Post Reply
jramirez-jh
Sr. Member
Sr. Member
Posts: 10
Joined: 14 Jun 2021, 23:39

Server SDK fails when the app is published as a Self Contained app

Post by jramirez-jh »

I'm trying to distribute my server as a Self-Contained .NET 5 App.

So what I do is to execute this command:

Code: Select all

dotnet publish -r win-x64 /p:PublishSingleFile=true /p:IncludeNativeLibrariesForSelfExtract=true --self-contained true
Once it's published and running it fails at the SDK level, exactly at the point when it's called:

Code: Select all

ApplicationInstanceBase.Start(ServerManager, null, ServerManager);
The stacktrace is the following:

Code: Select all

2021-10-26 13:11:27.200 +02:00 [ERR] OPC-UA Server - Failed. Exception: System.ArgumentException: The path is empty. (Parameter 'path')
   at System.IO.Path.GetFullPath(String path)
   at System.IO.FileInfo..ctor(String originalPath, String fullPath, String fileName, Boolean isNormalized)
   at UnifiedAutomation.UaServer.ServerSettings..ctor(ApplicationInstanceBase application)
   at UnifiedAutomation.UaServer.ServerManager.OnServerStarting(ApplicationInstanceBase application)
   at UnifiedAutomation.UaBase.ServerBase.Start(ApplicationInstanceBase application)
   at UnifiedAutomation.UaServer.ServerManager.Start(ApplicationInstanceBase application)
   at UnifiedAutomation.UaBase.ApplicationInstanceBase.Start(ServerBase server, WaitCallback callback, Object userData, Boolean silent)
The exactly same code published as a normal debug/release works without any issues.

User avatar
Support Team
Hero Member
Hero Member
Posts: 2695
Joined: 18 Mar 2011, 15:09

Re: Server SDK fails when the app is published as a Self Contained app

Post by Support Team »

Hi,

Microsoft has broken some API from Core 3.x to .NET 5. For that reason you can not use self-contained feature in .NET 5 in a similar way you are used to by Core3.x anymore. The API incompatibility within the different .NET Frameworks effects the location and path functions that are typically used to obtain DLL locations.

However, there is a switch (IncludeAllContentForSelfExtract) you can use to retain the behavior of the .NET Core 3.x. With that the "extraction before execution" is enabled again and includes the managed assemblies as well as the native ones.

Note: for security reasons you should limit access rights on the base folder used for extraction, on Linux this typically is done implicitely when extracting to "$HOME/.net", on Windows you should take similar precautions.
Best regards
Unified Automation Support Team

jramirez-jh
Sr. Member
Sr. Member
Posts: 10
Joined: 14 Jun 2021, 23:39

Re: Server SDK fails when the app is published as a Self Contained app

Post by jramirez-jh »

Support Team wrote:
26 Oct 2021, 16:02
Hi,

Microsoft has broken some API from Core 3.x to .NET 5. For that reason you can not use self-contained feature in .NET 5 in a similar way you are used to by Core3.x anymore. The API incompatibility within the different .NET Frameworks effects the location and path functions that are typically used to obtain DLL locations.

However, there is a switch (IncludeAllContentForSelfExtract) you can use to retain the behavior of the .NET Core 3.x. With that the "extraction before execution" is enabled again and includes the managed assemblies as well as the native ones.

Note: for security reasons you should limit access rights on the base folder used for extraction, on Linux this typically is done implicitely when extracting to "$HOME/.net", on Windows you should take similar precautions.
What about .NET 6? Have you tested this behavior with the current 6.0.100-rc.2?

bkraemer-jh
Jr. Member
Jr. Member
Posts: 1
Joined: 18 Nov 2021, 11:21

Re: Server SDK fails when the app is published as a Self Contained app

Post by bkraemer-jh »

The issue lies in the constructor of ServerSettings. Microsoft also has in it's documents, that for single file applications, the entry assembly will have an empty string. So it's a missing in the library from my sight. But there is an easy fix that the library could do, taking that into account (also ensuring that it's not crashing on empty strings anymore).

Code: Select all

if (serverSettings.BuildDate == DateTime.MinValue)
{
	Assembly entryAssembly = PlatformUtils.GetEntryAssembly();
	if (entryAssembly != (Assembly)null)
	{
		var assemblyLocation = entryAssembly.Location;
		if (string.IsNullOrEmpty(assemblyLocation))
		{
			assemblyLocation = System.Diagnostics.Process.GetCurrentProcess().MainModule?.FileName;
		}

		if (!string.IsNullOrEmpty(assemblyLocation))
		{
			FileInfo fileInfo = new FileInfo(entryAssembly.Location);
			if (fileInfo.Exists) {
				this.BuildDate = fileInfo.LastWriteTimeUtc;
			}
		}
	}
}
This bug can be worked around by setting the BuildDate manually (i.e. using this fix in your own code) to avoid the ctor going into the DateTime.MinValue routine.

jramirez-jh
Sr. Member
Sr. Member
Posts: 10
Joined: 14 Jun 2021, 23:39

Re: Server SDK fails when the app is published as a Self Contained app

Post by jramirez-jh »

bkraemer-jh wrote:
18 Nov 2021, 11:28
The issue lies in the constructor of ServerSettings. Microsoft also has in it's documents, that for single file applications, the entry assembly will have an empty string. So it's a missing in the library from my sight. But there is an easy fix that the library could do, taking that into account (also ensuring that it's not crashing on empty strings anymore).

Code: Select all

if (serverSettings.BuildDate == DateTime.MinValue)
{
	Assembly entryAssembly = PlatformUtils.GetEntryAssembly();
	if (entryAssembly != (Assembly)null)
	{
		var assemblyLocation = entryAssembly.Location;
		if (string.IsNullOrEmpty(assemblyLocation))
		{
			assemblyLocation = System.Diagnostics.Process.GetCurrentProcess().MainModule?.FileName;
		}

		if (!string.IsNullOrEmpty(assemblyLocation))
		{
			FileInfo fileInfo = new FileInfo(entryAssembly.Location);
			if (fileInfo.Exists) {
				this.BuildDate = fileInfo.LastWriteTimeUtc;
			}
		}
	}
}
This bug can be worked around by setting the BuildDate manually (i.e. using this fix in your own code) to avoid the ctor going into the DateTime.MinValue routine.
Thanks @bkraemer-jh I've applied your suggestion and now my Server is running completely fine when published as a Self Contained or Single File .NET 5 app.

Post Reply