clr-loader icon indicating copy to clipboard operation
clr-loader copied to clipboard

Implement support for self-contained .NET project

Open filmor opened this issue 4 years ago • 8 comments

Example project available in previous pythonnet issue.

filmor avatar Dec 13 '21 16:12 filmor

Related issues and PRs:

https://github.com/dotnet/runtime/issues/35465 https://github.com/dotnet/runtime/issues/39167 https://github.com/dotnet/runtime/pull/36990

filmor avatar Jan 12 '22 15:01 filmor

I found a neat workaround to run .NET projects in a self-contained manner which could suffice for most people encountering this issue. What we need to do is to bring dotnet by ourselves.

Example:

  • my-dotnet-directory
    • libhostfxr.so
    • shared
      • Microsoft.NETCore.App
        • 6.0.11
          • ...files

Because we are bringing all dotnet libraries already, we don't need to build our project as self-contained. Normally building the project is enough. This is how I call it in pythonnet

import os
from pythonnet import load

dotnet_root = os.path.abspath('./my-dotnet-directory')
runtime_config = os.path.abspath('runtimeconfig.json')
load("coreclr", dotnet_root=dotnet_root, runtime_config=runtime_config)

import clr
import os

clr.AddReference(os.path.abspath('./my-project/my-project.dll'))

from MyProject import Program
program = Program()
program.ExecuteSync()

This way I'm able to run my application as 'self-contained'

runtimeconfig.json:

{"runtimeOptions": {"tfm": "net6.0", "framework": {"name": "Microsoft.NETCore.App", "version": "6.0.11"}}}

vgibilmanno avatar Nov 14 '22 10:11 vgibilmanno

I found a neat workaround to run .NET projects in a self-contained manner which could suffice for most people encountering this issue. What we need to do is to bring dotnet by ourselves.

Example:

  • my-dotnet-directory

    • libhostfxr.so

    • shared

      • Microsoft.NETCore.App

        • 6.0.11

          • ...files

Because we are bringing all dotnet libraries already, we don't need to build our project as self-contained. Normally building the project is enough. This is how I call it in pythonnet

import os
from pythonnet import load

dotnet_root = os.path.abspath('./my-dotnet-directory')
runtime_config = os.path.abspath('runtimeconfig.json')
load("coreclr", dotnet_root=dotnet_root, runtime_config=runtime_config)

import clr
import os

clr.AddReference(os.path.abspath('./my-project/my-project.dll'))

from MyProject import Program
program = Program()
program.ExecuteSync()

This way I'm able to run my application as 'self-contained'

runtimeconfig.json:

{"runtimeOptions": {"tfm": "net6.0", "framework": {"name": "Microsoft.NETCore.App", "version": "6.0.11"}}}

@vgibilmanno Are you able to run this in linux? I am trying in Ubuntu

rishky-msft avatar Nov 14 '22 10:11 rishky-msft

@rishky-msft I'm able to run this on Debian 11 and Windows 11. It should work on Ubuntu too since it is based on Debian

vgibilmanno avatar Nov 14 '22 10:11 vgibilmanno

Why is this only a "workaround"? What are the limitations/risks of doing this?

sherryyshi avatar Sep 07 '23 23:09 sherryyshi

I just wanted to add a note about this workaround that was working fine in the past but now it seemed to stop working on my macbook M1. I did the test with NET8. I was getting an error. It was complaining that it couldn't find the dotnet-root folder. So after some trail and error i noticed an issue with the folder structure. see the example below. Example:

• my-dotnet-directory

	• libhostfxr.so

	• shared

		• shared

			• Microsoft.NETCore.App

				• 6.0.11

					...files

As you can see there is a 'shared' directory within the 'shared' directory in my case this works now.

The runtimeconfig.json is still the same:

{"runtimeOptions": {"tfm": "net8.0", "framework": {"name": "Microsoft.NETCore.App", "version": "8.0.1"}}}

If anyone has a better solution to this. Please let us know.

adwenn avatar Jul 13 '24 07:07 adwenn