성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] Reordering on an Alpha processor ;...
[정성태] 공유 감사합니다. ^^ 참고로, WPF에서 WindowsF...
[Tom Lee] 답변 감사합니다. 나름의 해결책 연구해보고 여기에도 공유해봅니다...
[정성태] 아래의 글을 보면, MoveWindow 하면 될 듯한데요. ^^...
[Tom Lee] 안녕하세요 올려주신 글 참고하여 WPF 어플리케이션 안에 Uni...
[정성태] A graphical depiction of the steps ...
[정성태] 질문을 주셔서 출판사 측에 문의를 했습니다. 약 한 달 정도 후...
[Thorondor
] @정성태 개인 블로그인데도 거의 커뮤니티 급 인 것 같아요. 요...
[정성태] Roll A Lisp In C - Reading ; https...
[정성태] Java - How to use the Foreign Funct...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>.NET Core/5+ 환경에서 (프로젝트가 아닌) C# 코드 파일을 입력으로 컴파일하는 방법 - 두 번째 이야기</h1> <p> 예전에 이에 대해 한 번 설명했는데요,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > .NET Core 환경에서 (프로젝트가 아닌) C# 코드 파일을 입력으로 컴파일하는 방법 ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12034'>https://www.sysnet.pe.kr/2/0/12034</a> </pre> <br /> 이후 .NET Core 2.2.2 SDK부터 배포되는 Roslyn 컴파일러에는 실행 파일 유형의 csc.exe가 누락되고 csc.dll로만 배포가 돼 위의 내용을 실습할 수 없습니다.<br /> <br /> 물론, csc.dll은 기존 csc.exe의 DLL 버전이므로 다음과 같은 식으로 직접 실행하는 것도 가능합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > // .NET 6 SDK가 설치된 경우 (버전 6.0.302) c:\temp> <span style='color: blue; font-weight: bold'>dotnet "C:\Program Files\dotnet\sdk\6.0.302\Roslyn\bincore\csc.dll"</span> Microsoft (R) Visual C# Compiler version 4.2.0-4.22220.5 (432d17a8) Copyright (C) Microsoft Corporation. All rights reserved. warning CS2008: No source files specified. error CS1562: Outputs without source must have the /out option specified </pre> <br /> 테스트를 위해 예제 C# 파일을 하나 만들고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > // c:\temp\test.cs 파일로 저장되었다고 가정 using System; namespace ConsoleApp1 { class Program { static void Main(string[] args) { Console.WriteLine("Hello World"); } } } </pre> <br /> 빌드해 볼까요? ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > c:\temp> <span style='color: blue; font-weight: bold'>dotnet "C:\Program Files\dotnet\sdk\6.0.302\Roslyn\bincore\csc.dll" test.cs</span> Microsoft (R) Visual C# Compiler version 4.2.0-4.22220.5 (432d17a8) Copyright (C) Microsoft Corporation. All rights reserved. test.cs(1,7): error CS0246: The type or namespace name 'System' could not be found (are you missing a using directive or an assembly reference?) test.cs(5,11): error CS0518: Predefined type 'System.Object' is not defined or imported test.cs(7,26): error CS0518: Predefined type 'System.String' is not defined or imported test.cs(7,16): error CS0518: Predefined type 'System.Void' is not defined or imported </pre> <br /> 아쉽게도, 가장 기본적인 System.Object 타입을 정의한 어셈블리조차도 참조를 해주지 않으므로 직접 명령행에 해당 DLL을 함께 전달해야 합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > // 옵션 추가 // -r:"C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.7\System.Private.CoreLib.dll" c:\temp> <span style='color: blue; font-weight: bold'>dotnet "C:\Program Files\dotnet\sdk\6.0.302\Roslyn\bincore\csc.dll" test.cs -r:"C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.7\System.Private.CoreLib.dll"</span> Microsoft (R) Visual C# Compiler version 4.2.0-4.22220.5 (432d17a8) Copyright (C) Microsoft Corporation. All rights reserved. test.cs(10,13): error CS0234: The type or namespace name 'Console' does not exist in the namespace 'System' (are you missing an assembly reference?) </pre> <br /> 음... Console 타입 역시 System.Console.dll로 분리돼 있으므로 이렇게 한 번 더 참조 추가를 해야 합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > // 옵션 추가 // -r:"C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.7\System.Console.dll" c:\temp> <span style='color: blue; font-weight: bold'>dotnet "C:\Program Files\dotnet\sdk\6.0.302\Roslyn\bincore\csc.dll" test.cs -r:"C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.7\System.Private.CoreLib.dll" -r:"C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.7\System.Console.dll"</span> Microsoft (R) Visual C# Compiler version 4.2.0-4.22220.5 (432d17a8) Copyright (C) Microsoft Corporation. All rights reserved. test.cs(10,28): error CS0012: The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. test.cs(10,13): error CS0012: The type 'Decimal' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. </pre> <br /> 하지만 ^^; 그래도 오류가 나는군요. 근데 오류 메시지가 잘 이해가 안 됩니다. System.Object의 실제 구현은 System.Private.CoreLib.dll에 있는 것이 맞고, System.Runtime의 경우에는 TypeForwardedTo를 이용해 System.Private.CoreLib.dll의 구현체를 가리키는 형태입니다.<br /> <br /> 따라서 원칙대로라면 System.Private.CoreLib.dll을 직접 참조하면 사실상 System.Runtime.dll의 참조는 필요하지 않습니다. (혹시 이에 대한 규칙을 아시는 분은 덧글 부탁드립니다. ^^)<br /> <br /> 암튼, 오류 메시지가 그러하니... 참조 추가를 하면 이제 컴파일이 잘 됩니다. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > // 옵션 추가 // -r:"C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.7\System.Runtime.dll" c:\temp> <span style='color: blue; font-weight: bold'>dotnet "C:\Program Files\dotnet\sdk\6.0.302\Roslyn\bincore\csc.dll" test.cs -r:"C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.7\System.Private.CoreLib.dll" -r:"C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.7\System.Console.dll" -r:"C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.7\System.Runtime.dll"</span> Microsoft (R) Visual C# Compiler version 4.2.0-4.22220.5 (432d17a8) Copyright (C) Microsoft Corporation. All rights reserved. </pre> <br /> <hr style='width: 50%' /><br /> <br /> 자... 이렇게 해서 test.exe가 생성되었고, 이를 실행해 보면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > c:\temp> <span style='color: blue; font-weight: bold'>test.exe</span> Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' or one of its dependencies. The system cannot find the file specified. </pre> <br /> System.Private.CoreLib.dll이 같은 디렉터리에 없어 오류가 발생합니다. 그래서 해당 DLL을 복사해 둔 후 실행하면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > c:\temp> <span style='color: blue; font-weight: bold'>test.exe</span> Unhandled Exception: System.TypeLoadException: Could not load type 'System.Object' from assembly 'System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' because the parent does not exist. </pre> <br /> 이번엔 파일이 아닌, Type을 로드할 수 없다는 오류 메시지가 나옵니다. 딱히 더 해볼 것이 없군요. ^^;<br /> <br /> 그럼, dotnet 실행 파일을 경유해 실행해 볼까요?<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > c:\temp> <span style='color: blue; font-weight: bold'>dotnet test.exe</span> A fatal error was encountered. The library 'hostpolicy.dll' required to execute the application was not found in 'c:\temp\'. Failed to run as a self-contained app. - The application was run as a self-contained app because 'c:\temp\test.runtimeconfig.json' was not found. - If this should be a framework-dependent app, add the 'c:\temp\test.runtimeconfig.json' file and specify the appropriate framework. </pre> <br /> test.runtimeconfig.json 파일이 없다고 하는데, 이것만 다음의 내용으로 test.exe와 동일한 폴더에 "test.runtimeconfig.json" 파일명으로 넣어주면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > { "runtimeOptions": { "tfm": "netcoreapp6.0", "framework": { "name": "Microsoft.NETCore.App", "version": "6.0.0" } } } </pre> <br /> 이제서야 정상적으로 프로그램이 실행됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > c:\temp> <span style='color: blue; font-weight: bold'>dir /b</span> test.cs <span style='color: blue; font-weight: bold'>test.exe test.runtimeconfig.json</span> c:\temp> <span style='color: blue; font-weight: bold'>dotnet test.exe</span> Hello World </pre> <br /> <hr style='width: 50%' /><br /> <br /> 재미있는 건, csc.dll이 생성한 EXE 파일의 "Runtime" 대상이 ".NET Framework 4"라는 점입니다. 즉, 위에서 dotnet을 경유해 실행했을 때 ".NET Framework 4" 바이너리였어도 정상적으로 실행했던 것입니다.<br /> <br /> 바이너리의 Runtime 대상을 바꾸려면 C# 소스 코드 파일에서 <a target='tab' href='https://docs.microsoft.com/en-us/dotnet/api/system.runtime.versioning.targetframeworkattribute'>TargetFrameworkAttribute 특성</a>을 이용해 선택할 수 있습니다. 예를 들어 우리가 만든 예제의 경우 다음과 같이 추가하면 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > using System; using System.Runtime.Versioning; <span style='color: blue; font-weight: bold'>[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]</span> namespace ConsoleApp1 { class Program { static void Main(string[] args) { // 문자열 출력 System.Console.WriteLine("Hello World"); } } } </pre> <br /> <hr style='width: 50%' /><br /> <br /> 참고로, 아래는 csc.dll의 /help 출력 결과입니다.<br /> <br /> <pre style='height: 400px; margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > c:\temp> <span style='color: blue; font-weight: bold'>dotnet "C:\Program Files\dotnet\sdk\6.0.302\Roslyn\bincore\csc.dll" /help</span> Microsoft (R) Visual C# Compiler version 4.2.0-4.22220.5 (432d17a8) Copyright (C) Microsoft Corporation. All rights reserved. Visual C# Compiler Options - OUTPUT FILES - -out:<file> Specify output file name (default: base name of file with main class or first file) -target:exe Build a console executable (default) (Short form: -t:exe) -target:winexe Build a Windows executable (Short form: -t:winexe) -target:library Build a library (Short form: -t:library) -target:module Build a module that can be added to another assembly (Short form: -t:module) -target:appcontainerexe Build an Appcontainer executable (Short form: -t:appcontainerexe) -target:winmdobj Build a Windows Runtime intermediate file that is consumed by WinMDExp (Short form: -t:winmdobj) -doc:<file> XML Documentation file to generate -refout:<file> Reference assembly output to generate -platform:<string> Limit which platforms this code can run on: x86, Itanium, x64, arm, arm64, anycpu32bitpreferred, or anycpu. The default is anycpu. - INPUT FILES - -recurse:<wildcard> Include all files in the current directory and subdirectories according to the wildcard specifications -reference:<alias>=<file> Reference metadata from the specified assembly file using the given alias (Short form: -r) -reference:<file list> Reference metadata from the specified assembly files (Short form: -r) -addmodule:<file list> Link the specified modules into this assembly -link:<file list> Embed metadata from the specified interop assembly files (Short form: -l) -analyzer:<file list> Run the analyzers from this assembly (Short form: -a) -additionalfile:<file list> Additional files that don't directly affect code generation but may be used by analyzers for producing errors or warnings. -embed Embed all source files in the PDB. -embed:<file list> Embed specific files in the PDB. - RESOURCES - -win32res:<file> Specify a Win32 resource file (.res) -win32icon:<file> Use this icon for the output -win32manifest:<file> Specify a Win32 manifest file (.xml) -nowin32manifest Do not include the default Win32 manifest -resource:<resinfo> Embed the specified resource (Short form: -res) -linkresource:<resinfo> Link the specified resource to this assembly (Short form: -linkres) Where the resinfo format is <file>[,<string name>[,public|private]] - CODE GENERATION - -debug[+|-] Emit debugging information -debug:{full|pdbonly|portable|embedded} Specify debugging type ('full' is default, 'portable' is a cross-platform format, 'embedded' is a cross-platform format embedded into the target .dll or .exe) -optimize[+|-] Enable optimizations (Short form: -o) -deterministic Produce a deterministic assembly (including module version GUID and timestamp) -refonly Produce a reference assembly in place of the main output -instrument:TestCoverage Produce an assembly instrumented to collect coverage information -sourcelink:<file> Source link info to embed into PDB. - ERRORS AND WARNINGS - -warnaserror[+|-] Report all warnings as errors -warnaserror[+|-]:<warn list> Report specific warnings as errors (use "nullable" for all nullability warnings) -warn:<n> Set warning level (0 or higher) (Short form: -w) -nowarn:<warn list> Disable specific warning messages (use "nullable" for all nullability warnings) -ruleset:<file> Specify a ruleset file that disables specific diagnostics. -errorlog:<file>[,version=<sarif_version>] Specify a file to log all compiler and analyzer diagnostics. sarif_version:{1|2|2.1} Default is 1. 2 and 2.1 both mean SARIF version 2.1.0. -reportanalyzer Report additional analyzer information, such as execution time. -skipanalyzers[+|-] Skip execution of diagnostic analyzers. - LANGUAGE - -checked[+|-] Generate overflow checks -unsafe[+|-] Allow 'unsafe' code -define:<symbol list> Define conditional compilation symbol(s) (Short form: -d) -langversion:? Display the allowed values for language version -langversion:<string> Specify language version such as `latest` (latest version, including minor versions), `default` (same as `latest`), `latestmajor` (latest version, excluding minor versions), `preview` (latest version, including features in unsupported preview), or specific versions like `6` or `7.1` -nullable[+|-] Specify nullable context option enable|disable. -nullable:{enable|disable|warnings|annotations} Specify nullable context option enable|disable|warnings|annotations. - SECURITY - -delaysign[+|-] Delay-sign the assembly using only the public portion of the strong name key -publicsign[+|-] Public-sign the assembly using only the public portion of the strong name key -keyfile:<file> Specify a strong name key file -keycontainer:<string> Specify a strong name key container -highentropyva[+|-] Enable high-entropy ASLR - MISCELLANEOUS - @<file> Read response file for more options -help Display this usage message (Short form: -?) -nologo Suppress compiler copyright message -noconfig Do not auto include CSC.RSP file -parallel[+|-] Concurrent build. -version Display the compiler version number and exit. - ADVANCED - -baseaddress:<address> Base address for the library to be built -checksumalgorithm:<alg> Specify algorithm for calculating source file checksum stored in PDB. Supported values are: SHA1 or SHA256 (default). -codepage:<n> Specify the codepage to use when opening source files -utf8output Output compiler messages in UTF-8 encoding -main:<type> Specify the type that contains the entry point (ignore all other possible entry points) (Short form: -m) -fullpaths Compiler generates fully qualified paths -filealign:<n> Specify the alignment used for output file sections -pathmap:<K1>=<V1>,<K2>=<V2>,... Specify a mapping for source path names output by the compiler. -pdb:<file> Specify debug information file name (default: output file name with .pdb extension) -errorendlocation Output line and column of the end location of each error -preferreduilang Specify the preferred output language name. -nosdkpath Disable searching the default SDK path for standard library assemblies. -nostdlib[+|-] Do not reference standard library (mscorlib.dll) -subsystemversion:<string> Specify subsystem version of this assembly -lib:<file list> Specify additional directories to search in for references -errorreport:<string> Specify how to handle internal compiler errors: prompt, send, queue, or none. The default is queue. -appconfig:<file> Specify an application configuration file containing assembly binding settings -moduleassemblyname:<string> Name of the assembly which this module will be a part of -modulename:<string> Specify the name of the source module -generatedfilesout:<dir> Place files generated during compilation in the specified directory. </pre> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
1091
(왼쪽의 숫자를 입력해야 합니다.)