C# Winform 프로젝트에서 전역 전처리기가 있을까요?

안녕하세요 아직 배울게 많은 C# 초보입니다.

다름이 아니라 전처리기 관련해서 궁금한게 생겨서 글을 올립니다.

MFC 에서는 STDAFX.H 에서 고객사마다 전처리기를 이용해서 하나의 소스로 관리한 적이 있습니다.

ex)
stdafx.h 소스에서

#define 삼성전자_화성캠퍼스
//#define 삼성디스플레이_탕정

분기점이 필요한 코드

#ifdef 삼성전자_화성캠퍼스
printf(“삼성전자_화성캠퍼스”);
#elseif 삼성디스플레이_탕정
printf(“삼성디스플레이_탕정”);
#endif
이런 식 입니다.

그런데 C# 에서는 일일이 모든 파일에서 전처리기를 선언해야 하더군요.
혹시 다른 방법이 있다면 알려주시기 바랍니다.
감사합니다.

p.s 구성 관리자에서 여러 개의 솔루션 구성을 만들어서 테스트 해봤는데 디버깅을 하려고 하자 “조건부 컴파일 기호” 가 먹히지 않고 솔루션 구성은 제가 만든 구성이지만 프로젝트 컨텍스트에서 디버그로 변경하자 아래의 메시지가 출력됩니다.
image

좋아요 1

csproj에서 설정에 따라 파일단위로 가능하니 원하시는 결과를 얻을 수 있을텐데요, 이게 아마도 .NET Framework 이랑 .NET (Core)의 설정이 다를 것 같습니다.

좋아요 2

아래 예시는 콘솔 프로젝트이지만 윈폼 프로젝트도 다르지 않습니다.

예시는 Const 클래스의 특정 값을 프로젝트에 따라 다르게 설정하는 것으로 예시를 들어봤습니다.

| Program.cs

using CsprojConditionDefineConstantsTest;

Console.WriteLine(Const.ProjectName);

| ProjectAConst.cs

    public static class Const   
    {
        public const string ProjectName = "ProjectA";
    }

| ProjectBConst.cs

    public static class Const   
    {
        public const string ProjectName = "ProjectB";
    }

| csporj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net7.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

	<PropertyGroup>
		<DefineConstants>ProjectA</DefineConstants> <!--또는 ProjectB-->
	</PropertyGroup>

	<ItemGroup>
		<Compile Remove="Project*.cs" />
	</ItemGroup>

	<ItemGroup Condition="$(DefineConstants.Contains('ProjectA'))">
		<Compile Include="ProjectA*.cs" />
	</ItemGroup>

	<ItemGroup Condition="$(DefineConstants.Contains('ProjectB'))">
		<Compile Include="ProjectB*.cs" />
	</ItemGroup>

</Project>

DefineConstants의 ProjectA, ProjectB의 유무에 따라 다른 이름이 출력되는 것을 확인할 수 있습니다.

| ProjectA로 설정했을 경우

	<PropertyGroup>
		<DefineConstants>ProjectA</DefineConstants>
	</PropertyGroup>

| 출력

ProjectA

| ProjectB로 설정했을 경우

	<PropertyGroup>
		<DefineConstants>ProjectB</DefineConstants>
	</PropertyGroup>

| 출력

ProjectB
좋아요 5

답변감사합니다. 제가 하고 싶은 것과 궁금한 것은 다음과 같습니다.


위의 사진에서 두 개의 컴파일 옵션을 만들었습니다.

그 중 하나의 옵션을 선택합니다.(조건부 컴파일 옵션에 전처리기를 입력하여 원하는 코드가 활성화 되었습니다.)

이 옵션을 선택하여 디버깅을 하려고 하자 이런 메시지가 출력됩니다.

생성된 폴더안의 pdb 파일은 없었습니다. 그래서 이런 메세지가 출력되는 것으로 이해했습니다.(물론 디버깅도 되지 않습니다.)
디버깅을 하기 위해서 아래와 같이 바꾸었습니다.

