Как получить путь csc.exe?

Есть ли способ получить путь к csc.exe последней версии.NET Framework?

Файл обычно находится в: c:\Windows\Microsoft.NET\Framework\vX.X.XXX, но проблема в том, что может быть установлено несколько версий + существуют как 32-, так и 64-разрядные версии.

Любое решение этого?

10 ответов

c:\Windows\Microsoft.NET\Framework\vX.X.XXX Должен содержать последнюю 32-битную версию csc.exe

c: \ Windows \ Microsoft.NET \ Framework64 \ vX.X.XXX Должен содержать последнюю 64-битную версию csc.exe

Это то, что это для меня в любом случае.

Кстати: вы можете получить доступ к обоим с помощью командной строки Visual Studio из папки инструментов Visual Studio в ваших программных файлах. Он автоматически устанавливает все пути, необходимые для создания 32- и 64-битных приложений с помощью компилятора csc.

Лучший способ найти путь CSC.exe - запустить в CLI (интерпретаторе командной строки) следующую простую строку:

dir /s %WINDIR%\CSC.EXE

dir - показывает каталог

/ s - включает подпапки

%WINDIR%\CSC.EXE - ищет в корневой папке фразу вроде "CSC.exe".

И это наш результат: введите описание изображения здесь

Затем мы можем просто скомпилировать пример кода построчно, например:

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

С уважением.

Ты можешь использовать 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

Обновлено:

Откройте командную строку или Powershell и выполните приведенную ниже команду, чтобы просмотреть полный путь к компиляторам для другой установленной версии.Net Frameworks.

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

Путь CSC выглядит следующим образом:

C: \ Program Files \ MSBuild \\ Bin

Пример: это будет 12.0, если вы используете Visual Studio 2013.

Я полагаю, вы хотите использовать csc.exe для компиляции файлов, поэтому вы просили путь. Вместо того, чтобы заглядывать в реестр для этой цели, вы можете использовать следующий небольшой пакетный скрипт, который я создал, чтобы получить путь к последнему доступному csc.exe:

@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 хранит все версии 4.x.NET, включая последнюю версию 4.7.1, в папке 4.0.30319. Из-за этого, если установлена ​​какая-либо версия.NET 4.x, вы найдете ее там.

  • Если вам нужна 64-битная версия, а не 32-битная, просто замените Framework от Framework64 в переменной среды dotNetBase (2-я строка сценария).

  • В то время как csc.exe все еще существует, он ограничен C# версии 5 (вы будете получать это предупреждение при каждом запуске csc.exe). Но для многих небольших полезных консольных приложений C#5 все еще хорош. Если вам нужна более высокая версия (C#6 или 7), то вам понадобится либо Visual Studio, либо вы можете посетить область Roslyn GitHub, чтобы получить исходный код компилятора Roslyn.

В командной строке разработчика выполните команду:

where csc

Вы получаете путь к csc который устанавливается с Visual Studio и net4, например:

C:\Program Files\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\Roslyn\csc.exe
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe

Если вы уже установили Visual Studio, просто: нажмите кнопку "Пуск", выберите "Все программы", "Microsoft Visual Studio", "Инструменты Visual Studio", а затем нажмите "Командная строка Visual Studio", и у вас появится окно командной строки, в котором вы компилируете следующее:

csc PathToYourCsSource

Microsoft недавно задокументировала это хорошо - проверьте здесь

Исполняемый файл csc.exe обычно находится в папке Microsoft.NET\Framework\ в каталоге Windows. Его местоположение может отличаться в зависимости от точной конфигурации конкретного компьютера. Если на вашем компьютере установлено более одной версии.NET Framework, вы найдете несколько версий этого файла.

Necromancing.
Вот как они делают это в 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" 

Но в 2018 году вам лучше использовать встроенный компилятор Roslyn:

Вот пример:

         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

Более простой способ использования csc.exe в командной строке — запуск следующего get_csc.bat. Вы можете запустить csc.exe, %CSC_PATH%.

      @FOR /f "usebackq" %%A IN (`powershell join-path ^([Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory^(^)^)  csc.exe`) DO @SET CSC_PATH=%%A
Другие вопросы по тегам