{"id":26030526,"url":"https://github.com/asmichi/dotnetinjectnativefiledepshack","last_synced_at":"2026-04-16T21:34:29.540Z","repository":{"id":41469700,"uuid":"509732393","full_name":"asmichi/DotNetInjectNativeFileDepsHack","owner":"asmichi","description":"An insane hack to inject runtime files into deps.json during a dotnet build process.","archived":false,"fork":false,"pushed_at":"2023-05-02T15:24:59.000Z","size":17,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-06T00:53:25.695Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PowerShell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/asmichi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-07-02T11:05:27.000Z","updated_at":"2024-10-26T04:34:25.000Z","dependencies_parsed_at":"2022-09-12T00:50:32.677Z","dependency_job_id":null,"html_url":"https://github.com/asmichi/DotNetInjectNativeFileDepsHack","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asmichi%2FDotNetInjectNativeFileDepsHack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asmichi%2FDotNetInjectNativeFileDepsHack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asmichi%2FDotNetInjectNativeFileDepsHack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asmichi%2FDotNetInjectNativeFileDepsHack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/asmichi","download_url":"https://codeload.github.com/asmichi/DotNetInjectNativeFileDepsHack/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242263548,"owners_count":20099219,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-03-06T18:32:14.462Z","updated_at":"2026-04-16T21:34:29.427Z","avatar_url":"https://github.com/asmichi.png","language":"PowerShell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Asmichi.InjectNativeFileDepsHack\n\nAn *insane hack* to inject runtime assets into deps.json by injecting `RuntimeTargetsCopyLocalItems` items into the `GenerateDepsFile` task.\n\nThis library can be obtained via [NuGet](https://www.nuget.org/packages/Asmichi.InjectNativeFileDepsHack/).\n\n# Background\n\nBy default (without `DllImportSearchPath.AssemblyDirectory`), the .NET runtime only loads native DLLs listed in the deps.json of an application. There is a long-standing issue: deps.json does not list native DLLs from reference projects (only native DLLs from NuGet packages), which means that such native DLLs cannot be loaded:\n\n- https://github.com/dotnet/sdk/issues/765 Copy runtime libraries from references project\n- https://github.com/dotnet/sdk/issues/1088 Allow runtime-specific assets in the project\n- https://github.com/dotnet/sdk/issues/24708 Architecture-specific folders like runtimes/\u003crid\u003e/native/ outside of NuGet packages [nativeinterop]\n\nSo, if you develop a library containing native DLLs, you get stuck. The test projects and sample projects will project-reference the library project, which does not work!\n\n# WARNING\n\nAgain, this is an *insane hack* that plays with the implementation details deep inside the .NET SDK. It is likely that this will break **even by a minor version update** of the .NET SDK.\n\nTested on the following versions of the .NET SDK:\n\n- 6.0.301\n\n# Usage\nList the native files as `InjectNativeFileDepsHack` items in your application project (**not** your library project).\n\nNotes:\n\n- Normally you list the native DLLs as `Content` items in the library project, so the native DLLs should be copied into `$(OutputPath)`.\n- You cannot use wildcards in `Include` to list files within output directories because these wildcards are evaluated before the build starts and thus output files are not yet built (such a wildcard will break clean builds).\n\n```xml\n  \u003cItemGroup\u003e\n    \u003cPackageReference Include=\"Asmichi.InjectNativeFileDepsHack\" Version=\"0.2.0\" PrivateAssets=\"all\" IncludeAssets=\"runtime;build;native;contentfiles;analyzers\" /\u003e\n  \u003c/ItemGroup\u003e\n\n  \u003cItemGroup\u003e\n    \u003cInjectNativeFileDepsHack Include=\"$(OutputPath)runtimes\\linux-x64\\native\\libMyAwesomeLibrary.so\"\u003e\n      \u003c!-- The relative path of the deployed directory from the application directory. --\u003e\n      \u003cDestinationSubDirectory\u003eruntimes\\linux-x64\\native\u003c/DestinationSubDirectory\u003e\n      \u003c!-- RID --\u003e\n      \u003cRuntimeIdentifier\u003elinux-x64\u003c/RuntimeIdentifier\u003e\n    \u003c/InjectNativeFileDepsHack\u003e\n  \u003c/ItemGroup\u003e\n```\n\n# Appendices\n\n## Example\n\nSee [sample](sample) for a minimal example. To run the sample, on an x64 Linux system, run:\n\n```\n(cd sample; ./build_and_run.sh)\n```\n\n## Real-world example\n\nSee https://github.com/asmichi/ChildProcess/blob/master/build/msbuild/InjectChildProcessNativeFileDeps.targets and its usage.\n\n## How Asmichi.InjectNativeFileDepsHack works\n\nBasically, it tricks the deps.json generation process into treating the specified native DLLs as the runtime assets of the `Asmichi.InjectNativeFileDepsHack` NuGet library.\n\nThe `runtimeTargets` items (`assetType` == `native`) of a library [comes from `RuntimeLibray.NativeLibraryGroups`](https://github.com/dotnet/runtime/blob/v6.0.6/src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContextWriter.cs#L289). Looking into [the target](https://github.com/dotnet/sdk/blob/v6.0.301/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.targets#L176),  [`GenerateDepsFile`](https://github.com/dotnet/sdk/blob/v6.0.301/src/Tasks/Microsoft.NET.Build.Tasks/GenerateDepsFile.cs#L194) and [`DependencyContextBuilder`](https://github.com/dotnet/sdk/blob/v6.0.301/src/Tasks/Microsoft.NET.Build.Tasks/DependencyContextBuilder.cs#L529) for clues of how `NativeLibraryGroups` are collected, you will notice that a `project` type library always have empty `NativeLibraryGroups`. So, there is no way to add `runtimeTargets` items into a `project` type library. Absolutely no way! Only NuGet libraries!\n\nNuGet runtime files are collected by `ResolvePackageAssets` as `RuntimeTargetsCopyLocalItems`. `Asmichi.InjectNativeFileDepsHack` adds the specified native DLLs as `RuntimeTargetsCopyLocalItems` items just before `GenerateDepsFile` runs, hence they appear as `runtimeTargets` items of the `Asmichi.InjectNativeFileDepsHack` NuGet library.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasmichi%2Fdotnetinjectnativefiledepshack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fasmichi%2Fdotnetinjectnativefiledepshack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasmichi%2Fdotnetinjectnativefiledepshack/lists"}