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

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

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

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

Ответ 1

Обновление: этот ответ больше не работает. Из-за множества различных фреймворков, которые Microsoft теперь отправляет, а также распространения различных версий Visual Studio и различных SDK, я не думаю, что есть еще один окончательный ответ на этот вопрос.

Один ключ к разумному ответу можно найти здесь. Вы можете перечислять установленные версии .NET Framework из реестра под HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP (для версий 1.1 и далее, я думаю). Под каждым ключом (или подраздел профиля, в случае 4.0) вы найдете InstallPath, который укажет на место установки фреймворка. Вам нужно будет перечислить все подразделы под NDP и перевести каждый в номер версии, а затем найти последнюю. Чтобы обнаружить 32-разрядные версии, запущенные в 64-разрядном режиме в 64-разрядной ОС, вам нужно будет найти в реестре эквивалентные места в разделе Wow6432Node.

Все это немного уродливо, но, возможно, это единственный надежный способ сделать это.

Ответ 2

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

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

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

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

Ответ 3

Лучший способ найти 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

С уважением.

Ответ 4

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

Ответ 5

Обновлено:

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

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

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

C:\Program Files\MSBuild\\Bin

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

Ответ 6

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

csc PathToYourCsSource

Ответ 7

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

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

Ответ 8

Я предполагаю, что вы хотите использовать 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, которые я опубликовал здесь.

Подсказка: Если вы хотите автоматически запускать приложение С# после компиляции, добавьте
%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 все еще существует, он ограничен С# версия 5 (вы будете получать это предупреждение при каждом запуске csc.exe). Но для многих маленьких полезных консольных приложений С# 5 все еще хорош. Если вам нужна более высокая версия (С# 6 или 7), то вам понадобится либо Visual Studio, либо вы можете посетить область GlyHub Roslyn, чтобы получить исходный код компилятора Roslyn.

Ответ 9

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

Ответ 10

@echo off
for /R "%SYSTEMROOT%\Microsoft.NET\Framework" %%i in (csc.*exe) do set CSC=%%~i
"%CSC%" /nologo /target:winexe "HelloWorld.cs"