net9nlib 1.2.2

dotnet add package net9nlib --version 1.2.2
                    
NuGet\Install-Package net9nlib -Version 1.2.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="net9nlib" Version="1.2.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="net9nlib" Version="1.2.2" />
                    
Directory.Packages.props
<PackageReference Include="net9nlib" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add net9nlib --version 1.2.2
                    
#r "nuget: net9nlib, 1.2.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package net9nlib@1.2.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=net9nlib&version=1.2.2
                    
Install as a Cake Addin
#tool nuget:?package=net9nlib&version=1.2.2
                    
Install as a Cake Tool

net9nlib

通用 .NET 9 类库,提供日志功能和单实例应用支持,支持 Windows、Linux、Mac 平台。

功能特性

  • 日志功能: 基于 Microsoft.Extensions.Logging 的统一日志接口
    • 支持控制台、调试窗口和文件输出
    • 日志文件存储在程序运行目录,按日期自动创建子文件夹
    • 支持自定义日志名称和目录
  • 配置文件管理: 提供简单的 JSON 配置文件读写功能
    • 配置文件存储在程序运行目录
    • 支持类型安全的配置读写
    • 支持实体双向绑定
  • 单实例应用: 确保应用程序在同一时间只能运行一个实例
  • 开机启动: 支持 Windows 平台的开机自动启动(通过启动文件夹快捷方式)
  • WinForms 全局异常捕获: 支持 WinForms 程序统一捕获 UI/非 UI/Task 异常(仅 Windows)
  • 跨平台支持: 支持 Windows、Linux、Mac 三大平台(部分功能仅 Windows)

安装

dotnet add package net9nlib

快速开始

日志功能

基础日志(仅控制台输出)
using net9nlib;

// 创建日志服务(仅控制台输出)
var logger = Net9nLib.CreateLoggerService("MyApp");

// 使用日志
logger.LogInformation("应用程序启动");
logger.LogWarning("这是一个警告");
logger.LogError("这是一个错误");
logger.LogError(exception, "发生异常: {Message}", exception.Message);
文件日志(推荐)
using net9nlib;
using Microsoft.Extensions.Logging;

// 创建带文件输出的日志服务
// 日志文件存储在程序运行目录的 logs 文件夹下,按日期创建子文件夹
// 日志文件格式:logs/yyyy-MM-dd/日志名_yyyy-MM-dd.log
var (logger, loggerFactory) = Net9nLib.CreateFileLoggerService(
    logName: "MyApp",              // 日志名称(用于日志文件名)
    categoryName: "MyApp",          // 日志类别名称
    enableConsole: true,            // 是否启用控制台输出
    enableDebug: true,              // 是否启用调试输出
    minimumLevel: LogLevel.Debug   // 最小日志级别
);

// 使用日志(会自动写入文件)
logger.LogInformation("应用程序启动");
logger.LogWarning("这是一个警告");
logger.LogError("这是一个错误");

// 注意:需要保持 loggerFactory 的引用,程序退出时调用 Dispose
loggerFactory.Dispose();
日志文件结构
程序运行目录/
├── logs/
│   ├── 2026-01-28/
│   │   └── MyApp_2026-01-28.log
│   ├── 2026-01-29/
│   │   └── MyApp_2026-01-29.log
│   └── ...

单实例应用

using net9nlib;

// 创建单实例服务
var singleInstance = Net9nLib.CreateSingleInstanceService();

// 尝试获取锁
if (!singleInstance.TryAcquireLock("MyUniqueAppName"))
{
    Console.WriteLine("应用程序已在运行,退出当前实例");
    return;
}

try
{
    // 应用程序主逻辑
    Console.WriteLine("应用程序正在运行...");
    // ...
}
finally
{
    // 释放资源
    singleInstance.Dispose();
}

开机启动(仅 Windows)

using net9nlib;

// 检查是否为 Windows 平台
if (OperatingSystem.IsWindows())
{
    try
    {
        // 创建开机启动服务(默认使用所有用户的启动文件夹,需要管理员权限)
        // 所有用户的启动文件夹:无论哪个用户登录都会启动
        var autoStart = Net9nLib.CreateAutoStartService(useAllUsers: true);
        
        // 如果只想为当前用户设置开机启动,可以使用:
        // var autoStart = Net9nLib.CreateAutoStartService(useAllUsers: false);
        
        var appName = "MyApp";
        var exePath = Environment.ProcessPath ?? AppDomain.CurrentDomain.BaseDirectory;
        
        // 检查是否已设置开机启动
        if (autoStart.IsAutoStartEnabled(appName))
        {
            Console.WriteLine("应用程序已设置开机启动");
        }
        else
        {
            // 设置开机启动(所有用户启动文件夹需要管理员权限)
            if (autoStart.SetAutoStart(appName, exePath, null, "我的应用程序"))
            {
                Console.WriteLine("已设置开机启动(所有用户)");
            }
        }
        
        // 取消开机启动
        // autoStart.RemoveAutoStart(appName);
    }
    catch (PlatformNotSupportedException)
    {
        Console.WriteLine("开机启动功能仅支持 Windows 平台");
    }
    catch (UnauthorizedAccessException)
    {
        Console.WriteLine("设置所有用户的开机启动需要管理员权限");
    }
}

