GitXplorerGitXplorer
G

community.wsa.sdk

public
5 stars
0 forks
0 issues

Commits

List of commits on branch main.
Verified
d492ced6f7cfc352609b4f6bc16fa3250120c741

Add unauthorized device type (#13)

GGitii committed 3 years ago
Verified
5cfe46cc804275046ef9aeefa2ed923b95f45851

Trim adb output (#12)

GGitii committed 3 years ago
Verified
b7e2d909cced87c0f990a883338bd85baff06dc7

Increase test coverage bounds (#11)

GGitii committed 3 years ago
Verified
cac185a1aaf4085ee86b0e7f6dabb3d94402515c

Restart server on adb timeout (#10)

GGitii committed 3 years ago
Verified
bf1a1e1370abcdda22d6eaa41d684e07587d773b

Remove `1` from cli command (#7)

GGitii committed 3 years ago
Verified
851d371e16eaad3bb746f8f049fa558932258fe7

Include standarderror into error details (#8)

GGitii committed 3 years ago

README

The README file for this repository.

Community SDK for Windows Subsystem for Android

This project contains a WSA API for Windows developers who wants to integrate WSA features into existing Windows applications. You can enumerate and query packages, install and uninstall packages via C# classes.

Physical devices and other emulators are also supported (see section WSA and other android devices (for example pysical devices)).

Supported frameworks

  • .Net 5 (net5.0-windows10.0.19041.0 or higher)
  • .Net 6 (net6.0-windows10.0.19041.0 or higher)

Supported Operating Systems

  • Windows 10 19041 or higher
  • Windows 11

How to use

There are one default implementations of IWsaApi.

It uses the wsaclient.exe and adb.exe executable and (mostly) public information stored in the registry.

platform-tools need to be installed. They include the adb.exe. The folder containing adb.exe must be added to %PATH%.

How to install

This package is available on nuget.org.
You can add a reference using dotnet:

dotnet add package Community.Wsa.Sdk

API

WSA Api

Class Description
WsaApi Check if WSA is installed or running. Allows you to start WSA if needed.
WsaPackageManager List all installed packages, install new packages, upgrade, downgrade or uninstall existing packages. Uses wsaclient.exe (and adb.exe for packages installation).
AdbPackageManager List all installed packages, install new packages, upgrade, downgrade or uninstall existing packages. Uses adb.exe for all operations.

wsaclient.exe sometimes locks up and never finishes. It is recommended to use WsaPackageManager for readonly operations (like querying of packages) and AdbPackageManager for write operations like installing and uninstalling packages. Both implement the same interface (IPackageManager).

Code Examples

Basic usage of wsa api

using Community.Wsa.Sdk;

// Create instance
var api = new WsaApi();

// Check if wsa is supported
bool isSupported = api.IsWsaSupported();

// OR check if wsa is supported and also know why not:
string reason;
bool isSupported = api.IsWsaSupported(out reason);

// Check if wsa is installed
bool isSupported = api.IsWsaInstalled();

// Check if wsa is running
bool isRunning = api.IsRunning();

// Ensures that WSA is ready (started and adb is connected).
// NOTE: will fail if developer mode is not activated.
await api.EnsureWsaIsReadyAsync();

// Starts the WSA service if it's not already running.
await api.StartServiceAsync();

Basic commands

using Community.Wsa.Sdk;

// Setup
var api = new WsaApi();
var pkgm = new WsaPackageManager();

// Get the device serial number of WSA
// Usually this is 127.0.01:58526 or localhost:58526
// but that depends how (and who) connected adb to the WSA device.
// GetDeviceIdAsync will find it regardless.
var deviceId = await api.GetDeviceIdAsync();

// assume that we have a valid path to an existing apk file
// for example C:\app.apk
var apkPath = "..."; 

// Install package
await pkgm.InstallPackageAsync(deviceId, apkPath);

// Uninstall package 
await pkgm.UninstallPackageAsync(deviceId, "package.name.of.the.app");

Available methods for IPackageManager

/// <summary>
/// Manages apps.
/// </summary>
public interface IPackageManager
{
    /// <summary>
    /// Install a new or upgrade an existing package.
    /// </summary>
    /// <param name="deviceId">Use device with given serial</param>
    /// <param name="filePath">File path to the app package.</param>
    /// <param name="progress">Optional provider for reporting installation updates.</param>
    public Task InstallPackageAsync(string deviceId, string filePath, IProgress<string>? progress = null);

    /// <summary>
    /// Returns all installed packages.
    /// </summary>
    /// <param name="deviceId">Use device with given serial</param>
    public Task<PackageInfo[]> GetAllInstalledPackagesAsync(string deviceId);

    /// <summary>
    /// Gets package info of the specified installed package.
    /// </summary>
    /// <param name="deviceId">Use device with given serial</param>
    /// <param name="packageName">Name of the package which info should be fetched.</param>
    /// <returns>Info of the installed package or <c>null</c> if the package isn't installed.</returns>
    public Task<PackageInfo?> GetInstalledPackageAsync(string deviceId, string packageName);

    /// <summary>
    /// Checks whether the specified package is installed.
    /// </summary>
    /// <param name="deviceId">Use device with given serial</param>
    /// <param name="packageName">The name of the package which will be checked.</param>
    /// <returns><c>true</c> if the package is installed, otherwise <c>false</c>.</returns>
    public Task<bool> IsPackageInstalledAsync(string deviceId, string packageName);

    /// <summary>
    /// Uninstalls the specified package.
    /// </summary>
    /// <param name="deviceId">Use device with given serial</param>
    /// <param name="packageName">The name of the package which will be uninstalled.</param>
    public Task UninstallPackageAsync(string deviceId, string packageName);

    /// <summary>
    /// Launches the installed package.
    /// </summary>
    /// <param name="deviceId">Use device with given serial</param>
    /// <param name="packageName">The name of the package which will be launched.</param>
    public Task LaunchAsync(string deviceId, string packageName);
}

Unit tests and Mocks

All classes in Community.Wsa.Sdk implement interfaces, for example WsaApi implements IWsaApi. If you already use mocking frameworks & DI, use them to create a test friendly instance, for example using FakeItEasy:

var api = A.Fake<IWsaApi>();

You can also mock specific parts of the implementation by passing custom implementations in the constructor:

/*
Signature of the constructor:
public WsaApi(
    IAdb? adb = null,
    IWsaClient? wsaClient = null,
    IIo? io = null,
    IEnvironment? environment = null,
    IProcessManager? processManager = null
)
*/

// mock only the IIo logic
var api = new WsaApi(
    io: A.Fake<IIo>()
);

WSA and Developer Mode

There is no known way to programmatically enable Developer Mode for WSA. It needs to be done manually, by the user.

Community.Wsa.Sdk requires Developer Mode to be enabled for all operations that rely on adb (all package related operations except querying and listing packages when WsaPackageManager is used).

WSA and other android devices (for example pysical devices)

The WSA device is regular android system (running in an emulator). Community.Wsa.Sdk will work with any android system (physical or emulated), as long as developer mode is enabled.

Use AdbClient (for example ListDevicesAsync for listing all known devices) and AdbPackageManager (or AdbClient) for managing the packages.