Author Topic: Simple APK Installer for WSA (Windows Subsystem for Android (11 Insider))  (Read 3955 times)

0 Members and 1 Guest are viewing this topic.

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
"Simple" is a relative term. For those of you who are on Windows 11 Insider builds, you should have access to Windows Subsystem for Android (WSA). This code assumes you have downloaded the Android Debug Bridge (adb) binaries. It's a lot of code to just show a tiny window and run a couple of commands. I probably won't expand it but I thought I'd share it anyways because @mpgcan and @Petr both made some good Win32 code recently. Maybe they can make use of some of the wrappers.

Code: QB64 $NOPREFIX: [Select]
  1.  
  2. ConsoleTitle "QB64 APK Installer for WSA (Console)"
  3.  
  4. $VersionInfo:CompanyName=SpriggsySpriggs
  5. $VersionInfo:FileDescription=APK installer for WSA
  6. $VersionInfo:ProductName=QB64 APK Installer for WSA
  7.  
  8. Const IDI_APPLICATION = 32512
  9. Const IDC_ARROW = 32512
  10. Const COLOR_WINDOW = 5
  11.  
  12. Const WS_EX_CLIENTEDGE = &H00000200
  13. Const WS_OVERLAPPED = &H00000000
  14. Const WS_CAPTION = &H00C00000
  15. Const WS_SYSMENU = &H00080000
  16. Const WS_THICKFRAME = &H00040000
  17. Const WS_MINIMIZEBOX = &H00020000
  18. Const WS_MAXIMIZEBOX = &H00010000
  19. Const WS_OVERLAPPEDWINDOW = WS_OVERLAPPED Or WS_CAPTION Or WS_SYSMENU Or WS_THICKFRAME Or WS_MINIMIZEBOX Or WS_MAXIMIZEBOX
  20. Const CW_USEDEFAULT = &H80000000
  21. Const WS_TABSTOP = &H00010000
  22. Const WS_CHILD = &H40000000
  23. Const WS_VISIBLE = &H10000000
  24.  
  25. Const WS_VSCROLL = &H00200000
  26. Const WS_HSCROLL = &H00100000
  27.  
  28.  
  29. Const BS_PUSHBUTTON = 0
  30. Const BS_AUTOCHECKBOX = 3
  31. Const BS_GROUPBOX = 7
  32. Const BS_AUTORADIOBUTTON = 9
  33. Const BS_TEXT = 0
  34. Const BS_SPLITBUTTON = &HC
  35. Const BS_DEFPUSHBUTTON = &H00000001
  36.  
  37. Const SW_SHOWDEFAULT = &HA
  38.  
  39. Const WM_DESTROY = 2
  40. Const WM_GETTEXT = &H000D
  41. Const WM_CLOSE = &H0010
  42. Const WM_COMMAND = &H0111
  43. Const WM_ENTERSIZEMOVE = &H0231
  44. Const WM_EXITSIZEMOVE = &H0232
  45.  
  46. Const IDCANCEL = 2
  47. Const IDNO = 7
  48. Const IDOK = 1
  49. Const IDRETRY = 4
  50. Const IDYES = 6
  51.  
  52. Const LF_FACESIZE = 32
  53.  
  54. Const SPI_GETNONCLIENTMETRICS = &H0029
  55. Const WM_SETFONT = &H0030
  56.  
  57. Const BM_GETCHECK = &HF0
  58.  
  59. Const PROGRESS_CLASS = "msctls_progress32"
  60. Const PBS_SMOOTH = &H1
  61. Const PBS_VERTICAL = &H4
  62.  
  63. Const CCM_FIRST = &H2000
  64. Const CCM_LAST = CCM_FIRST + &H200
  65. Const CCM_SETBKCOLOR = CCM_FIRST + 1
  66. Const CCM_SETCOLORSCHEME = CCM_FIRST + 2
  67. Const CCM_GETCOLORSCHEME = CCM_FIRST + 3
  68. Const CCM_GETDROPTARGET = CCM_FIRST + 4
  69. Const CCM_SETUNICODEFORMAT = CCM_FIRST + 5
  70. Const CCM_GETUNICODEFORMAT = CCM_FIRST + 6
  71. Const CCM_SETVERSION = CCM_FIRST + &H7
  72. Const CCM_GETVERSION = CCM_FIRST + &H8
  73. Const CCM_SETNOTIFYWINDOW = CCM_FIRST + &H9
  74. Const CCM_SETWINDOWTHEME = CCM_FIRST + &HB
  75. Const CCM_DPISCALE = CCM_FIRST + &HC
  76.  
  77. Const COMCTL32_VERSION = 6
  78.  
  79. Const WM_USER = &H0400
  80. Const PBM_SETRANGE = WM_USER + 1
  81. Const PBM_SETPOS = WM_USER + 2
  82. Const PBM_DELTAPOS = WM_USER + 3
  83. Const PBM_SETSTEP = WM_USER + 4
  84. Const PBM_STEPIT = WM_USER + 5
  85. Const PBM_SETRANGE32 = WM_USER + 6
  86. Const PBM_SETSTATE = WM_USER + 16
  87.  
  88. Const PBST_NORMAL = 1
  89. Const PBST_ERROR = 2
  90. Const PBST_PAUSED = 3
  91.  
  92. Const PBM_GETRANGE = WM_USER + 7
  93. Const PBM_GETPOS = WM_USER + 8
  94. Const PBM_SETBARCOLOR = WM_USER + 9
  95. Const PBM_SETBKCOLOR = CCM_SETBKCOLOR
  96.  
  97. Const WC_EDIT = "Edit"
  98. Const WM_SETTEXT = &H000C
  99.  
  100. Const ES_LEFT = 0
  101. Const ES_MULTILINE = 4
  102. Const ES_AUTOVSCROLL = &H0040
  103. Const ES_AUTOHSCROLL = &H0080
  104. Const ES_WANTRETURN = &H1000
  105. Const ES_READONLY = &H0800
  106.  
  107. Const WC_COMBOBOX = "ComboBox"
  108.  
  109. Const WM_ENABLE = &H000A
  110. Const WM_CTLCOLORBTN = &H0135
  111.  
  112. Const WM_ERASEBKGND = &H0014
  113.  
  114.     As Long x, y
  115.  
  116. Type MSG
  117.     As Offset hwnd
  118.     As Unsigned Long message
  119.     As Unsigned Offset wParam
  120.     As Offset lParam
  121.     As Long time
  122.     As POINT pt
  123.     As Long lPrivate
  124.  
  125. Type WNDCLASSEX
  126.     As Unsigned Long cbSize, style
  127.     As Offset lpfnWndProc
  128.     As Long cbClsExtra, cbWndExtra
  129.     As Offset hInstance, hIcon, hCursor, hbrBackground, lpszMenuName, lpszClassName, hIconSm
  130.  
  131. Type RECT
  132.     As Long left, top, right, bottom
  133.  
  134. Type PBRANGE
  135.     As Long iLow, iHigh
  136.  
  137.     Function SendMessage%& (ByVal hWnd As Offset, Byval Msg As Unsigned Long, Byval wParam As Unsigned Offset, Byval lParam As Offset)
  138.     Sub SendMessage (ByVal hWnd As Offset, Byval Msg As Unsigned Long, Byval wParam As Unsigned Offset, Byval lParam As Offset)
  139.     Function DefWindowProc%& (ByVal hWnd As Offset, Byval Msg As Unsigned Long, Byval wParam As Unsigned Offset, Byval lParam As Offset)
  140.     Sub PostQuitMessage (ByVal nExitCode As Long)
  141.     Function LoadCursor%& (ByVal hInstance As Offset, Byval lpCursorName As Offset)
  142.     Function LoadIcon%& (ByVal hInstance As Offset, Byval lpIconName As Offset)
  143.     Function RegisterClassEx% (ByVal wndclassex As Offset)
  144.     Function CreateWindowEx%& (ByVal dwExStyle As Long, Byval lpClassName As Offset, Byval lpWindowName As Offset, Byval dwStyle As Long, Byval X As Long, Byval Y As Long, Byval nWidth As Long, Byval nHeight As Long, Byval hWndParent As Offset, Byval wMenu As Offset, Byval hInstance As Offset, Byval lpParam As Offset)
  145.     Sub CreateWindowEx (ByVal dwExStyle As Long, Byval lpClassName As Offset, Byval lpWindowName As Offset, Byval dwStyle As Long, Byval X As Long, Byval Y As Long, Byval nWidth As Long, Byval nHeight As Long, Byval hWndParent As Offset, Byval wMenu As Offset, Byval hInstance As Offset, Byval lpParam As Offset)
  146.     Sub ShowWindow (ByVal hWnd As Offset, Byval nCmdShow As Long)
  147.     Sub UpdateWindow (ByVal hWnd As Offset)
  148.     Function GetMessage%% (ByVal lpMsg As Offset, Byval hWnd As Offset, Byval wMsgFilterMin As Unsigned Long, Byval wMsgFilterMax As Unsigned Long)
  149.     Sub TranslateMessage (ByVal lpMsg As Offset)
  150.     Sub DispatchMessage (ByVal lpMsg As Offset)
  151.     Function GetModuleHandle%& (ByVal lpModulename As Offset)
  152.     Sub SystemParametersInfo (ByVal uiAction As Unsigned Long, Byval uiParam As Unsigned Long, Byval pvParam As Offset, Byval fWinIni As Unsigned Long)
  153.     Sub SetWindowPos (ByVal hWnd As Offset, Byval hWndInsertAfter As Offset, Byval X As Long, Byval Y As Long, Byval cx As Long, Byval cy As Long, Byval uFlags As Unsigned Long)
  154.     Sub EndDialog (ByVal hDlg As Offset, Byval nResult As Offset)
  155.     Sub EnableWindow (ByVal hWnd As Offset, Byval bEnable As Long)
  156.     Sub GetWindowRect (ByVal hWnd As Offset, Byval lpRect As Offset)
  157.     Function GetDC%& (ByVal hWnd As Offset)
  158.     Function GetDlgItem%& (ByVal hDlg As Offset, Byval nIDDlgItem As Long)
  159.     Function GetDlgCtrlID& (ByVal hWnd As Offset)
  160.     Sub GetWindowText (ByVal hWnd As Offset, Byval lpString As Offset, Byval nMaxCount As Long)
  161.     Sub SetWindowText (ByVal hWnd As Offset, Byval lpString As Offset)
  162.  
  163. $If GETLASTERROR = UNDEFINED Then
  164.         Function GetLastError~& ()
  165.     End Declare
  166.     $Let GETLASTERROR = TRUE
  167.  
  168.     Function MAKEINTRESOURCE%& Alias "MAKEINTRSC" (ByVal i As Offset)
  169.  
  170.     Function MAKELPARAM%& (ByVal l As Integer, Byval h As Integer)
  171.  
  172.     'Function CreateFontIndirect%& Alias "CreateFontIndirectA" (ByVal lplf As Offset)
  173.     Function CreateFont%& Alias "CreateFontA" (ByVal cHeight As Long, Byval cWidth As Long, Byval cEscapement As Long, Byval cOrientation As Long, Byval cWeight As Long, Byval bItalic As Unsigned Long, Byval bUnderline As Unsigned Long, Byval bStrikeout As Unsigned Long, Byval iCharSet As Unsigned Long, Byval iOutPrecision As Unsigned Long, Byval iClipPrecision As Unsigned Long, Byval iQuality As Unsigned Long, Byval iPitchAndFamily As Unsigned Long, pszFaceName As String)
  174.     Sub SetBkColor (ByVal hdc As Offset, Byval color As Unsigned Long)
  175.     Sub SetDCBrushColor (ByVal hdc As Offset, Byval color As Unsigned Long)
  176.     Function CreateSolidBrush%& (ByVal color As Unsigned Long)
  177.  
  178. Declare CustomType Library ".\internal\c\c_compiler\x86_64-w64-mingw32\include\shellapi"
  179.     Function ExtractIcon%& Alias "ExtractIconA" (ByVal hInst As Offset, pszExeFileName As String, Byval nIconIndex As Unsigned Long)
  180.  
  181.     Function GetWindowProc%& ()
  182.  
  183. Rem $Include:'OpenSave.BI'
  184.  
  185. Const DEFEXT = "APK"
  186.  
  187. Dim As WNDCLASSEX wc
  188. Dim As String className: className = "main" + Chr$(0)
  189. Dim Shared As Offset hInstance: hInstance = GetModuleHandle(0)
  190. Dim As MSG msg
  191.  
  192.  
  193. wc.cbSize = Len(wc)
  194. wc.lpfnWndProc = GetWindowProc
  195. wc.hInstance = hInstance
  196. wc.hCursor = LoadCursor(0, MAKEINTRESOURCE(IDC_ARROW))
  197. wc.hIcon = ExtractIcon(0, _CWD$ + "\WSA-icon.ico" + Chr$(0), 0)
  198. wc.hbrBackground = CreateSolidBrush(__RGB(61, 219, 134))
  199. wc.lpszClassName = Offset(className)
  200.  
  201. Dim As Unsigned Integer reg: reg = RegisterClassEx(Offset(wc))
  202. If reg = 0 Then System GetLastError
  203.  
  204. Dim As String childTitle: childTitle = "QB64 APK Installer for WSA" + Chr$(0)
  205. Dim Shared As Offset parentWin: parentWin = CreateWindowEx(0, MAKELPARAM(reg, 0), Offset(childTitle), WS_OVERLAPPED Or WS_CAPTION Or WS_SYSMENU Or WS_MINIMIZEBOX Or WS_MAXIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 320, 120, 0, 0, hInstance, 0)
  206.  
  207. If parentWin = 0 Then System GetLastError
  208.  
  209. Dim As String t0: t0 = "BUTTON" + Chr$(0)
  210. Dim As String t1: t1 = "Browse" + Chr$(0)
  211. Dim Shared As Offset browseBtn: browseBtn = CreateWindowEx(0, Offset(t0), Offset(t1), WS_TABSTOP Or WS_VISIBLE Or WS_CHILD Or BS_DEFPUSHBUTTON, 5, 10, 50, 25, parentWin, 0, hInstance, 0)
  212.  
  213.  
  214. t1 = "Install" + Chr$(0)
  215. Dim Shared As Offset installBtn: installBtn = CreateWindowEx(0, Offset(t0), Offset(t1), WS_TABSTOP Or WS_VISIBLE Or WS_CHILD Or BS_DEFPUSHBUTTON, 80, 10, 50, 25, parentWin, 0, hInstance, 0)
  216.  
  217. Dim Shared As Offset outputBox: outputBox = NewEditBox(5, 50, 300, 20, "READONLY", "")
  218.  
  219. SetFont browseBtn, "Arial", 12, "", "BLACK"
  220. SetFont installBtn, "Arial", 12, "", "BLACK"
  221. SetFont outputBox, "Arial", 16, "", ""
  222.  
  223. ShowWindow parentWin, SW_SHOWDEFAULT
  224. UpdateWindow parentWin
  225.  
  226. While GetMessage(Offset(msg), 0, 0, 0)
  227.     TranslateMessage Offset(msg)
  228.     DispatchMessage Offset(msg)
  229.  
  230. System Val(Str$(msg.wParam))
  231.  
  232. Function WindowProc%& (hwnd As Offset, uMsg As Unsigned Long, wParam As Unsigned Offset, lParam As Offset)
  233.     Select Case uMsg
  234.         Case WM_CLOSE
  235.             WindowProc = DefWindowProc(hwnd, uMsg, wParam, lParam)
  236.         Case WM_DESTROY
  237.             PostQuitMessage 0
  238.             WindowProc = 0
  239.             Exit Function
  240.         Case WM_COMMAND
  241.             Select Case lParam
  242.                 Case browseBtn
  243.                     APKfile = ComDlgFileName("Open APK Package", Dir$("downloads"), "Android APK Files(*.APK)|*.APK", 1, 0) + Chr$(0)
  244.                     SetWindowText outputBox, Offset(APKfile)
  245.                 Case installBtn
  246.                     If APKfile <> "" And APKfile <> Chr$(0) Then
  247.                         Dim As String stdout
  248.                         stdout = pipecom_lite("adb connect 127.0.0.1:58526")
  249.                         If InStr(stdout, "cannot connect") = 0 Then
  250.                             Console On
  251.                             Shell "adb install " + APKfile
  252.                             Console Off
  253.                         Else
  254.                             SoftError "Connection failure", "adb failed to connect to the Windows Subsystem for Android host"
  255.                         End If
  256.                     End If
  257.             End Select
  258.         Case Else
  259.             WindowProc = DefWindowProc(hwnd, uMsg, wParam, lParam)
  260.     End Select
  261.  
  262. Function NewEditBox%& (x As Long, y As Long, w As Long, h As Long, style As String, defaultText As String)
  263.     Dim As Long flags
  264.     style = UCase$(style)
  265.     flags = WS_CHILD Or WS_VISIBLE
  266.     If InStr(style, "NOWRAP") Then
  267.         flags = flags Or WS_VSCROLL Or WS_HSCROLL Or ES_AUTOHSCROLL Or ES_AUTOVSCROLL Or ES_LEFT Or ES_MULTILINE Or ES_WANTRETURN
  268.     ElseIf InStr(style, "WRAP") Then
  269.         flags = flags Or WS_VSCROLL Or ES_AUTOVSCROLL Or ES_LEFT Or ES_MULTILINE Or ES_WANTRETURN
  270.     Else
  271.         flags = flags Or ES_LEFT
  272.     End If
  273.     If InStr(style, "READONLY") Then
  274.         flags = flags Or ES_READONLY
  275.     End If
  276.     Dim As String class: class = WC_EDIT + Chr$(0)
  277.     defaultText = defaultText + Chr$(0)
  278.     NewEditBox = CreateWindowEx(0, Offset(class), Offset(defaultText), flags, x, y, w, h, parentWin, 0, hInstance, 0)
  279.  
  280. Function WindowHeight& ()
  281.     Dim As RECT rect
  282.     GetWindowRect parentWin, Offset(rect)
  283.     WindowHeight = rect.bottom - rect.top
  284.  
  285. Function WindowWidth& ()
  286.     Dim As RECT rect
  287.     GetWindowRect parentWin, Offset(rect)
  288.     WindowWidth = rect.right - rect.left
  289.  
  290. Sub MoveWindow (X As Long, Y As Long)
  291.     Const SWP_NOSIZE = &H0001
  292.     SetWindowPos parentWin, 0, X, Y, 0, 0, SWP_NOSIZE
  293.  
  294. Sub ResizeWindow (w As Long, h As Long)
  295.     Const SWP_NOMOVE = &H0002
  296.     SetWindowPos parentWin, 0, 0, 0, w, h, SWP_NOMOVE
  297.  
  298. Function WindowTitle$ ()
  299.     Dim As String wintitle: wintitle = Space$(260)
  300.     GetWindowText parentWin, Offset(wintitle), Len(wintitle)
  301.     WindowTitle = wintitle
  302.  
  303. Sub SetFont (controlHandle As Offset, fontName As String * 32, __height As Long, style As String, weightStyle As String)
  304.     Dim As Offset __font
  305.     Dim As Byte bold, underline, strikeout, italic
  306.     Dim As Long weight
  307.     style = UCase$(style)
  308.     If InStr(style, "UNDERLINE") Then underline = -1
  309.     If InStr(style, "STRIKEOUT") Then strikeout = -1
  310.     If InStr(style, "ITALIC") Then italic = -1
  311.     Select Case UCase$(weightStyle)
  312.         Case "THIN"
  313.             weight = 100
  314.         Case "EXTRALIGHT", "ULTRALIGHT"
  315.             weight = 200
  316.         Case "LIGHT"
  317.             weight = 300
  318.         Case "NORMAL", "REGULAR"
  319.             weight = 400
  320.         Case "MEDIUM"
  321.             weight = 500
  322.         Case "SEMIBOLD", "DEMIBOLD"
  323.             weight = 600
  324.         Case "BOLD"
  325.             weight = 700
  326.         Case "EXTRABOLD", "ULTRABOLD"
  327.             weight = 800
  328.         Case "HEAVY", "BLACK"
  329.             weight = 900
  330.         Case Else
  331.             weight = 0
  332.     End Select
  333.     Dim As Long FF_DECORATIVE: FF_DECORATIVE = _SHL(5, 4)
  334.     Dim As Long FF_MODERN: FF_MODERN = _SHL(3, 4)
  335.     Dim As Long FF_ROMAN: FF_ROMAN = _SHL(1, 4)
  336.     Dim As Long FF_SCRIPT: FF_SCRIPT = _SHL(4, 4)
  337.     Dim As Long FF_SWISS: FF_SWISS = _SHL(2, 4)
  338.     __font = CreateFont(__height, 0, 0, 0, weight, italic, underline, strikeout, 0, 0, 0, 5, FF_DECORATIVE Or FF_MODERN Or FF_ROMAN Or FF_SCRIPT Or FF_SWISS, fontName + Chr$(0))
  339.     If Font Then
  340.         SendMessage controlHandle, WM_SETFONT, __font, MAKELPARAM(-1, 0)
  341.     End If
  342.  
  343. Sub ToggleEnable (controlHandle As Offset, __toggle As Byte)
  344.     Select Case __toggle
  345.         Case 1
  346.             EnableWindow controlHandle, -1
  347.         Case 0
  348.             EnableWindow controlHandle, 0
  349.     End Select
  350.  
  351. Sub StepProgressBar (pbHandle As Offset, amount As Unsigned Long)
  352.     Dim As PBRANGE range
  353.     SendMessage pbHandle, PBM_GETRANGE, 0, Offset(range)
  354.     Dim As Offset currentpos: currentpos = SendMessage(pbHandle, PBM_GETPOS, 0, 0)
  355.     If currentpos >= range.iHigh Then Exit Sub
  356.     SendMessage pbHandle, PBM_DELTAPOS, amount, 0
  357.  
  358. Sub SetProgressBarVal (pbHandle As Offset, newValue As Unsigned Long)
  359.     Dim As PBRANGE range
  360.     SendMessage pbHandle, PBM_GETRANGE, 0, Offset(range)
  361.     Dim As Offset currentpos: currentpos = SendMessage(pbHandle, PBM_GETPOS, 0, 0)
  362.     If currentpos >= range.iHigh Or newValue > range.iHigh Or newValue < range.iLow Then Exit Sub
  363.     SendMessage pbHandle, PBM_SETPOS, newValue, 0
  364.  
  365. Sub UpdateProgressBar (pbHandle As Offset)
  366.     Dim As PBRANGE range
  367.     SendMessage pbHandle, PBM_GETRANGE, 0, Offset(range)
  368.     Dim As Offset currentpos: currentpos = SendMessage(pbHandle, PBM_GETPOS, 0, 0)
  369.     If currentpos >= range.iHigh Then Exit Sub
  370.     SendMessage pbHandle, PBM_STEPIT, 0, 0
  371.  
  372. Sub SetProgressBarState (pbHandle As Offset, state As Unsigned Byte)
  373.     Select Case state
  374.         Case 1
  375.             SendMessage pbHandle, PBM_SETSTATE, PBST_NORMAL, 0
  376.         Case 2
  377.             SendMessage pbHandle, PBM_SETSTATE, PBST_ERROR, 0
  378.         Case 3
  379.             SendMessage pbHandle, PBM_SETSTATE, PBST_PAUSED, 0
  380.     End Select
  381.  
  382. Rem $Include:'pipecomqb64.bas'
  383. Rem $Include:'OpenSave.BM'
  384. Rem $Include:'MessageBox.BM'

