Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/nulastudio/netbeauty2

Move a .NET Framework/.NET Core app runtime components and dependencies into a sub-directory and make it beauty.
https://github.com/nulastudio/netbeauty2

fody nbeauty ncbeauty netbeauty netbeauty2 netcorebeauty portable

Last synced: 6 days ago
JSON representation

Move a .NET Framework/.NET Core app runtime components and dependencies into a sub-directory and make it beauty.

Awesome Lists containing this project

README

        

# NetBeauty 2

## What is it?
NetBeauty moves a .NET Framework/.NET Core app runtime components and dependencies into a sub-directory and make it beauty.

### After Beauty
![after_beauty](screenshot/after_beauty.png)

**EVEN LESS!**

see [`--hiddens`](#use-the-binary-application-if-your-project-has-already-been-published) option

![after_beauty_with_hiddens](screenshot/after_beauty_with_hiddens.png)

### Before Beauty
![before_beauty](screenshot/before_beauty.png)

## What's New?
| | [NetBeauty 2](https://github.com/nulastudio/NetBeauty2) | [NetCoreBeauty](https://github.com/nulastudio/NetBeauty2/tree/v1) |
| ---- | ---- | ---- |
| Supported Framework | `.Net Framework`
`.Net Core 3.0+` | `.Net Core 2.0+` |
| Supported Deployment Model | Framework-dependent deployment (`FDD`)
Self-contained deployment (`SCD`)
Framework-dependent executables (`FDE`) | Self-contained deployment (`SCD`) |
| Supported System | All | `win-x64` `win-x86`
`win-arm64`(.NET 6+)
`linux-x64` `linux-arm` `linux-arm64`
`osx-x64`
`osx-arm64`(.NET 6+) |
| Need Patched HostFXR | No
Yes(if use patch) | Yes |
| Minimum Structure | ~20 Files
~8 Files(if use patch) | ~8 Files |
| How It Works | [`STARTUP_HOOKS`](https://github.com/dotnet/runtime/blob/main/docs/design/features/host-startup-hook.md)
[`AssemblyLoadContext.Resolving`](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.loader.assemblyloadcontext.resolving?view=netcore-3.0)
[`AssemblyLoadContext.ResolvingUnmanagedDll`](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.loader.assemblyloadcontext.resolvingunmanageddll?view=netcore-3.0)
+
[`patched libhostfxr`](https://github.com/nulastudio/HostFXRPatcher)(if use patch)
[`additionalProbingPaths`](https://github.com/dotnet/toolset/blob/master/Documentation/specs/runtime-configuration-file.md#runtimeoptions-section-runtimeconfigjson)(if use patch) | [`patched libhostfxr`](https://github.com/nulastudio/HostFXRPatcher)
[`additionalProbingPaths`](https://github.com/dotnet/toolset/blob/master/Documentation/specs/runtime-configuration-file.md#runtimeoptions-section-runtimeconfigjson) |
| Shared Runtime | Yes | Possible If Using `patched libhostfxr` Alone |

## The patch is back!
One of the main goals of NetBeauty2 is trying to use a customize loader to replace the patch, but in fact, the loader need to use lots of Types and APIs like `Dictionary` `List` `Path.GetFullPath` `File.Exists` `NativeLibrary` `RuntimeInformation` etc. this causes lots of assembly references and the worst thing is that those files can not be moved, otherwise CoreCLR will failed to initialize and invoke the loader. More complex logic, more files. So i have to make it back.

Now they work excellently together!

the loader lets us support `FDD`/`FDE` apps.

the patch reduces the file count as possible(`SCD` app only).

## How to use?
### Add Nuget reference to your .NET Core project.
```
dotnet add package nulastudio.NetBeauty
```
Your `*.csproj` should be like:
```xml


Exe
netcoreapp3.0


False

../libraries
./libraries





False

False

False

auto

False



True










Info





```
When you run `dotnet build` or `dotnet publish`, everything will be done automatically.

### Use the binary application if your project has already been published.
```
Usage:
nbeauty2 [--loglevel=(Error|Detail|Info)] [--srmode] [--enabledebug] [--usepatch] [--hiddens=hiddenFiles] [--noruntimeinfo] [--roll-forward=] [--nbloaderverpolicy=(auto|with|without)] [--apphostentry=] [--apphostdir=] [ []]
```

for example
```
ncbeauty2 --usepatch --loglevel Detail --hiddens "hostfxr;hostpolicy;*.deps.json;*.runtimeconfig*.json" /path/to/publishDir libraries "dll1.dll;lib*;..."
```

**`--hiddens` option just hiding the files, not move them, and only works under Windows!**

### Install as a .NETCore Global Tool
```
dotnet tool install --global nulastudio.nbeauty
```
then use it just like normal binary distribution.

## Shared Runtime Structure
```
├── libraries - shared runtime dlls(customizable name)
│ ├── locales - satellite assemblies
│ │ ├── en
│ │ │ └── *.resources.dll
│ │ │ ├── MD5_1 - allows multiple runtimes between apps.
│ │ │ │ └── *.resources.dll
│ │ │ └── MD5_2
│ │ │ └── *.resources.dll
│ │ │
│ │ ├── zh-Hans
│ │ │ └── *.resources.dll
│ │ │ ├── MD5_1
│ │ │ │ └── *.resources.dll
│ │ │ └── MD5_2
│ │ │ └── *.resources.dll
│ │ │
│ │ └── ... - others languages
│ │
│ ├── *.dll - shared managed assemblies
│ │ ├── MD5_1
│ │ │ └── *.dll
│ │ └── MD5_2
│ │ └── *.dll
│ │
│ └── srm_native - native dlls(can't be shared, each app has a full
│ ├── APPID_1 copy of their own native dlls)
│ │ └── *.dll
│ └── APPID_2
│ └── *.dll


├── app1 - the app1 main/base folder
│ ├── hostfxr.dll;... - dlls that can't be moved.
│ ├── nbloader.dll - NBLoader(will be moved if use patch)
│ ├── app1.deps.json
│ ├── app1.dll
│ ├── app1.exe
│ ├── app1.runtimeconfig.json
│ └── ...


└── app2 - the app2 main/base folder
├── hostfxr.dll;...
├── nbloader.dll
├── app2.deps.json
├── app2.dll
├── app2.exe
├── app2.runtimeconfig.json
└── ...
```

## Customize AppHost
Inspired by [`AppHostPatcher`](https://github.com/dnSpy/dnSpy/tree/master/Build/AppHostPatcher).

More user-friendly folder structure for software suite by patching the imprinted entry path of AppHost, [Demo](https://github.com/nulastudio/NetBeauty2/tree/master/NetBeautyTest/SharedRuntimeTest).

```
├── MyApp - the app1 main/base folder
│ ├── libs - dependencies.
│ ├── hostfxr.dll;... - dlls that can't be moved.
│ ├── nbloader.dll - NBLoader(will be moved if use patch)
│ ├── MyApp.deps.json
│ ├── MyApp.dll
│ ├── MyApp.runtimeconfig.json
│ └── ...

└── MyApp.exe - AppHost
```

`Shared Runtime` + `Customized AppHost`

```
├── libraries - shared runtime dlls(customizable name)

├── app1 - the app1 main/base folder
│ ├── hostfxr.dll;... - dlls that can't be moved.
│ ├── app1.deps.json
│ ├── app1.dll
│ ├── app1.runtimeconfig.json
│ └── ...

├── app2 - the app2 main/base folder
│ ├── hostfxr.dll;...
│ ├── app2.deps.json
│ ├── app2.dll
│ ├── app2.runtimeconfig.json
│ └── ...

├── app1.exe
└── app2.exe
```