可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Is there a way to get path for the latest .NET Framework's csc.exe?
The file usually in: c:\Windows\Microsoft.NET\Framework\vX.X.XXX but the problem is there can be multiple versions installed + there are both 32 and 64 bit versions.
Any solution to this?
回答1:
c:\Windows\Microsoft.NET\Framework\vX.X.XXX Should contain the latest 32 bit version of csc.exe
c:\Windows\Microsoft.NET\Framework64\vX.X.XXX Should contain the lastest 64 bit version of csc.exe
That's what it is for mine anyway.
BTW: You can access both by using the Visual Studio Command Line from your visual studio tools folder in your program files. It auto sets up all the paths you need to build 32 and 64 bit apps with your csc compiler.
回答2:
The best way to find CSC.exe path is running in CLI (Command Line Interpreter) that simple line:
dir /s %WINDIR%\CSC.EXE
dir - shows directory
/s - includes subfolders
%WINDIR%\CSC.EXE - looks in root folder for phrase like "CSC.exe".
And it is our result:
Then we can simply compile example code by line like:
C:\WINDOWS\...\v.4.0.30319\CSC.exe HelloWorld.cs
Regards.
回答3:
You can use System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory()
.
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
回答4:
Updated:
Open Command Prompt or Powershell and run the below command to list complete path of compilers for different .Net Frameworks version installed.
dir %WINDIR%\Microsoft.NET\Framework64\csc.exe /s/b
CSC Path is as follows:
C:\Program Files\MSBuild\\Bin
Ex: It will be 12.0, if you are using Visual Studio 2013.
回答5:
If you already installed Visual Studio, just:
Click Start, point to All Programs, point to Microsoft Visual Studio, point to Visual Studio Tools, and then click Visual Studio Command Prompt
and there you have your command line box where you compile as follows:
csc PathToYourCsSource
回答6:
Microsoft has documented this well recently - check here
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.
回答7:
I assume you want to use csc.exe
to compile files, that's why you were asking for the path. Rather than looking into the registry for this purpose you can use the following little batch script I have created to get the path to the latest csc.exe available:
@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
Save it as CompileCS.cmd
and put it in the same path as your *.cs files. Then you can simply compile it as follows:
CompileCS GetDotNetVersion.cs
Which will compile the console application GetDotNetVersion, a program to determine the installed .NET versions, which I've published here.
Hint: If you want to run the C# application automatically after compilation, add
%outPath%%outFileName%.exe
to the end of the batch script.
The script checks for existence of the system directories for .NET 2.0.x, 3.5 and 4.0.30319 - in other folders I have never seen csc.exe. Because it does the check from the oldest to the newest version, the variable dotNet
contains the latest existing path.
Note that
Microsoft stores all the 4.x versions of .NET - including the latest version 4.7.1 - in the folder 4.0.30319. Because of that, if any version of .NET 4.x is installed, you will find it there.
If you need the 64 bit version rather than the 32 bit version then simply replace Framework
by Framework64
in the environment variable dotNetBase
(2nd line of the script).
While csc.exe
still exists, it is restricted to C# version 5 (you will get this warning each time you invoke csc.exe). But for many little useful console applications, C#5 is still fine. If you need a higher version (C#6 or 7), then you'll need either Visual Studio or you can visit the Roslyn GitHub area to get the Roslyn compiler source code.
回答8:
Necromancing.
This is how they do it in ReportViewer:
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"
But in 2018, you'd be better off using the roslyn built-in compiler:
Here an example:
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\Roslyn
//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