C# Conditional compilation ile Win32 ve WinRT nasıl ayrılabilir?

Katılım
26 Temmuz 2023
Mesajlar
4.721
Makaleler
27
Çözümler
180
Yer
Başkent
Daha fazla  
Sistem Özellikleri
HP Victus 16 S1035NT
Cinsiyet
Erkek
Meslek
Yazılımcı/Yayıncı
Selamlar. Bugün biraz internette zor bulunan ve makalesinden de tam emin olamadığım bir konuyla geldim. Amacım şu:
Sadece WinRT'ye özel bir kod bloğunu WinForms, WPF vb. teknolojilerin kullanımına kapatmak. Bunun için de en safe yöntem Conditional compilation olduğunu düşünüyorum. Yâni direkt otomatik algılayıp compile sırasında o kısmı build etmeyecek. WinRT #if'i tek başına işe yaramıyor. Bunu da nasıl 4/4'lük yapabileceğimi bulamadım.
Örnek olarak şöyle açıklayayım:
Kod:
#if WinRT
public static void ForWinRT()
{
    /// blabla
}
/// Buna Cond Comp gerek yok çünkü Win32'de olan
/// Her şey WinUI'da da var. Ama yine de:
#if Win32
public static void ForWin32()
{
    /// blabla
}
Kodda bu şekilde kullanıyoruz ama .csproj'a da:
Kod:
<--! Örneğin: -->
<PropertyGroup Condition="'$(TargetFramework)'=='net9.0-windows'">
    <DefineConstants>$(DefineConstants);WIN32</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)'=='net9.0-windows10.0.19043.0'">
    <DefineConstants>$(DefineConstants);WINRT</DefineConstants>
</PropertyGroup>
Tarzında eklenmesi gerekiyor ama sadece Framework vb. gibi değil de X NuGet'i yüklüyse nasıl yapabiliriz tam anlayamadım. Mesela WinUI'da kullanılan NuGet'lar:
1762157609163.png

Bunları da algılayabilmesi için cond ekleyebiliyoruz sanırım.

@bitwise @TheAny yardımcı olabilir misiniz bu konuda bilginiz varsa?
 
Sifir malesef, windows API'ina dokunmayali 10 sene oldu.
Aslında API'den çok yeni nesil C# esnekliği diyebiliriz. Ya da ben yeni öğrendim. # sembolünün C++++'da çok güçlü bir karşılığı var.
 
Paketlerin kendi set ettikleri proplar varsa onlari kontrol edebilirsin. Mesela WindowsAppSDK/version.props icerisinde;
XML:
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT License. See LICENSE in the project root for license information. -->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <WindowsAppSDKVersionMajor>0</WindowsAppSDKVersionMajor>
    <WindowsAppSDKVersionMinor>1</WindowsAppSDKVersionMinor>
    <WindowsAppSDKVersionPatch>0</WindowsAppSDKVersionPatch>
    <WindowsAppSDKVersionBuild Condition="$(WindowsAppSDKVersionBuild) == ''">0</WindowsAppSDKVersionBuild>
    <WindowsAppSDKVersionRevision Condition="$(WindowsAppSDKVersionRevision) == ''">0</WindowsAppSDKVersionRevision>
  </PropertyGroup>
  <ItemDefinitionGroup>
    <ClCompile>
      <PreprocessorDefinitions>
        %(PreprocessorDefinitions);
        WINDOWSAPPSDK_VERSION_MAJOR=$(WindowsAppSDKVersionMajor);
        WINDOWSAPPSDK_VERSION_MINOR=$(WindowsAppSDKVersionMinor);
        WINDOWSAPPSDK_VERSION_PATCH=$(WindowsAppSDKVersionPatch);
        WINDOWSAPPSDK_VERSION_BUILD=$(WindowsAppSDKVersionBuild);
        WINDOWSAPPSDK_VERSION_REVISION=$(WindowsAppSDKVersionRevision);
      </PreprocessorDefinitions>
    </ClCompile>
    <ResourceCompile>
      <PreprocessorDefinitions>
        %(PreprocessorDefinitions);
        WINDOWSAPPSDK_VERSION_MAJOR=$(WindowsAppSDKVersionMajor);
        WINDOWSAPPSDK_VERSION_MINOR=$(WindowsAppSDKVersionMinor);
        WINDOWSAPPSDK_VERSION_PATCH=$(WindowsAppSDKVersionPatch);
        WINDOWSAPPSDK_VERSION_BUILD=$(WindowsAppSDKVersionBuild);
        WINDOWSAPPSDK_VERSION_REVISION=$(WindowsAppSDKVersionRevision);
      </PreprocessorDefinitions>
    </ResourceCompile>
  </ItemDefinitionGroup>
</Project>

Dolayisiyla su sekilde bi constant belirleyebilirsin muhtemelen;
XML:
<PropertyGroup Condition="'$(WindowsAppSDKVersionMajor)' != ''">
  <DefineConstants>$(DefineConstants);HAS_WINAPPSDK</DefineConstants>
</PropertyGroup>

Denemen lazim ama.
 
