Skip to content

Akarinnnnn/dnhost-demo

Repository files navigation

DotNetHosting 项目 - .NET 运行时自定义承载示例

这是一个演示如何自定义承载 .NET 运行时的示例项目集。通过替换或扩展标准的.NET宿主,可以实现诸如版本控制、自定义程序集加载、进程注入、应用程序兼容性修补等高级场景。

项目结构概述

  • HostingSdk/ - 核心依赖:包含准备特定版本 .NET Hosting SDK 的说明。
  • osu.coreclr/ - 具体应用示例:演示如何将 .NET CoreCLR 宿主化以运行特定游戏客户端。
  • osu.Loader/ - 配套的加载器与兼容性层。

⚠️ 核心要求:成功运行osu.coreclr前,必须完成以下准备工作中的 1、2、3 步。

准备工作(osu.coreclr)

1. 获取源码与基础环境

  • 克隆仓库到本地。
  • 安装 .NET 10 SDK (x86版本)
  • 安装 Visual Studio 2026(社区版即可)。在安装器中务必勾选以下工作负载:
    • .NET 桌面开发
    • 使用C++的桌面开发

2. 准备代码签名证书

签名是强制要求,而非可选步骤。 目标应用程序(如游戏客户端)会验证其所在进程的主模块(即 osu.coreclr.exe)的代码签名有效性。未经签名的模块将导致目标程序抛出异常并拒绝运行。

你有两个选择:

  • A. 使用已有的可信证书:使用受本机信任的代码签名证书(如来自企业CA或购买的个人证书,或曾创建过的自签证书)。
  • B. 创建自签名证书(推荐用于本地测试)
    1. 创建证书:使用PowerShell创建一个用于代码签名的自签证书。
      # 打开 PowerShell(管理员权限)
      New-SelfSignedCertificate -CertStoreLocation Cert:\CurrentUser\My -Subject "CN=DotNetHosting-Local" -KeyExportPolicy Exportable -Type CodeSigningCert

      提示:可使用DeepSeek等AI助手生成更详细的证书创建命令。

    2. 导入到受信任的根目录:将创建的证书从“当前用户 -> 个人”存储区,导入到“受信任的根证书颁发机构”存储区(使用 certmgr.msc)。
    3. 重启计算机:此步骤必须执行,以使系统完全信任新证书。

📌 关于自签证书的重要说明

  • 此证书仅在你的计算机上有效。其他用户要运行你签名的程序,也必须导入此证书。
  • 签名原因:客户端验证的是进程主模块(osu.coreclr.exe)的签名,未签名的主模块将导致验证失败

3. 获取 .NET Hosting SDK

这是项目运行的核心依赖,版本必须完全匹配

  1. 进入项目下的 HostingSdk/ 文件夹。
  2. 仔细阅读并遵循其中的 README.md 文件说明。
  3. 准备 .NET 10.0.0 x86 版本的 Hosting SDK。

    🚨 警告:SDK版本必须为 10.0.0 x86,差一点都不行!

示例:osu.coreclr - 游戏客户端承载

此示例演示如何通过自定义的 .NET CoreCLR 宿主来运行 osu! 游戏客户端,特别展示了如何处理需要代码签名的真实世界场景。

示例概述与技术原理

  • 目标:使原生为 .NET Framework 编写的 osu! 客户端运行在 .NET 10 运行时上。
  • 签名必要性:osu! 客户端会验证其所在进程的主模块的代码签名。由于整个进程由 osu.coreclr.exe 启动,该主模块必须被有效签名,否则客户端将拒绝运行。
  • 核心加载原理(进程内连续加载)
    1. osu.coreclr.exe(原生C++) 作为进程主模块启动,通过 hostfxr 在同一进程内初始化 .NET CoreCLR 运行时
    2. 运行时初始化后,加载 osu.Loader 托管程序集。
    3. 调用 osu.Loader 中唯一的非托管导出函数 Loader.LoadAndExecute()
    4. 该函数继续在同一进程内加载并执行原版 osu! 客户端的程序集。

