如何从记事本运行C#代码?能否通过挂钩代码实现无重启运行?
Hey there! Let's tackle your C# code running and dynamic update questions one by one—here are practical, actionable solutions tailored to your needs:
You don’t need VS to run your C# code—there are two straightforward ways:
- Use the .NET CLI (modern approach):
If your code is part of a console app or library, create a .NET project withdotnet new console, drop your .cs files into the project folder, then rundotnet runto execute it, ordotnet buildto compile into an executable/DLL. - Direct compilation with
csc.exe:
For standalone .cs files, open a command prompt (make sure the .NET SDK is in your PATH), runcsc YourClass.cs—this will generateYourClass.exewhich you can run directly. If you’re building a library, add/target:libraryto get a DLL instead.
The core issue here is that C# is statically compiled by default—once your program is running, it can’t automatically pick up changes to .cs files. But you can solve this with dynamic compilation and runtime loading:
Key Tools & Approach
- Roslyn (.NET’s official compiler API): This is the recommended way to dynamically compile C# code at runtime. It’s more powerful and maintained than older tools like
CSharpCodeProvider. - FileSystemWatcher: Use this to monitor your .cs file for changes—when the file is updated, trigger a recompile and reload of the code.
- AppDomain Isolation (optional but useful): If you need to unload old versions of your code (to free memory or avoid conflicts), load the dynamically compiled assembly into a child
AppDomain—you can unload the entire domain later when updating.
Quick Example Code
First, add the Roslyn NuGet packages (Microsoft.CodeAnalysis.CSharp and Microsoft.CodeAnalysis.Common) to your main project.
Dynamic Code Loader
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using System; using System.IO; using System.Reflection; public class DynamicCodeLoader { public static object ReloadAndRun(string csFilePath, string className, string methodName) { try { // Read the latest code from the .cs file string code = File.ReadAllText(csFilePath); // Set up compilation options (build as a DLL) var compileOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary); // Create the compilation with necessary references (add more if your code uses other libraries) var compilation = CSharpCompilation.Create( Guid.NewGuid().ToString(), // Unique name to avoid caching syntaxTrees: new[] { CSharpSyntaxTree.ParseText(code) }, references: new[] { MetadataReference.CreateFromFile(typeof(object).Assembly.Location), MetadataReference.CreateFromFile(typeof(Console).Assembly.Location) }, options: compileOptions); // Compile to a memory stream using var ms = new MemoryStream(); var emitResult = compilation.Emit(ms); if (!emitResult.Success) { // Print compilation errors to debug foreach (var error in emitResult.Diagnostics) { Console.WriteLine($"Compilation Error: {error.GetMessage()}"); } return null; } // Load the compiled assembly from memory ms.Seek(0, SeekOrigin.Begin); Assembly updatedAssembly = Assembly.Load(ms.ToArray()); // Find the class and method, then invoke it Type targetClass = updatedAssembly.GetType(className); if (targetClass == null) { Console.WriteLine($"Couldn't find class: {className}"); return null; } object instance = Activator.CreateInstance(targetClass); MethodInfo targetMethod = targetClass.GetMethod(methodName); if (targetMethod == null) { Console.WriteLine($"Couldn't find method: {methodName}"); return null; } return targetMethod.Invoke(instance, null); } catch (Exception ex) { Console.WriteLine($"Error loading code: {ex.Message}"); return null; } } }
Main Program with Auto-Update
using System.IO; class Program { static void Main(string[] args) { string targetCsFile = @"C:\YourCodePath\YourAlgorithmClass.cs"; string className = "YourAlgorithmClass"; string methodToRun = "ExecuteAlgorithm"; // Set up a watcher to detect changes to the .cs file var fileWatcher = new FileSystemWatcher(Path.GetDirectoryName(targetCsFile)) { Filter = Path.GetFileName(targetCsFile), NotifyFilter = NotifyFilters.LastWrite, EnableRaisingEvents = true }; // Trigger reload when the file is updated fileWatcher.Changed += (sender, e) => { // Wait a bit to make sure the file is fully saved System.Threading.Thread.Sleep(200); Console.WriteLine("\nDetected code update—reloading..."); DynamicCodeLoader.ReloadAndRun(targetCsFile, className, methodToRun); }; // Run the code initially Console.WriteLine("Initial code run:"); DynamicCodeLoader.ReloadAndRun(targetCsFile, className, methodToRun); Console.WriteLine("\nWatching for code changes. Press any key to exit."); Console.ReadKey(); } }
Nope! Notepad is just a basic text editor—you can use any editor (VS Code, Notepad++, Sublime Text, etc.) to save your .cs files. The only requirement is that the file is saved as a plain text file with the .cs extension, encoded in UTF-8 (without BOM is safest for compilers).
What you’re describing (updating code without restarting) is exactly what the dynamic compilation approach above achieves—you’re essentially "hooking" into the main process to load new code at runtime. If you meant something like injecting code into an already running C# process, that’s more complex (usually involves debugging APIs or third-party tools), but for your use case, dynamic compilation is the cleanest and most maintainable solution.
内容的提问来源于stack exchange,提问作者Oat