Paketlerin kendi set ettikleri proplar varsa onlari kontrol edebilirsin. Mesela WindowsAppSDK/version.props icerisinde;
XML:
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT License. See LICENSE in the project root for license information. -->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <WindowsAppSDKVersionMajor>0</WindowsAppSDKVersionMajor>
    <WindowsAppSDKVersionMinor>1</WindowsAppSDKVersionMinor>
    <WindowsAppSDKVersionPatch>0</WindowsAppSDKVersionPatch>
    <WindowsAppSDKVersionBuild Condition="$(WindowsAppSDKVersionBuild) == ''">0</WindowsAppSDKVersionBuild>
    <WindowsAppSDKVersionRevision Condition="$(WindowsAppSDKVersionRevision) == ''">0</WindowsAppSDKVersionRevision>
  </PropertyGroup>
  <ItemDefinitionGroup>
    <ClCompile>
      <PreprocessorDefinitions>
        %(PreprocessorDefinitions);
        WINDOWSAPPSDK_VERSION_MAJOR=$(WindowsAppSDKVersionMajor);
        WINDOWSAPPSDK_VERSION_MINOR=$(WindowsAppSDKVersionMinor);
        WINDOWSAPPSDK_VERSION_PATCH=$(WindowsAppSDKVersionPatch);
        WINDOWSAPPSDK_VERSION_BUILD=$(WindowsAppSDKVersionBuild);
        WINDOWSAPPSDK_VERSION_REVISION=$(WindowsAppSDKVersionRevision);
      </PreprocessorDefinitions>
    </ClCompile>
    <ResourceCompile>
      <PreprocessorDefinitions>
        %(PreprocessorDefinitions);
        WINDOWSAPPSDK_VERSION_MAJOR=$(WindowsAppSDKVersionMajor);
        WINDOWSAPPSDK_VERSION_MINOR=$(WindowsAppSDKVersionMinor);
        WINDOWSAPPSDK_VERSION_PATCH=$(WindowsAppSDKVersionPatch);
        WINDOWSAPPSDK_VERSION_BUILD=$(WindowsAppSDKVersionBuild);
        WINDOWSAPPSDK_VERSION_REVISION=$(WindowsAppSDKVersionRevision);
      </PreprocessorDefinitions>
    </ResourceCompile>
  </ItemDefinitionGroup>
</Project>

Dolayisiyla su sekilde bi constant belirleyebilirsin muhtemelen;
XML:
<PropertyGroup Condition="'$(WindowsAppSDKVersionMajor)' != ''">
  <DefineConstants>$(DefineConstants);HAS_WINAPPSDK</DefineConstants>
</PropertyGroup>

Denemen lazim ama.
Maalesef kendi propu yok. Sadece WinUI'da UseWindowsForms ve WPF propu var ama onlar da tam isteğimi karşılamıyor. Müsait olunca deneyeceğim.

Denedim ama maalesef başarısız.

Direkt 2 adımlık bir olay var. Sadece .csproj'a tanımlayıp, #if cond ile kullanmak. Dotnet'e özel yapabiliyorum ama konunun dotnetle alakası pek olmadığı için nasıl mantık kurmam gerek anlayamadım. WinRT min 6.0 kullanıyor ama Win32 de 6.0 ve üzeri kullanabiliyor. Hatta WinForms'un yeni versiyonlarını denemedim ama belki WinRT bile çalışıyor olabilir. En safe bir şekilde nasıl yapabilirim sence?
 
Son düzenleme:
Reisim bu WinAPI konusunda pek bilgim yok ama şöyle bir fikir vereyim. Bir işi birden fazla frameworkten implemente etmek için ayrı statik methodlar yerine bir arabirim üzerinden yapsan nasıl olur? Örneğin ayrı ayrı frameworklerde bir buttonu tıklamak istiyorsun diyelim.

Bir tane IButtonClicker interface’i koysan, WinRTButtonClicker, WinUIButtonClicker diye ayrı ayrı bu sorumlulukları yüklesen. Derlediğin bundle’a göre de bu dll’i eklesen nasıl olur? Hem de moduler şekilde güncelleme sunabilirsin. Ama dediğim şey amacının karşılığı mı tam bilemedim :(
 
Reisim bu WinAPI konusunda pek bilgim yok ama şöyle bir fikir vereyim. Bir işi birden fazla frameworkten implemente etmek için ayrı statik methodlar yerine bir arabirim üzerinden yapsan nasıl olur? Örneğin ayrı ayrı frameworklerde bir buttonu tıklamak istiyorsun diyelim.

Bir tane IButtonClicker interface’i koysan, WinRTButtonClicker, WinUIButtonClicker diye ayrı ayrı bu sorumlulukları yüklesen. Derlediğin bundle’a göre de bu dll’i eklesen nasıl olur? Hem de moduler şekilde güncelleme sunabilirsin. Ama dediğim şey amacının karşılığı mı tam bilemedim :(
Evet dediğiniz yöntem de kullanılıyor fakat benim amacım bir WinRT uygulamasında lazım olacak her şeyi bir core dll de sunmak. Yâni evet bir nevi doğru ama bu bahsettiğim cond comp daha profesyonel geldi.

Ek olarak bu cond comp'un bir API ile ilgisi yok. Herhangi bir boolean değeri olabilir. Ben sadece mantığını tam oturtamadı çünkü ilk defa GitCopilot ile gördüm ve mantıklı bir şey olduğunu anladım da o da tam yapamıyor.

Aslında uğraşmak istesem Wincore.System, Wincore.System.Form vs. gibi bölüp ayrı ayrı dll yapcam da direkt Wincore yapmak daha kolay😅 Zaten bunlarla uğraşarak ana hedefim gecikiyor.
 

Technopat Haberler

Yeni konular

Geri
Yukarı