关于C#:如何获取csc.exe路径?

How to get csc.exe path?

是否有方法获取最新.NET框架的csc.exe的路径?

文件通常位于:c:windowsmicrosoft.netframeworkvx.x.x x x中,但问题是可以安装多个版本+32位和64位版本。

有什么解决办法吗?


C:windowsmicrosoft.netframeworkvx.x.x x x应包含最新的32位版本的csc.exe

C:windowsmicrosoft.netframework64vx.x.x x x应包含csc.exe的最新64位版本。

不管怎样,这就是我要的。

顺便说一句:您可以通过使用程序文件中的Visual Studio工具文件夹中的Visual Studio命令行来访问这两个文件。它会自动设置使用CSC编译器构建32位和64位应用程序所需的所有路径。


找到csc.exe路径的最佳方法是在cli(命令行解释器)中运行以下简单行:

1
dir /s %WINDIR%\CSC.EXE

dir-显示目录

/S-包括子文件夹

%windir%csc.exe-在根文件夹中查找类似"csc.exe"的短语。

这是我们的结果:enter image description here

然后我们可以简单地一行一行地编译示例代码,如下所示:

1
C:\WINDOWS\...\v.4.0.30319\CSC.exe HelloWorld.cs

当做。


您可以使用System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory()

1
2
3
4
5
6
using System.Runtime.InteropServices;
var frameworkPath = RuntimeEnvironment.GetRuntimeDirectory();
var cscPath = Path.Combine(frameworkPath,"csc.exe");

Console.WriteLine(frameworkPath);  // C:\Windows\Microsoft.NET\Framework\v4.0.30319
Console.WriteLine(cscPath); }      // C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe

更新:

打开命令提示符或PowerShell并运行以下命令列出安装的不同.NET框架版本的编译器的完整路径。

dir %WINDIR%\Microsoft.NET\Framework64\csc.exe /s/b

CSC路径如下:

C:程序文件msbuild\bin

例如:如果您使用的是Visual Studio 2013,它将是12.0。


如果已经安装了Visual Studio,只需:单击"开始",指向"所有程序",指向"Microsoft Visual Studio",指向"Visual Studio工具",然后单击"Visual Studio命令提示"。在这里,您有自己的命令行框,您可以在其中编译如下:

1
csc PathToYourCsSource


我假设您想使用csc.exe来编译文件,这就是您要求路径的原因。您可以使用我创建的以下小批处理脚本来获取可用的最新csc.exe的路径,而不是为此目的查看注册表:

1
2
3
4
5
6
7
8
9
10
11
12
@echo off
set dotNetBase=%SystemRoot%\Microsoft.NET\Framework\
rem get latest .net path containing csc.exe:
set dotNet20=%dotNetBase%v2.0.50727\
set dotNet35=%dotNetBase%v3.5\
set dotNet40=%dotNetBase%v4.0.30319\
if exist %dotNet20%nul set dotNet=%dotNet20%
if exist %dotNet35%nul set dotNet=%dotNet35%
if exist %dotNet40%nul set dotNet=%dotNet40%
set outPath=%~DP1
set outFileName=%~n1
"%dotNet%csc.exe" /t:exe /out:%outPath%%outFileName%.exe %1

将其保存为CompileCS.cmd,并将其与您的*.cs文件放在同一路径中。然后您可以简单地编译它,如下所示:

CompileCS GetDotNetVersion.cs

它将编译控制台应用程序getdotnetversion,这是一个确定已安装.NET版本的程序,我在这里发布了它。

提示:如果要在编译后自动运行C应用程序,请在批处理脚本的末尾添加
%outPath%%outFileName%.exe

该脚本检查.NET 2.0.x、3.5和4.0.30319的系统目录是否存在-在其他文件夹中,我从未见过csc.exe。因为它执行从最旧版本到最新版本的检查,所以变量dotNet包含最新的现有路径。

注意

  • Microsoft将.NET的所有4.x版本(包括最新版本4.7.1)存储在文件夹4.0.30319中。因此,如果安装了.NET 4.x的任何版本,您将在那里找到它。

  • 如果您需要64位版本而不是32位版本,那么只需在环境变量EDOCX1(脚本的第2行)中将Framework替换为Framework64

  • 虽然csc.exe仍然存在,但它仅限于C版本5(每次调用csc.exe时都会收到此警告)。但是对于许多小的有用的控制台应用程序,C 5仍然可以。如果您需要更高版本(C 6或7),那么您将需要Visual Studio或访问Roslyn Github区域以获取Roslyn编译器源代码。


微软最近很好地记录了这一点-请查看此处

The csc.exe executable file usually is located in the
Microsoft.NET\Framework\ folder under the Windows directory.
Its location might vary depending on the exact configuration of a
particular computer. If more than one version of the .NET Framework is
installed on your computer, you'll find multiple versions of this
file.


亡灵术。
这是他们在ReportViewer中的操作方式:

1
2
3
4
5
6
7
8
string compilerDirectory = System.IO.Path.Combine(
System.Environment.GetEnvironmentVariable("windir")
,"Microsoft.NET\\Framework" + (System.Environment.Is64BitProcess ?"64" :"")
, System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion());

C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319
"C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319\vbc.exe"
"C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319\csc.exe"

但是在2018年,您最好使用Roslyn内置编译器:

