<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      【UWP】在 UWP 中使用 Windows App SDK

      眾所周知,WAS (Windows App SDK,俗稱 WinUI3)在剛開始是支持 UWP 的,甚至最早只支持 UWP,但是微軟在正式版發布前刪除了對 UWP 的支持,不過真的刪除了嗎?初生之鳥2023年10月發現在 VS 調試下無視報錯繼續運行可以正常在 UWP 加載 WAS。隨著 WAS 的開源,WAS 阻止在 UWP 上運行的原因也被找到,至此大家終于找到在 UWP 上使用 WAS 的方法了。

      WAS 阻止在 UWP 上運行的方法很簡單,就是檢查注冊表HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WinUI\Xaml\EnableUWPWindow是否為00000001,如果不是就直接報錯。

      Window_Partial.cpp#L80-L114
      // ----------------------------------------------------------------------
      //                               IWindow
      // ----------------------------------------------------------------------
      Window::Window()
      {
          // The first window created internally by DXamlCore _must_ be a UWP Window.  DXamlCore
          // requires and controls the lifetime of a hidden UWP Microsoft.UI.Xaml.Window.
          // note that this Window instance will be the 'real' window for UWP instances, but
          // serves as a dummy for all other instances. dummy behavior is deprecated and being removed.
          auto dxamlCore = DXamlCore::GetCurrent();
          Window* window = dxamlCore->GetDummyWindowNoRef();
      
          if (!window)
          {
              // Do a runtime check to see if UWP should be enabled
              static auto runtimeEnabledFeatureDetector = RuntimeFeatureBehavior::GetRuntimeEnabledFeatureDetector();
              auto UWPWindowEnabled = runtimeEnabledFeatureDetector->IsFeatureEnabled(RuntimeEnabledFeature::EnableUWPWindow);
      
              // WinUI UWP
              if (!UWPWindowEnabled && DXamlCore::GetCurrent()->GetHandle()->GetInitializationType() != InitializationType::IslandsOnly)
              {
                  ::RoOriginateError(
                      E_NOT_SUPPORTED,
                      wrl_wrappers::HStringReference(
                      L"WinUI: Error creating an UWP Window. Creating an UWP window is not allowed."
                      ).Get());
                  XAML_FAIL_FAST();
              }
              m_spWindowImpl = std::make_shared<UWPWindowImpl>(this);
          }
          else
          {
              m_spWindowImpl = std::make_shared<DesktopWindowImpl>(this);
          }
      }
      Window_Partial.cpp#L80-L114
      { L"EnableUWPWindow", RuntimeEnabledFeature::EnableUWPWindow, false, 0, 0 }

      所以我們只需要修改注冊表就行了。

      Windows Registry Editor Version 5.00
      
      [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WinUI\Xaml]
      "EnableUWPWindow"=dword:00000001

      但是到處修改注冊表并不是一個好主意,于是初生之鳥便提出利用Detours來劫持讀取注冊表的方法:HookCoreAppWinUI

      我們將其翻譯成 C#,再加一些小修改,便能得出如下內容:

      #r "nuget:Detours.Win32Metadata"
      #r "nuget:Microsoft.Windows.CsWin32"
      
      using System;
      using System.Collections.Generic;
      using System.Runtime.CompilerServices;
      using System.Runtime.InteropServices;
      using Windows.Win32;
      using Windows.Win32.Foundation;
      using Windows.Win32.System.Registry;
      using Detours = Microsoft.Detours.PInvoke;
      
      /// <summary>
      /// Represents a hook for getting the value of the <c>HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WinUI\Xaml\EnableUWPWindow</c> registry key always returning <see langword="00000001"/>.
      /// </summary>
      public partial class HookRegistry : IDisposable
      {
          /// <summary>
          /// The value that indicates whether the class has been disposed.
          /// </summary>
          private bool disposed;
      
          /// <summary>
          /// The reference count for the hook.
          /// </summary>
          private static int refCount;
      
          /// <summary>
          /// The dictionary that maps the <see cref="HKEY"/> to a value that indicates whether the key is a real key.
          /// </summary>
          private static readonly Dictionary<HKEY, bool> xamlKeyMap = [];
      
          /// <summary>
          /// The object used to synchronize access to the <see cref="xamlKeyMap"/> dictionary.
          /// </summary>
          private static readonly object locker = new();
      
          /// <remarks>The original <see cref="PInvoke.RegOpenKeyEx(HKEY, PCWSTR, uint, REG_SAM_FLAGS, HKEY*)"/> function.</remarks>
          /// <inheritdoc cref="PInvoke.RegOpenKeyEx(HKEY, PCWSTR, uint, REG_SAM_FLAGS, HKEY*)"/>
          private static unsafe delegate* unmanaged[Stdcall]<HKEY, PCWSTR, uint, REG_SAM_FLAGS, HKEY*, WIN32_ERROR> RegOpenKeyExW;
      
          /// <remarks>The original <see cref="PInvoke.RegCloseKey(HKEY)"/> function.</remarks>
          /// <inheritdoc cref="PInvoke.RegCloseKey(HKEY)"/>
          private static unsafe delegate* unmanaged[Stdcall]<HKEY, WIN32_ERROR> RegCloseKey;
      
          /// <remarks>The original <see cref="PInvoke.RegQueryValueEx(HKEY, PCWSTR, uint*, REG_VALUE_TYPE*, byte*, uint*)"/> function.</remarks>
          /// <inheritdoc cref="PInvoke.RegQueryValueEx(HKEY, PCWSTR, uint*, REG_VALUE_TYPE*, byte*, uint*)"/>
          private static unsafe delegate* unmanaged[Stdcall]<HKEY, PCWSTR, uint*, REG_VALUE_TYPE*, byte*, uint*, WIN32_ERROR> RegQueryValueExW;
      
          /// <summary>
          /// Initializes a new instance of the <see cref="HookRegistry"/> class.
          /// </summary>
          public HookRegistry()
          {
              refCount++;
              StartHook();
          }
      
          /// <summary>
          /// Finalizes this instance of the <see cref="HookRegistry"/> class.
          /// </summary>
          ~HookRegistry()
          {
              Dispose();
          }
      
          /// <summary>
          /// Gets the value that indicates whether the hook is active.
          /// </summary>
          public static bool IsHooked { get; private set; }
      
          /// <summary>
          /// Starts the hook for the <see cref="PInvoke.AppPolicyGetWindowingModel(HANDLE, AppPolicyWindowingModel*)"/> function.
          /// </summary>
          private static unsafe void StartHook()
          {
              if (!IsHooked)
              {
                  using FreeLibrarySafeHandle library = PInvoke.GetModuleHandle("ADVAPI32.dll");
                  if (!library.IsInvalid
                      && NativeLibrary.TryGetExport(library.DangerousGetHandle(), "RegOpenKeyExW", out nint regOpenKeyExW)
                      && NativeLibrary.TryGetExport(library.DangerousGetHandle(), nameof(PInvoke.RegCloseKey), out nint regCloseKey)
                      && NativeLibrary.TryGetExport(library.DangerousGetHandle(), "RegQueryValueExW", out nint regQueryValueExW))
                  {
                      void* regOpenKeyExWPtr = (void*)regOpenKeyExW;
                      void* regCloseKeyPtr = (void*)regCloseKey;
                      void* regQueryValueExWPtr = (void*)regQueryValueExW;
      
                      delegate* unmanaged[Stdcall]<HKEY, PCWSTR, uint, REG_SAM_FLAGS, HKEY*, WIN32_ERROR> overrideRegOpenKeyExW = &OverrideRegOpenKeyExW;
                      delegate* unmanaged[Stdcall]<HKEY, WIN32_ERROR> overrideRegCloseKey = &OverrideRegCloseKey;
                      delegate* unmanaged[Stdcall]<HKEY, PCWSTR, uint*, REG_VALUE_TYPE*, byte*, uint*, WIN32_ERROR> overrideRegQueryValueExW = &OverrideRegQueryValueExW;
      
                      _ = Detours.DetourRestoreAfterWith();
      
                      _ = Detours.DetourTransactionBegin();
                      _ = Detours.DetourUpdateThread(PInvoke.GetCurrentThread());
                      _ = Detours.DetourAttach(ref regOpenKeyExWPtr, overrideRegOpenKeyExW);
                      _ = Detours.DetourAttach(ref regCloseKeyPtr, overrideRegCloseKey);
                      _ = Detours.DetourAttach(ref regQueryValueExWPtr, overrideRegQueryValueExW);
                      _ = Detours.DetourTransactionCommit();
      
                      RegOpenKeyExW = (delegate* unmanaged[Stdcall]<HKEY, PCWSTR, uint, REG_SAM_FLAGS, HKEY*, WIN32_ERROR>)regOpenKeyExWPtr;
                      RegCloseKey = (delegate* unmanaged[Stdcall]<HKEY, WIN32_ERROR>)regCloseKeyPtr;
                      RegQueryValueExW = (delegate* unmanaged[Stdcall]<HKEY, PCWSTR, uint*, REG_VALUE_TYPE*, byte*, uint*, WIN32_ERROR>)regQueryValueExWPtr;
      
                      IsHooked = true;
                  }
              }
          }
      
          /// <summary>
          /// Ends the hook for the <see cref="PInvoke.AppPolicyGetWindowingModel(HANDLE, AppPolicyWindowingModel*)"/> function.
          /// </summary>
          public static unsafe void EndHook()
          {
              if (--refCount == 0 && IsHooked)
              {
                  void* regOpenKeyExWPtr = RegOpenKeyExW;
                  void* regCloseKeyPtr = RegCloseKey;
                  void* regQueryValueExWPtr = RegQueryValueExW;
      
                  delegate* unmanaged[Stdcall]<HKEY, PCWSTR, uint, REG_SAM_FLAGS, HKEY*, WIN32_ERROR> overrideRegOpenKeyExW = &OverrideRegOpenKeyExW;
                  delegate* unmanaged[Stdcall]<HKEY, WIN32_ERROR> overrideRegCloseKey = &OverrideRegCloseKey;
                  delegate* unmanaged[Stdcall]<HKEY, PCWSTR, uint*, REG_VALUE_TYPE*, byte*, uint*, WIN32_ERROR> overrideRegQueryValueExW = &OverrideRegQueryValueExW;
      
                  _ = Detours.DetourTransactionBegin();
                  _ = Detours.DetourUpdateThread(PInvoke.GetCurrentThread());
                  _ = Detours.DetourDetach(&regOpenKeyExWPtr, overrideRegOpenKeyExW);
                  _ = Detours.DetourDetach(&regCloseKeyPtr, overrideRegCloseKey);
                  _ = Detours.DetourDetach(&regQueryValueExWPtr, overrideRegQueryValueExW);
                  _ = Detours.DetourTransactionCommit();
      
                  RegOpenKeyExW = null;
                  RegCloseKey = null;
                  RegQueryValueExW = null;
      
                  IsHooked = false;
              }
          }
      
          /// <remarks>The overridden <see cref="PInvoke.RegOpenKeyEx(HKEY, PCWSTR, uint, REG_SAM_FLAGS, HKEY*)"/> function.</remarks>
          /// <inheritdoc cref="PInvoke.RegOpenKeyEx(HKEY, PCWSTR, uint, REG_SAM_FLAGS, HKEY*)"/>
          [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])]
          private static unsafe WIN32_ERROR OverrideRegOpenKeyExW(HKEY hKey, PCWSTR lpSubKey, uint ulOptions, REG_SAM_FLAGS samDesired, HKEY* phkResult)
          {
              WIN32_ERROR result = RegOpenKeyExW(hKey, lpSubKey, ulOptions, samDesired, phkResult);
              if (hKey == HKEY.HKEY_LOCAL_MACHINE && lpSubKey.ToString().Equals(@"Software\Microsoft\WinUI\Xaml", StringComparison.OrdinalIgnoreCase))
              {
                  if (result == WIN32_ERROR.ERROR_FILE_NOT_FOUND)
                  {
                      HKEY key = new(HANDLE.INVALID_HANDLE_VALUE);
                      xamlKeyMap[key] = false;
                      *phkResult = key;
                      result = WIN32_ERROR.ERROR_SUCCESS;
                  }
                  else if (result == WIN32_ERROR.ERROR_SUCCESS)
                  {
                      xamlKeyMap[*phkResult] = true;
                  }
              }
              return result;
          }
      
          /// <remarks>The overridden <see cref="PInvoke.RegCloseKey(HKEY)"/> function.</remarks>
          /// <inheritdoc cref="PInvoke.RegCloseKey(HKEY)"/>
          [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])]
          private static unsafe WIN32_ERROR OverrideRegCloseKey(HKEY hKey)
          {
              bool isXamlKey;
              lock (locker)
              {
                  if (isXamlKey = xamlKeyMap.TryGetValue(hKey, out bool isRealKey))
                  {
                      xamlKeyMap.Remove(hKey);
                  }
                  return isXamlKey
                      ? isRealKey
                          ? RegCloseKey(hKey) // real key
                          : WIN32_ERROR.ERROR_SUCCESS // simulated key
                      : hKey == HANDLE.INVALID_HANDLE_VALUE
                          ? WIN32_ERROR.ERROR_INVALID_HANDLE
                          : RegCloseKey(hKey);
              }
          }
      
          /// <remarks>The overridden <see cref="PInvoke.RegQueryValueEx(HKEY, PCWSTR, uint*, REG_VALUE_TYPE*, byte*, uint*)"/> function.</remarks>
          /// <inheritdoc cref="PInvoke.RegQueryValueEx(HKEY, PCWSTR, uint*, REG_VALUE_TYPE*, byte*, uint*)"/>
          [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])]
          private static unsafe WIN32_ERROR OverrideRegQueryValueExW(HKEY hKey, PCWSTR lpValueName, [Optional] uint* lpReserved, [Optional] REG_VALUE_TYPE* lpType, [Optional] byte* lpData, [Optional] uint* lpcbData)
          {
              if (lpValueName.Value != default && lpValueName.ToString().Equals("EnableUWPWindow", StringComparison.OrdinalIgnoreCase))
              {
                  lock (locker)
                  {
                      if (xamlKeyMap.TryGetValue(hKey, out bool isRealKey))
                      {
                          WIN32_ERROR result;
                          if (isRealKey)
                          {
                              // real key
                              result = RegQueryValueExW(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);
                              if (result == WIN32_ERROR.ERROR_SUCCESS && lpData != default)
                              {
                                  *lpData = 1;
                              }
                              else if (result == WIN32_ERROR.ERROR_FILE_NOT_FOUND)
                              {
                                  if (lpData == default && lpcbData != default)
                                  {
                                      *lpcbData = sizeof(int);
                                      result = WIN32_ERROR.ERROR_SUCCESS;
                                  }
                                  else if (lpData != default && lpcbData != default)
                                  {
                                      if (*lpcbData >= sizeof(int))
                                      {
                                          *lpData = 1;
                                          result = WIN32_ERROR.ERROR_SUCCESS;
                                      }
                                      else
                                      {
                                          result = WIN32_ERROR.ERROR_MORE_DATA;
                                      }
                                  }
                              }
                          }
                          else
                          {
                              // simulated key
                              result = WIN32_ERROR.ERROR_FILE_NOT_FOUND;
                              if (lpData == default && lpcbData != default)
                              {
                                  *lpcbData = sizeof(int);
                                  result = WIN32_ERROR.ERROR_SUCCESS;
                              }
                              else if (lpData != default && lpcbData != default)
                              {
                                  if (*lpcbData >= sizeof(int))
                                  {
                                      *lpData = 1;
                                      result = WIN32_ERROR.ERROR_SUCCESS;
                                  }
                                  else
                                  {
                                      result = WIN32_ERROR.ERROR_MORE_DATA;
                                  }
                              }
                          }
                          return result;
                      }
                  }
              }
              return RegQueryValueExW(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);
          }
      
          /// <inheritdoc/>
          public void Dispose()
          {
              if (!disposed && IsHooked)
              {
                  EndHook();
              }
              GC.SuppressFinalize(this);
              disposed = true;
          }
      }

      隨后我們只需要在入口點創建App時進行劫持就行了。

      private static bool IsSupportCoreWindow
      {
          get
          {
              try
              {
                  RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\WinUI\Xaml");
                  return registryKey?.GetValue("EnableUWPWindow") is > 0;
              }
              catch
              {
                  return false;
              }
          }
      }
      
      private static void Main()
      {
          ComWrappersSupport.InitializeComWrappers();
          HookRegistry hookRegistry = null;
          try
          {
              if (!IsSupportCoreWindow)
              {
                  hookRegistry = new HookRegistry();
              }
              XamlCheckProcessRequirements();
              Application.Start(p =>
              {
                  DispatcherQueueSynchronizationContext context = new(DispatcherQueue.GetForCurrentThread());
                  SynchronizationContext.SetSynchronizationContext(context);
                  _ = new App();
              });
          }
          finally
          {
              hookRegistry?.Dispose();
          }
      }

      當然想要自定義入口函數,我們需要在csproj加上定義。

      <DefineConstants>$(DefineConstants);DISABLE_XAML_GENERATED_MAIN</DefineConstants>

      同時還要記得在清單中明確入口點。

      <?xml version="1.0" encoding="utf-8"?>
      <Package ...>
        ...
        <Applications>
          <Application ...
            EntryPoint="明確的入口點">
            ...
          </Application>
        </Applications>
        ...
      </Package>

      隨后我們就可以正常的使用 UWP/WAS 了。

      最后附上示例應用:https://github.com/wherewhere/CoreAppUWP/tree/muxc

      posted @ 2024-10-18 15:49  where-where  閱讀(287)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 2021国产成人精品久久| 国产AV无码专区亚洲AWWW| 最新亚洲人成网站在线影院| 东京热人妻无码人av| 亚洲国产精品无码一区二区三区 | 熟妇人妻中文a∨无码| 中文字幕在线亚洲精品| 镇雄县| 熟女精品国产一区二区三区| 国产卡一卡二卡三免费入口| 国内精品久久久久影院薰衣草| 91久久偷偷做嫩草影院免费看 | 少妇伦子伦情品无吗| 国产精品福利一区二区三区| 亚洲国产综合自在线另类| 国产精品一区在线蜜臀| 欧美亚洲另类自拍偷在线拍| 男同精品视频免费观看网站| 97人人超碰国产精品最新| 中文字幕国产精品一二区| 亚洲av成人在线一区| 99精品久久毛片a片| 国产精品亚洲欧美大片在线看| 日本免费一区二区三区久久| 忍着娇喘人妻被中出中文字幕| 亚洲中文字幕在线二页| 午夜福利电影| 国产a级三级三级三级| 晋中市| 夜夜添狠狠添高潮出水| 中文字幕有码高清日韩| 中文一区二区视频| 亚洲AV国产福利精品在现观看| 国产精品一区二区久久精品| 国产精品亚洲а∨无码播放| 久久精品无码免费不卡| 国产在线98福利播放视频| 午夜DY888国产精品影院| 都匀市| 精品无码人妻一区二区三区| 老少配老妇老熟女中文普通话|