三谈 C# 交互窗口

时间:2022-08-31 07:58:00

mono 2.8.1 中和 csharp.exe 和 Mono.CSharp.dll 相关的 C# 源程序总共只有六十个左右,分布在以下目录中:

三谈 C# 交互窗口

 

Mono.CSharp.dll 需要以下57个 C# 源文件:

..\..\mcs\anonymous.cs
..\..\mcs\argument.cs
..\..\mcs\assign.cs
..\..\mcs\attribute.cs
..\..\mcs\cs-tokenizer.cs
..\..\mcs\cfold.cs
..\..\mcs\class.cs
..\..\mcs\codegen.cs
..\..\mcs\complete.cs
..\..\mcs\const.cs
..\..\mcs\constant.cs
..\..\mcs\convert.cs
..\..\mcs\context.cs
..\..\mcs\decl.cs
..\..\mcs\delegate.cs
..\..\mcs\doc.cs
..\..\mcs\doc-bootstrap.cs
..\..\mcs\driver.cs
..\..\mcs\dynamic.cs
..\..\mcs\ecore.cs
..\..\mcs\enum.cs
..\..\mcs\eval.cs
..\..\mcs\expression.cs
..\..\mcs\field.cs
..\..\mcs\flowanalysis.cs
..\..\mcs\generic.cs
..\..\mcs\import.cs
..\..\mcs\iterators.cs
..\..\mcs\lambda.cs
..\..\mcs\linq.cs
..\..\mcs\literal.cs
..\..\mcs\location.cs
..\..\mcs\membercache.cs
..\..\mcs\method.cs
..\..\mcs\modifiers.cs
..\..\mcs\namespace.cs
..\..\mcs\nullable.cs
..\..\mcs\parameter.cs
..\..\mcs\pending.cs
..\..\mcs\property.cs
..\..\mcs\report.cs
..\..\mcs\rootcontext.cs
..\..\mcs\roottypes.cs
..\..\mcs\statement.cs
..\..\mcs\support.cs
..\..\mcs\typemanager.cs
..\..\mcs\typespec.cs
..\..\mcs\visit.cs
..\..\mcs\symbolwriter.cs
..\..\class\Mono.CompilerServices.SymbolWriter\MonoSymbolFile.cs
..\..\class\Mono.CompilerServices.SymbolWriter\MonoSymbolTable.cs
..\..\class\Mono.CompilerServices.SymbolWriter\MonoSymbolWriter.cs
..\..\class\corlib\Mono.Security.Cryptography\CryptoConvert.cs
..\..\build\common\Consts.cs
..\..\tools\monop\outline.cs
..\..\mcs\cs-parser.cs
Assembly\AssemblyInfo.cs

这是 mcs/class/Mono.CSharp.dll.sources 文件的内容。注意在该文件中的目录分隔符原来是 Linux 操作系统的“/”,现在被我替换为 Windows 操作系统的“\”。

而 csharp.exe 只需要以下三个 C# 源文件:

..\..\class\corlib\Mono\DataConverter.cs
repl.cs
getline.cs

这是 mcs/tools/csharp/csharp.exe.sources 文件的内容。然后,参照上一篇随笔,在 mcs/tools/csharp/repl.cs 文件第 59 行后加入以下一句:

Console.WriteLine(ex);

现在,编辑以下 mak.cmd 文件用来编译:

@echo off
cd mcs\class\Mono.CSharp
csc -t:library -out:..\..\..\Mono.CSharp.dll -D:NET_4_0 @Mono.CSharp.dll.sources > ..\..\..\Mono.CSharp.txt
cd ..\..\tools\csharp
csc /unsafe -out:..\..\..\csharp.exe -D:ON_DOTNET -r:..\..\..\Mono.CSharp.dll @csharp.exe.sources > ..\..\..\csharp.exe.txt
cd ..\..\..
sn -R Mono.CSharp.dll mcs\class\mono.snk > sn.txt

编译和运行结果如下:

E:\CS\CsharpRepl\mono> mak

E:\CS\CsharpRepl\mono> csharp
System.TypeLoadException: 重写成员
“Mono.CSharp.StreamReportPrinter.Print(Mono.CSharp.AbstractMessage)”
时违反了继承安全性规则。重写方法的安全可访问性必须与所重写方法的安全可访问性匹配。
在 Mono.CSharp.Evaluator.InitAndGetStartupFiles(String[] args)
在 Mono.Driver.Startup(String[] args)

E:\CS\CsharpRepl\mono>

这和上一篇随笔中的出错情况一样。现在让我们在 mcs/class/Mono.CSharp/Assembly/AssemblyInfo.cs 文件文件中加入以下语句:

[assembly: SecurityRules(SecurityRuleSet.Level1)]

然后重新编译,运行:

E:\CS\CsharpRepl\mono> mak

E:\CS\CsharpRepl\mono> csharp --version
Mono C# compiler version 4.0.0.0

E:\CS\CsharpRepl\mono> csharp
Mono C# Shell, type "help;" for help

Enter statements below.
csharp> Environment.OSVersion;
Microsoft Windows NT 6.0.6002 Service Pack 2
csharp> Environment.Version;
4.0.30319.1
csharp> quit;

E:\CS\CsharpRepl\mono>

终于在 Windows 操作系统下实现了 C# 交互窗口,并且没有安装 mono,而是只需要 Mono.CSharp.dll 和 csharp.exe 两个文件就可以了。

此外,还可以将 Mono.CSharp.dll 加入到全局程序集缓存中(需要管理员权限):

E:\CS\CsharpRepl\mono> gacutil /i Mono.CSharp.dll
Microsoft (R) .NET Global Assembly Cache Utility. Version 4.0.30319.1
版权所有(C) Microsoft Corporation。保留所有权利。

程序集已成功添加到缓存中

E:\CS\CsharpRepl\mono> gacutil /l Mono.CSharp
Microsoft (R) .NET Global Assembly Cache Utility. Version 4.0.30319.1
版权所有(C) Microsoft Corporation。保留所有权利。

全局程序集缓存包含下列程序集:
Mono.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL

项目数 = 1

E:\CS\CsharpRepl\mono>

这样之后再将 csharp.exe 放到 PATH 中的目录里,就可以随时随处运行 C# 交互窗口了。