启动文件夹说明:

  • 所有用户的启动文件夹(默认):%ProgramData%\Microsoft\Windows\Start Menu\Programs\StartUp
    • 无论哪个用户登录都会启动
    • 需要管理员权限才能写入
  • 当前用户的启动文件夹%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup
    • 仅当前用户登录时启动
    • 不需要管理员权限

WinForms 全局异常捕获(仅 Windows)

using net9nlib;
using Microsoft.Extensions.Logging;
using System.Windows.Forms;

// 1) 建议使用文件日志
var (logger, loggerFactory) = Net9nLib.CreateFileLoggerService(
    logName: "MyWinFormsApp",
    categoryName: "MyWinFormsApp"
);

// 2) 在 Application.Run 之前尽早注册
using var guard = Net9nLib.CreateWithWinForms全局异常捕获(
    logger,
    new WinFormsGlobalExceptionOptions
    {
        ApplicationName = "MyWinFormsApp",
        ShowMessageBox = true,
        ExitOnFatal = true,
        OnException = (src, ex) =>
        {
            // 可选:写入额外现场信息/触发告警/安全停机等
        }
    }
);

Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());

// 3) 程序退出时释放(using 会自动 Dispose);同时释放 loggerFactory 关闭文件句柄
loggerFactory.Dispose();

覆盖范围:

  • UI 线程异常:Application.ThreadException
  • 非 UI 线程未处理异常:AppDomain.CurrentDomain.UnhandledException
  • 未观察到的 Task 异常:TaskScheduler.UnobservedTaskException

配置文件管理

基础配置管理器(键值对方式)
using net9nlib;

// 创建配置文件管理器(配置文件存储在程序运行目录)
var config = Net9nLib.CreateConfigManager("MyApp");

// 读取配置(带默认值)
var appName = config.GetValue("AppName", "默认应用名称");
var maxRetries = config.GetValue("MaxRetries", 3);
var timeout = config.GetValue("Timeout", TimeSpan.FromSeconds(30));

// 设置配置
config.SetValue("AppName", "我的应用程序");
config.SetValue("MaxRetries", 5);
config.SetValue("Timeout", TimeSpan.FromMinutes(1));

// 保存配置到文件
config.SaveConfig();

// 获取配置文件路径
Console.WriteLine($"配置文件路径: {config.ConfigFilePath}");
实体配置管理器(双向绑定,推荐)
using net9nlib;

// 定义配置实体类
public class AppConfig
{
    public string AppName { get; set; } = "默认应用";
    public int MaxRetries { get; set; } = 3;
    public int TimeoutSeconds { get; set; } = 30;
    public bool EnableDebug { get; set; } = true;
    public List<string> ServerUrls { get; set; } = new();
}

// 创建实体配置管理器(支持双向绑定)
var entityConfig = Net9nLib.CreateEntityConfigManager<AppConfig>("MyApp");

// 自动从配置文件加载实体(如果文件不存在,使用默认值)
var config = entityConfig.Entity;
Console.WriteLine($"应用名称: {config.AppName}");

// 修改实体属性
config.AppName = "我的应用程序";
config.MaxRetries = 5;
config.ServerUrls.Add("http://example.com");

// 保存实体到配置文件(双向绑定)
entityConfig.Save();

// 重新加载配置(从文件读取)
var reloadedConfig = entityConfig.Reload();

// 重置为默认值
var defaultConfig = entityConfig.Reset();

实体双向绑定的优势:

  • ✅ 类型安全:编译时检查,避免键名拼写错误
  • ✅ 自动序列化:实体对象自动转换为 JSON
  • ✅ 支持复杂对象:嵌套对象、集合等
  • ✅ 代码简洁:直接操作对象属性,无需键值对
  • ✅ 智能默认值:使用实体类的属性初始值

完整示例

using net9nlib;
using Microsoft.Extensions.Logging;

// 创建带文件输出的日志服务
var (logger, loggerFactory) = Net9nLib.CreateFileLoggerService(
    logName: "MyApp",
    categoryName: "MyApp"
);

