<p>Notepad++ 本身不能运行 C# 代码片段,但可通过 Roslyn 的 CSharpScript.EvaluateAsync 实现轻量级脚本执行——前提是跳过 .NET SDK 环境依赖,改用预编译的 Roslyn 脚本运行时(如 Microsoft.CodeAnalysis.Scripting NuGet 包),且必须手动管理引用和命名空间。</p>

Notepad++ 本身不能运行 C# 代码片段,但可通过 Roslyn 的 CSharpScript.EvaluateAsync 实现轻量级脚本执行——前提是跳过 .NET SDK 环境依赖,改用预编译的 Roslyn 脚本运行时(如 Microsoft.CodeAnalysis.Scripting NuGet 包),且必须手动管理引用和命名空间。
为什么直接调用 csc.exe 或 dotnet run 不算“运行代码片段”
传统方式(csc 编译成 .exe / dotnet run 执行项目)要求完整文件结构、Main 方法、项目文件(.csproj),甚至输出目录权限。而“代码片段”通常只是几行表达式或语句,比如 1 + 2 * 3 或 DateTime.Now.ToString("yyyy-MM-dd"),它不构成可编译的程序入口。硬套编译流程会失败或报错 CS5001。
-
csc默认只接受完整类定义,不支持裸表达式 -
dotnet run必须在含.csproj的目录下执行,且要求Program.cs有静态Main - Notepad++ 的 NppExec 无法自动补全引用、using 或上下文变量,纯靠命令行做不到“片段级”求值
用 Roslyn Scripting 运行单行/多行 C# 表达式
真正可行的路径是引入 Microsoft.CodeAnalysis.Scripting 库,用 CSharpScript.EvaluateAsync(单表达式)或 CSharpScript.RunAsync(多语句+变量导出)在宿主进程内即时编译执行。这不是调系统命令,而是嵌入式脚本引擎。
- 需提前准备一个控制台宿主程序(如
script-runner.exe),引用Microsoft.CodeAnalysis.Scripting和必要程序集(System,System.Linq,System.Text.Json等) - 脚本内容从标准输入读取,或通过参数传入,例如:
script-runner.exe "DateTime.Now.AddDays(7)" - 关键点:必须显式添加引用和导入命名空间,否则
List<int>、JsonSerializer等类型一律报"Cannot resolve symbol" - 示例脚本上下文构造:
var options = ScriptOptions.Default
.WithReferences(typeof(Console).Assembly, typeof(JsonSerializer).Assembly)
.WithImports("System", "System.Text.Json");然后传给 CSharpScript.EvaluateAsync("JsonSerializer.Serialize(new { a = 1 })", options)
NppExec 如何安全调用 Roslyn 脚本宿主
不能让 NppExec 直接跑 csc 或 dotnet,而应指向你写的 script-runner.exe,并确保它能接收当前文件内容或选中文本作为输入源。
- 在 NppExec 控制台(F6)中写:
NPP_SAVE cmd /c script-runner.exe "<$(FULL_CURRENT_PATH)"
其中 <$(FULL_CURRENT_PATH) 表示将当前文件内容重定向为标准输入;若只想运行选中代码,改用 script-runner.exe "$(SELECTED_TEXT)"
- 务必关闭 NppExec 的 “Follow $(CURRENT_DIRECTORY)” 选项——因为
script-runner.exe是独立程序,工作目录由它自己控制,不需要 Notepad++ 强制切换 - 如果脚本里用了第三方 NuGet 类型(如
Newtonsoft.Json),必须把对应 DLL 放到script-runner.exe同目录,并在WithReferences中显式加载Assembly.LoadFrom("Newtonsoft.Json.dll") - 避免使用
await除非设置.WithLanguageVersion(LanguageVersion.CSharp11),否则默认只支持 C# 7.3
容易被忽略的兼容性陷阱
Roslyn Scripting 不是“开箱即用”的黑盒,每个环节都可能断链:宿主程序编译目标框架(.NET 6+)、脚本运行时版本(Microsoft.CodeAnalysis.* 主版本需匹配)、甚至 Windows 的 TLS 1.2 支持(影响 NuGet 包下载阶段)。最常卡住的地方不是语法,而是 Assembly.Load 失败或 ScriptOptions 配置遗漏——它不会告诉你缺了哪个命名空间,只会抛泛型异常。



