这里有一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
         protected override System.CodeDom.Compiler.CompilerResults FromFileBatch(System.CodeDom.Compiler.CompilerParameters options, string[] fileNames)
        {

#if NETSTANDARD2_0
            return NetStandardFromFileBatch(options, fileNames);
#else
            return OldFromFileBatch(options, fileNames);
#endif
        }




#if NETSTANDARD2_0        



        protected System.CodeDom.Compiler.CompilerResults NetStandardFromFileBatch(System.CodeDom.Compiler.CompilerParameters options, string[] fileNames)
        {
            //// C:\Program Files\dotnet\sdk\2.0.0
oslyn

            //string sysver = System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion();
            //System.Console.WriteLine(sysver);


            //string pf64 = System.Environment.ExpandEnvironmentVariables("%ProgramW6432%");
            //string pf32 = System.Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%");
            //string pf = pf32;

            //if (System.IntPtr.Size * 8 == 64)
            //    pf = pf64;

            //// compilerDirectory = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFiles);
            ////compilerDirectory = System.IO.Path.Combine(compilerDirectory,"dotnet","sdk","2.0.0","Roslyn");
            //compilerDirectory = System.IO.Path.Combine(pf32,"MSBuild","14.0","Bin");
            //if (System.IntPtr.Size * 8 == 64)
            //    compilerDirectory = System.IO.Path.Combine(compilerDirectory,"amd64");

            string assemblyName = System.IO.Path.GetFileNameWithoutExtension(options.OutputAssembly);

            Microsoft.CodeAnalysis.SyntaxTree[] syntaxTrees = new Microsoft.CodeAnalysis.SyntaxTree[fileNames.Length];

            for (int i = 0; i < fileNames.Length; ++i)
            {
                string fileContent = System.IO.File.ReadAllText(fileNames[i], System.Text.Encoding.UTF8);

                Microsoft.CodeAnalysis.VisualBasic.VisualBasicParseOptions op = null;

                // ERR_EncodinglessSyntaxTree = 37236 - Encoding must be specified...
                syntaxTrees[i] = Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxTree.ParseText(
                    fileContent, op, fileNames[i], System.Text.Encoding.UTF8
                );

            }

            Microsoft.CodeAnalysis.MetadataReference[] references =
                new Microsoft.CodeAnalysis.MetadataReference[options.ReferencedAssemblies.Count];

            for (int i = 0; i < references.Length; ++i)
            {
                references[i] = Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(
                    options.ReferencedAssemblies[i]
                );
            }



            Microsoft.CodeAnalysis.VisualBasic.VisualBasicCompilationOptions co =
                new Microsoft.CodeAnalysis.VisualBasic.VisualBasicCompilationOptions
            (
                Microsoft.CodeAnalysis.OutputKind.DynamicallyLinkedLibrary
            );

            co.WithOptionStrict(Microsoft.CodeAnalysis.VisualBasic.OptionStrict.Off);
            co.WithOptionExplicit(false);
            co.WithOptionInfer(true);

            Microsoft.CodeAnalysis.Compilation compilation = Microsoft.CodeAnalysis.VisualBasic.VisualBasicCompilation.Create(
                assemblyName,
                syntaxTrees,
                references,
                co
            );


            System.CodeDom.Compiler.CompilerResults compilerResults = new System.CodeDom.Compiler.CompilerResults(options.TempFiles);

            compilerResults.NativeCompilerReturnValue = -1;

            // using (var dllStream = new System.IO.MemoryStream())
            using (System.IO.FileStream dllStream = System.IO.File.Create(options.OutputAssembly))
            {
                using (System.IO.MemoryStream pdbStream = new System.IO.MemoryStream())
                {
                    Microsoft.CodeAnalysis.Emit.EmitResult emitResult = compilation.Emit(dllStream, pdbStream);
                    if (!emitResult.Success)
                    {

                        foreach (Microsoft.CodeAnalysis.Diagnostic diagnostic in emitResult.Diagnostics)
                        {
                            // options.TreatWarningsAsErrors
                            if (diagnostic.IsWarningAsError || diagnostic.Severity == Microsoft.CodeAnalysis.DiagnosticSeverity.Error)
                            {
                                string errorNumber = diagnostic.Id;
                                string errorMessage = diagnostic.GetMessage();

                                string message = $"{errorNumber}: {errorMessage};";
                                string fileName = diagnostic.Location.SourceTree.FilePath;

                                Microsoft.CodeAnalysis.FileLinePositionSpan lineSpan = diagnostic.Location.GetLineSpan();
                                string codeInQuestion = lineSpan.Path;
                                int line = lineSpan.StartLinePosition.Line;
                                int col = lineSpan.StartLinePosition.Character;

                                compilerResults.Errors.Add(
                                    new System.CodeDom.Compiler.CompilerError(fileName, line, col, errorNumber, errorMessage)
                                );
                            } // End if

                        } // Next diagnostic

                        // emitResult.Diagnostics
                        // CheckCompilationResult(emitResult);
                    }
                    else
                    {
                        compilerResults.PathToAssembly = options.OutputAssembly;
                        compilerResults.NativeCompilerReturnValue = 0;
                    }
                }
            }

            // compilerResults.CompiledAssembly = System.Reflection.Assembly.Load(array3, null);

            return compilerResults;
        }
#endif