⚠️ 此示例当前状态

  • 不支持官方联网:请勿尝试连接Bancho,否则因此导致帐号被封禁,作者概不负责。此条在LICENSE文件(本项目许可条款)中有依据。禁止连Bancho的具体方式请咨询社区。
  • 可能支持第三方服务器:部分私服(如 osu.ppy.sb)可能允许此类客户端。若有需要,请手动添加相应参数。
  • 不稳定:为概念验证,可能崩溃。

编译与运行步骤

1. 编译项目

  1. 使用 Visual Studio 2026 打开项目根目录的 DotNetHosting.sln
  2. 选择 Debug | x86 作为解决方案配置。

    提示:Release | x86 会损失加载器的可调试性,并且需要额外调整调试设置。 提示2:必须是x86,stable携带的原生库是32位的。 提示3:osu.coreclr只在启动时有用,它的优化程度无关紧要。除非要将它发布给未安装VS的人,否则不需要修改配置。

  3. osu.coreclr 项目设为启动项目。
  4. osu.coreclr 项目属性的“调试”选项卡中,将“工作目录”设置为:
    ..\osu.Loader\bin\Debug\net10.0-windows\
    
    如何调整osu.coreclr项目的调试选项
  5. 按下 Ctrl+Shift+B 编译解决方案。

2. 签名主模块(关键步骤)

必须对作为进程主模块的 osu.coreclr.exe 进行有效代码签名,这是客户端验证通过的前提。

  1. 打开 Developer PowerShell for VS 2026
  2. 切换到 osu.Loader 的输出目录:
    cd "你的项目绝对路径\DotNetHosting\osu.Loader\bin\Debug\net10.0-windows"
  3. 查找你的证书名称
    Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert | Select-Object Subject
  4. 使用 signtool 签名主模块
    signtool sign /n "你的证书名称" /fd SHA512 .\osu.coreclr.exe

    注意:将 "你的证书名称" 替换为实际的证书名称(CN)。必须使用英文双引号

3. 启动游戏

首先预先添加命令行参数osu://b/1,使启动时更新检测失效。

  • 选项一(下载更新)
    1. 在 VS 中直接启动 osu.coreclr 项目(按 F5),将看到 osu! 更新窗口。
    2. 等待bootstrapper下载游戏文件,然后重新启动为.NET Framework进程。
    3. 退出游戏,此时你已经可以按照选项二的第二步继续。
  • 选项二(跳过更新)
    1. 如果 osu.Loader 输出目录没有完整客户端,则将原版 osu!.exe 及其依赖 DLL复制到输出目录。
    2. 清空osu!auth.dll内容,使其全部字节为0,这是必要步骤,否则会进入更新过程。
    3. F5运行 osu.coreclr 项目,应直接进入游戏主界面。

💡 提示

  1. 启动前建议将 Visual Studio 窗口移到另一个虚拟桌面,避免游戏全屏覆盖调试器。
  2. 若遇到崩溃,可在 Visual Studio 中查看调用堆栈以定位问题。

高级配置

  • 已知问题:某绘制当中顶点数组传入了null,但OpenTK不检查,引发了用户模式的OpenGL显卡驱动Access Violation。如果osu!(stable)利用AccessViolationException异常进行初始化,那么我们必须patch客户端。因为CoreCLR不支持任何托管代码catch此类异常。用osu!(lazer)的osuTK代替OpenTK可能有效。

其他用例(自行扩展)

您可以参考 osu.coreclr 示例的结构,创建自己的自定义承载项目,例如:

  • 为旧版 .NET Framework 应用提供现代化运行时环境。
  • 实现应用程序的插件隔离与热重载机制。
  • 构建自定义的调试与分析工具链。

贡献

如果您有新的承载用例想法或改进建议,欢迎提交 Issue 和 Pull Request 进行探讨。

About

.NET native hosting demo, run osu!stable on .NET 10 for example

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published