A couple videos showing the code in action:

* pipecomqb64.bas (Filesize: 7.63 KB, Downloads: 192)
* OpenSave.BI (Filesize: 1.04 KB, Downloads: 193)
* OpenSave.BM (Filesize: 8.94 KB, Downloads: 189)
* MessageBox.BM (Filesize: 5.99 KB, Downloads: 205)
* win.h (Filesize: 0.41 KB, Downloads: 187)
* makeint.h (Filesize: 0.06 KB, Downloads: 218)
* unicodetoansi.bas (Filesize: 1.74 KB, Downloads: 195)
* preproc.h (Filesize: 0.51 KB, Downloads: 209)

* WSA-icon.ico (Filesize: 4.19 KB, Dimensions: 32x32, Views: 403)
Shuwatch!

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
@SpriggsySpriggs

Thanks for sharing, I can't test it yet because I don't have the necessary operating system.
« Last Edit: October 24, 2021, 12:58:22 pm by Petr »

Offline jack

  • Seasoned Forum Regular
  • Posts: 408
    • View Profile
Quote
Windows Subsystem for Android™️ enables your Windows 11 device to run Android applications that are available in the Amazon Appstore.
Windows 11 for android applications?

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
@jack Windows 11 allows you to run Android apps similar to how 10 allowed for Linux applications.
Shuwatch!