// 创建配置文件管理器
var config = Net9nLib.CreateConfigManager("MyApp");

// 读取配置
var appName = config.GetValue("AppName", "默认应用");
logger.LogInformation("应用程序名称: {AppName}", appName);

// 创建单实例服务
var singleInstance = Net9nLib.CreateSingleInstanceService();

// 检查单实例
if (!singleInstance.TryAcquireLock("MyUniqueAppName"))
{
    logger.LogWarning("应用程序已在运行,退出当前实例");
    return;
}

logger.LogInformation("应用程序启动成功");

try
{
    // 应用程序主逻辑
    logger.LogInformation("应用程序正在运行...");
}
catch (Exception ex)
{
    logger.LogError(ex, "应用程序发生错误");
}
finally
{
    singleInstance.Dispose();
    loggerFactory.Dispose(); // 释放日志工厂
    logger.LogInformation("应用程序退出");
}

API 文档

ILoggerService

提供统一的日志记录接口:

  • LogDebug(string message, params object[] args) - 记录调试信息
  • LogInformation(string message, params object[] args) - 记录信息
  • LogWarning(string message, params object[] args) - 记录警告
  • LogError(string message, params object[] args) - 记录错误
  • LogError(Exception exception, string message, params object[] args) - 记录错误(带异常)
  • LogCritical(string message, params object[] args) - 记录严重错误
  • LogCritical(Exception exception, string message, params object[] args) - 记录严重错误(带异常)

ISingleInstanceService

提供单实例应用支持:

  • TryAcquireLock(string instanceName) - 尝试获取单实例锁
  • IsLockAcquired - 是否已获取锁
  • Dispose() - 释放资源

IAutoStartService

提供开机启动功能(仅 Windows):

  • IsAutoStartEnabled(string appName) - 检查是否已设置开机启动
  • SetAutoStart(string appName, string executablePath, string? arguments, string? description) - 设置开机启动
  • RemoveAutoStart(string appName) - 取消开机启动

启动文件夹选项:

  • 默认使用所有用户的启动文件夹(%ProgramData%\Microsoft\Windows\Start Menu\Programs\StartUp),需要管理员权限
  • 所有用户的启动文件夹:无论哪个用户登录都会启动
  • 可通过 CreateAutoStartService(useAllUsers: false) 使用当前用户的启动文件夹

WinFormsGlobalExceptionService

提供 WinForms 全局异常捕获(仅 Windows + WinForms):

  • CreateWith全局异常捕获(ILoggerService logger, WinFormsGlobalExceptionOptions? options) - 创建并安装全局异常捕获
  • Dispose() - 解除订阅(建议用 using

相关配置:

  • WinFormsGlobalExceptionOptions.ShowMessageBox - 是否弹窗提示
  • WinFormsGlobalExceptionOptions.ExitOnFatal - 致命异常是否退出
  • WinFormsGlobalExceptionOptions.ObserveUnobservedTaskException - 是否 SetObserved

ConfigManager

提供基础配置文件管理功能(键值对方式):

  • GetValue<T>(string key, T defaultValue) - 获取配置值(带默认值)
  • SetValue<T>(string key, T value) - 设置配置值
  • GetAllValues() - 获取所有配置
  • SaveConfig() - 保存配置到文件
  • ConfigFilePath - 配置文件路径(只读)

EntityConfigManager<T>

提供实体双向绑定功能(推荐使用):

  • Entity - 获取当前绑定的实体对象(自动加载)
  • Load() - 从配置文件加载实体
  • Save() - 保存当前实体到配置文件
  • Save(T entity) - 保存指定实体到配置文件
  • Reload() - 重新加载实体(从文件读取)
  • Reset() - 重置实体为默认值
  • ConfigFilePath - 配置文件路径(只读)
  • ConfigFileExists - 配置文件是否存在(只读)

使用要求:

  • 实体类型 T 必须有无参构造函数(new() 约束)
  • 实体属性必须是可序列化的(public 属性)

平台支持

  • ✅ Windows
    • 单实例:使用 Mutex
    • 开机启动:使用启动文件夹快捷方式
  • ✅ Linux
    • 单实例:使用文件锁
  • ✅ macOS
    • 单实例:使用文件锁

注意: 开机启动功能仅支持 Windows 平台。

许可证

MIT License

作者

aranwuyou

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net9.0-windows7.0 is compatible.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.2 127 1/28/2026
1.2.1 126 1/28/2026
1.2.0 127 1/28/2026
1.1.0 122 1/28/2026
1.0.0 123 1/28/2026