디버그 모드에는 전처리기를 입력하지 않았습니다.
이유는 사용자 옵션에 다른 전처리기를 입력해서 그 코드가 컴파일 되도록 하기 위해서 입니다. 디버그 모드에 모든 전처리기를 넣을 수는 없습니다.

즉 각 사용자 옵션에 따라서 디버깅 및 릴리즈를 하고 싶습니다.
방법이 있을까요?

좋아요 1

제가 잘 이해했는지는 모르겠습니다.

만드신 MNET 및 MNET_DEBUG는 각각의 구성 속성이 있을 것입니다. 그 속성에서 아마도 디버그 모드로 실행 (화면상에서는 MNET이네요??) 되어야 하는 속성에 아마도 디버그 관련 속성이 설정되지 않은 것 같아요.

구성 속성을 살펴보세요. MNET은 아마도 Release에서 파생된 것 같아서… 디버그가 안될 것 같습니다. MNET는 릴리스 구성 속성으로, MNET_Debug는 디버그 구성 속성으로 구성하신 후 그 구성에 맞는 전처리기가 동작하는지를 살펴보시면 될 듯 해요.

좋아요 2

답변 감사드립니다. 보신 솔루션 구성은 예시로 만든 것입니다. 이 상태에서 디버그나 릴리즈 모드로 컴파일하면 #if 가 먹히지 않더군요. 혹시 솔루션 구성과 프로젝트-> 속성 의 구성은 서로 다른 것 입니까?
만약 그렇다면 파일 전부에 전처리기를 정의하는 것밖에는 방법이 없는거로군요?
그렇다면 구성관리자의 프로젝트 컨텍스트에서 제가 만든 구성으로 선택해서 빌드할 경우 릴리즈인지 디버그 인지 판단할 수 있나요? 아니면 확인이라도 할 수 있는 방법이 있나요?

좋아요 1

이게 무슨 말인지 모르겠습니다.

일단 아래 처럼,

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net7.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <Configurations>Debug;Release;Debug_Test;Release_Test</Configurations>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Test|AnyCPU'">
    <Optimize>True</Optimize>
    <DefineConstants>$(DefineConstants);HAHA</DefineConstants>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <DefineConstants>$(DefineConstants);HAHA</DefineConstants>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
    <DefineConstants>$(DefineConstants);HAHA</DefineConstants>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Test|AnyCPU'">
    <DefineConstants>$(DefineConstants);HAHA</DefineConstants>
  </PropertyGroup>
</Project>

분기 할 수 있음을 알 수 있습니다. (그리고… DefineConstants에 Configuration 이름으로 정의 될 것이고요)

위의 코드를 살펴보세요.
(.NET Framework 과 .NET(Core)의 구성이 다를 수도 있는데… 이건 살펴봐야합니다)

※ Platform은 뺄 수 있습니다.

좋아요 2

답변 감사합니다. 제가 잘못 알고 있었네요 그러니까 제 질문은 솔루션구성을 여러개 할 경우 디버그모드와 릴리즈를 따로 가져갈 수 있는지 였습니다. 디모이님께서 올려주신 csporj 에서 디버그 모드와 릴리즈 모드를 살펴보니
디버그모드에서는

<DebugSymbols> true</DebugSymbols> 

이 태그가 있고

<DebugType >full </DebugType>  
<Optimize> false </Optimize> 

로 설정되어 있었습니다.
릴리즈에서는

<DebugSymbols> true </DebugSymbols> 

이 태그가 없고

<DebugType> pdbonly </DebugType> 
<Optimize> true </Optimize> 

이렇게 구성되어 있는것을 확인했습니다.
처음에 올려주신 것에서 답이 있었네요… 정말 감사드립니다. 귀한 시간 내주셔서 감사합니다.

좋아요 3