diff --git a/.filenesting.json b/.filenesting.json new file mode 100644 index 0000000..2c46e1b --- /dev/null +++ b/.filenesting.json @@ -0,0 +1,16 @@ +{ + "help": "https://go.microsoft.com/fwlink/?linkid=866610", + "dependentFileProviders": { + "add": { + "pathSegment": { + "add": { + ".*": [ + ".bin", + ".cs", + ".txt" + ] + } + } + } + } +} \ No newline at end of file diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 9eba94a..cd13217 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -14,7 +14,7 @@ on: workflow_dispatch: env: - DOTNET_VERSION: '8.0.x' # The .NET SDK version to use + DOTNET_VERSION: '9.0.x' # The .NET SDK version to use jobs: build-and-test: diff --git a/.gitignore b/.gitignore index f11eb3a..95ad761 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. ## -## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore +## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore # User-specific files *.rsuser @@ -29,14 +29,11 @@ x86/ bld/ [Bb]in/ [Oo]bj/ -[Oo]ut/ [Ll]og/ #[Ll]ogs/ # Visual Studio 2015/2017 cache/options directory .vs/ -# JetBrains Rider options directory -.idea/ # Uncomment if you have tasks that create the project's static files in wwwroot #wwwroot/ @@ -85,6 +82,8 @@ StyleCopReport.xml *.pgc *.pgd *.rsp +# but not Directory.Build.rsp, as it configures directory-level build defaults +!Directory.Build.rsp *.sbr *.tlb *.tli @@ -93,6 +92,7 @@ StyleCopReport.xml *.tmp_proj *_wpftmp.csproj *.log +*.tlog *.vspscc *.vssscc .builds @@ -296,6 +296,17 @@ node_modules/ # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) *.vbw +# Visual Studio 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files +*.ncb +*.aps + # Visual Studio LightSwitch build output **/*.HTMLClient/GeneratedArtifacts **/*.DesktopClient/GeneratedArtifacts @@ -352,6 +363,9 @@ ASALocalRun/ # Local History for Visual Studio .localhistory/ +# Visual Studio History (VSHistory) files +.vshistory/ + # BeatPulse healthcheck temp database healthchecksdb @@ -363,3 +377,24 @@ MigrationBackup/ # Fody - auto-generated XML schema FodyWeavers.xsd + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +*.sln.iml \ No newline at end of file diff --git a/AdvancedSharpAdbClient.Tests/AdbClientTests.Async.cs b/AdvancedSharpAdbClient.Tests/AdbClientTests.Async.cs index 01d5065..ba1c14c 100644 --- a/AdvancedSharpAdbClient.Tests/AdbClientTests.Async.cs +++ b/AdvancedSharpAdbClient.Tests/AdbClientTests.Async.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; using System.Globalization; using System.IO; using System.Linq; @@ -367,7 +365,7 @@ await File.ReadAllBytesAsync("Assets/Framebuffer.bin") Assert.Equal(1u, header.Version); Assert.Equal(0u, header.ColorSpace); -#if WINDOWS +#if HAS_IMAGING if (!OperatingSystem.IsWindows()) { return; } using Bitmap image = framebuffer.ToImage(); @@ -937,7 +935,7 @@ await RunTestAsync( () => TestClient.InstallCommitAsync(Device, "936013062")); } -#if WINDOWS10_0_17763_0_OR_GREATER +#if WINDOWS10_0_18362_0_OR_GREATER /// /// Tests the method. /// @@ -963,7 +961,7 @@ public async Task InstallWinRTAsyncTest() byte[] response = "Success\n"u8.ToArray(); - StorageFile storageFile = await StorageFile.GetFileFromPathAsync(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Assets\TestApp\base.apk")); + StorageFile storageFile = await StorageFile.GetFileFromPathAsync(Path.GetFullPath("Assets/TestApp/base.apk")); using (IRandomAccessStreamWithContentType stream = await storageFile.OpenReadAsync()) { string[] requests = @@ -1012,7 +1010,7 @@ public async Task InstallMultipleWinRTAsyncTest() } } - StorageFile storageFile = await StorageFile.GetFileFromPathAsync(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Assets\TestApp\split_config.arm64_v8a.apk")); + StorageFile storageFile = await StorageFile.GetFileFromPathAsync(Path.GetFullPath("Assets/TestApp/split_config.arm64_v8a.apk")); using IRandomAccessStreamWithContentType abiStream = await storageFile.OpenReadAsync(); string[] requests = @@ -1086,9 +1084,9 @@ public async Task InstallMultipleWinRTWithBaseAsyncTest() } } - StorageFile storageFile = await StorageFile.GetFileFromPathAsync(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Assets\TestApp\base.apk")); + StorageFile storageFile = await StorageFile.GetFileFromPathAsync(Path.GetFullPath("Assets/TestApp/base.apk")); using IRandomAccessStreamWithContentType baseStream = await storageFile.OpenReadAsync(); - storageFile = await StorageFile.GetFileFromPathAsync(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Assets\TestApp\split_config.arm64_v8a.apk")); + storageFile = await StorageFile.GetFileFromPathAsync(Path.GetFullPath("Assets/TestApp/split_config.arm64_v8a.apk")); using IRandomAccessStreamWithContentType abiStream = await storageFile.OpenReadAsync(); string[] requests = @@ -1153,7 +1151,7 @@ public async Task InstallWriteWinRTAsyncTest() } } - StorageFile storageFile = await StorageFile.GetFileFromPathAsync(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Assets\TestApp\base.apk")); + StorageFile storageFile = await StorageFile.GetFileFromPathAsync(Path.GetFullPath("Assets/TestApp/base.apk")); using (IRandomAccessStreamWithContentType stream = await storageFile.OpenReadAsync()) { string[] requests = diff --git a/AdvancedSharpAdbClient.Tests/AdbClientTests.cs b/AdvancedSharpAdbClient.Tests/AdbClientTests.cs index b8401f5..4beaef4 100644 --- a/AdvancedSharpAdbClient.Tests/AdbClientTests.cs +++ b/AdvancedSharpAdbClient.Tests/AdbClientTests.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; using System.Globalization; using System.IO; using System.Linq; @@ -489,7 +487,7 @@ public void GetFrameBufferTest() Assert.Equal(1u, header.Version); Assert.Equal(0u, header.ColorSpace); -#if WINDOWS +#if HAS_IMAGING if (!OperatingSystem.IsWindows()) { return; } using Bitmap image = framebuffer.ToImage(); @@ -1141,7 +1139,7 @@ public void GetFeatureSetTest() public void CloneTest() { Assert.True(TestClient is ICloneable); -#if WINDOWS10_0_17763_0_OR_GREATER +#if WINDOWS10_0_18362_0_OR_GREATER Assert.True(TestClient is ICloneable); #endif AdbClient client = TestClient.Clone(); diff --git a/AdvancedSharpAdbClient.Tests/AdvancedSharpAdbClient.Tests.csproj b/AdvancedSharpAdbClient.Tests/AdvancedSharpAdbClient.Tests.csproj index 03de9f0..6bb67e2 100644 --- a/AdvancedSharpAdbClient.Tests/AdvancedSharpAdbClient.Tests.csproj +++ b/AdvancedSharpAdbClient.Tests/AdvancedSharpAdbClient.Tests.csproj @@ -1,10 +1,11 @@  + True latest $(NoWarn);CS1591 - + @@ -19,13 +20,13 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + + + + runtime; build; native; contentfiles; analyzers; buildtransitive @@ -39,5 +40,9 @@ PreserveNewest + + + $(DefineConstants);HAS_IMAGING + diff --git a/AdvancedSharpAdbClient.Tests/DeviceCommands/DeviceClientTexts.Async.cs b/AdvancedSharpAdbClient.Tests/DeviceCommands/DeviceClientTexts.Async.cs index 598da93..2319523 100644 --- a/AdvancedSharpAdbClient.Tests/DeviceCommands/DeviceClientTexts.Async.cs +++ b/AdvancedSharpAdbClient.Tests/DeviceCommands/DeviceClientTexts.Async.cs @@ -105,7 +105,7 @@ public async Task DumpScreenAsyncTest() Assert.Equal(doc, xml); } -#if WINDOWS10_0_17763_0_OR_GREATER +#if WINDOWS10_0_18362_0_OR_GREATER /// /// Tests the method. /// diff --git a/AdvancedSharpAdbClient.Tests/DeviceCommands/DeviceClientTexts.cs b/AdvancedSharpAdbClient.Tests/DeviceCommands/DeviceClientTexts.cs index 23cb8b5..382faf3 100644 --- a/AdvancedSharpAdbClient.Tests/DeviceCommands/DeviceClientTexts.cs +++ b/AdvancedSharpAdbClient.Tests/DeviceCommands/DeviceClientTexts.cs @@ -191,7 +191,7 @@ public void DumpScreenTest() Assert.Equal(doc, xml); } -#if WINDOWS10_0_17763_0_OR_GREATER +#if WINDOWS10_0_18362_0_OR_GREATER /// /// Tests the method. /// diff --git a/AdvancedSharpAdbClient.Tests/DeviceCommands/Models/VersionInfoTests.cs b/AdvancedSharpAdbClient.Tests/DeviceCommands/Models/VersionInfoTests.cs index 8197d47..8d9da8f 100644 --- a/AdvancedSharpAdbClient.Tests/DeviceCommands/Models/VersionInfoTests.cs +++ b/AdvancedSharpAdbClient.Tests/DeviceCommands/Models/VersionInfoTests.cs @@ -32,7 +32,7 @@ public void TryAsVersionTest(int versionCode, string versionName, bool expected) } } -#if WINDOWS10_0_17763_0_OR_GREATER +#if WINDOWS10_0_18362_0_OR_GREATER /// /// Tests the method. /// diff --git a/AdvancedSharpAdbClient.Tests/DeviceCommands/Receivers/GetPropReceiverTests.cs b/AdvancedSharpAdbClient.Tests/DeviceCommands/Receivers/GetPropReceiverTests.cs index 7463316..181be70 100644 --- a/AdvancedSharpAdbClient.Tests/DeviceCommands/Receivers/GetPropReceiverTests.cs +++ b/AdvancedSharpAdbClient.Tests/DeviceCommands/Receivers/GetPropReceiverTests.cs @@ -14,7 +14,7 @@ public void ListPropertiesTest() }; DummyAdbClient client = new(); - client.Commands["shell:/system/bin/getprop"] = + client.Commands["shell:/system/bin/getprop"] = """ [init.svc.BGW]: [running] [init.svc.MtkCodecService]: [running] diff --git a/AdvancedSharpAdbClient.Tests/Dummys/DummyAdbClient.cs b/AdvancedSharpAdbClient.Tests/Dummys/DummyAdbClient.cs index ad40f25..7d7be23 100644 --- a/AdvancedSharpAdbClient.Tests/Dummys/DummyAdbClient.cs +++ b/AdvancedSharpAdbClient.Tests/Dummys/DummyAdbClient.cs @@ -26,8 +26,8 @@ public void ExecuteRemoteCommand(string command, DeviceData device) => public void ExecuteRemoteCommand(string command, DeviceData device, IShellOutputReceiver receiver, Encoding encoding) => ExecuteServerCommand("shell", command, receiver, encoding); - public IEnumerable ExecuteRemoteCommand(string command, DeviceData device, Encoding encoding) => - ExecuteServerCommand("shell", command, encoding); + public IEnumerable ExecuteRemoteEnumerable(string command, DeviceData device, Encoding encoding) => + ExecuteServerEnumerable("shell", command, encoding); public Task ExecuteRemoteCommandAsync(string command, DeviceData device, CancellationToken cancellationToken = default) => ExecuteServerCommandAsync("shell", command, cancellationToken); @@ -35,8 +35,8 @@ public Task ExecuteRemoteCommandAsync(string command, DeviceData device, Cancell public Task ExecuteRemoteCommandAsync(string command, DeviceData device, IShellOutputReceiver receiver, Encoding encoding, CancellationToken cancellationToken = default) => ExecuteServerCommandAsync("shell", command, receiver, encoding, cancellationToken); - public IAsyncEnumerable ExecuteRemoteCommandAsync(string command, DeviceData device, Encoding encoding, CancellationToken cancellationToken) => - ExecuteServerCommandAsync("shell", command, encoding, cancellationToken); + public IAsyncEnumerable ExecuteRemoteEnumerableAsync(string command, DeviceData device, Encoding encoding, CancellationToken cancellationToken) => + ExecuteServerEnumerableAsync("shell", command, encoding, cancellationToken); public void ExecuteServerCommand(string target, string command) { @@ -89,7 +89,7 @@ public void ExecuteServerCommand(string target, string command, IShellOutputRece public void ExecuteServerCommand(string target, string command, IAdbSocket socket, IShellOutputReceiver receiver, Encoding encoding) => ExecuteServerCommand(target, command, receiver, encoding); - public IEnumerable ExecuteServerCommand(string target, string command, Encoding encoding) + public IEnumerable ExecuteServerEnumerable(string target, string command, Encoding encoding) { StringBuilder requestBuilder = new(); if (!StringExtensions.IsNullOrWhiteSpace(target)) @@ -115,8 +115,8 @@ public IEnumerable ExecuteServerCommand(string target, string command, E } } - public IEnumerable ExecuteServerCommand(string target, string command, IAdbSocket socket, Encoding encoding) => - ExecuteServerCommand(target, command, encoding); + public IEnumerable ExecuteServerEnumerable(string target, string command, IAdbSocket socket, Encoding encoding) => + ExecuteServerEnumerable(target, command, encoding); public async Task ExecuteServerCommandAsync(string target, string command, CancellationToken cancellationToken = default) { @@ -171,7 +171,7 @@ public async Task ExecuteServerCommandAsync(string target, string command, IShel public Task ExecuteServerCommandAsync(string target, string command, IAdbSocket socket, IShellOutputReceiver receiver, Encoding encoding, CancellationToken cancellationToken) => ExecuteServerCommandAsync(target, command, receiver, encoding, cancellationToken); - public async IAsyncEnumerable ExecuteServerCommandAsync(string target, string command, Encoding encoding, [EnumeratorCancellation] CancellationToken cancellationToken) + public async IAsyncEnumerable ExecuteServerEnumerableAsync(string target, string command, Encoding encoding, [EnumeratorCancellation] CancellationToken cancellationToken) { StringBuilder requestBuilder = new(); if (!StringExtensions.IsNullOrWhiteSpace(target)) @@ -197,8 +197,8 @@ public async IAsyncEnumerable ExecuteServerCommandAsync(string target, s } } - public IAsyncEnumerable ExecuteServerCommandAsync(string target, string command, IAdbSocket socket, Encoding encoding, CancellationToken cancellationToken = default) => - ExecuteServerCommandAsync(target, command, socket, encoding, cancellationToken); + public IAsyncEnumerable ExecuteServerEnumerableAsync(string target, string command, IAdbSocket socket, Encoding encoding, CancellationToken cancellationToken = default) => + ExecuteServerEnumerableAsync(target, command, socket, encoding, cancellationToken); #region Not Implemented diff --git a/AdvancedSharpAdbClient.Tests/Dummys/DummyAdbSocket.cs b/AdvancedSharpAdbClient.Tests/Dummys/DummyAdbSocket.cs index 2821b76..c54d040 100644 --- a/AdvancedSharpAdbClient.Tests/Dummys/DummyAdbSocket.cs +++ b/AdvancedSharpAdbClient.Tests/Dummys/DummyAdbSocket.cs @@ -11,7 +11,7 @@ namespace AdvancedSharpAdbClient.Tests /// /// A mock implementation of the class. /// - internal class DummyAdbSocket : IDummyAdbSocket, ICloneable + internal partial class DummyAdbSocket : IDummyAdbSocket, ICloneable { /// /// Use this message to cause and to throw @@ -314,7 +314,5 @@ public async Task ReconnectAsync(bool isForce, CancellationToken cancellationTok SyncRequests = SyncRequests, ShellStreams = ShellStreams }; - - object ICloneable.Clone() => Clone(); } } diff --git a/AdvancedSharpAdbClient.Tests/Dummys/DummySyncService.cs b/AdvancedSharpAdbClient.Tests/Dummys/DummySyncService.cs index 17a27e1..f5008ad 100644 --- a/AdvancedSharpAdbClient.Tests/Dummys/DummySyncService.cs +++ b/AdvancedSharpAdbClient.Tests/Dummys/DummySyncService.cs @@ -9,7 +9,7 @@ namespace AdvancedSharpAdbClient.Tests /// /// A mock implementation of the class. /// - internal class DummySyncService : ISyncService + internal partial class DummySyncService : ISyncService { public Dictionary UploadedFiles { get; } = []; diff --git a/AdvancedSharpAdbClient.Tests/Dummys/DummyTcpSocket.cs b/AdvancedSharpAdbClient.Tests/Dummys/DummyTcpSocket.cs index 9223dfd..aa0c20e 100644 --- a/AdvancedSharpAdbClient.Tests/Dummys/DummyTcpSocket.cs +++ b/AdvancedSharpAdbClient.Tests/Dummys/DummyTcpSocket.cs @@ -10,7 +10,7 @@ namespace AdvancedSharpAdbClient.Tests /// /// A mock implementation of the class. /// - internal class DummyTcpSocket : ITcpSocket, ICloneable + internal partial class DummyTcpSocket : ITcpSocket, ICloneable { /// /// The stream from which the reads. @@ -114,16 +114,10 @@ public async ValueTask SendAsync(ReadOnlyMemory buffer, SocketFlags s public byte[] GetBytesSent() => OutputStream.ToArray(); - public DummyTcpSocket Clone() + public DummyTcpSocket Clone() => new() { - DummyTcpSocket socket = new() - { - Connected = true, - ReceiveBufferSize = ReceiveBufferSize - }; - return socket; - } - - object ICloneable.Clone() => Clone(); + Connected = true, + ReceiveBufferSize = ReceiveBufferSize + }; } } diff --git a/AdvancedSharpAdbClient.Tests/Dummys/TracingAdbSocket.cs b/AdvancedSharpAdbClient.Tests/Dummys/TracingAdbSocket.cs index 02f08be..83e780b 100644 --- a/AdvancedSharpAdbClient.Tests/Dummys/TracingAdbSocket.cs +++ b/AdvancedSharpAdbClient.Tests/Dummys/TracingAdbSocket.cs @@ -8,7 +8,7 @@ namespace AdvancedSharpAdbClient.Tests { - internal class TracingAdbSocket(EndPoint endPoint) : AdbSocket(endPoint), IDummyAdbSocket + internal partial class TracingAdbSocket(EndPoint endPoint) : AdbSocket(endPoint), IDummyAdbSocket { private readonly EndPoint endPoint = endPoint; diff --git a/AdvancedSharpAdbClient.Tests/Extensions/AdbClientExtensionsTests.Async.cs b/AdvancedSharpAdbClient.Tests/Extensions/AdbClientExtensionsTests.Async.cs index be84f69..7603dcd 100644 --- a/AdvancedSharpAdbClient.Tests/Extensions/AdbClientExtensionsTests.Async.cs +++ b/AdvancedSharpAdbClient.Tests/Extensions/AdbClientExtensionsTests.Async.cs @@ -44,7 +44,7 @@ public async Task ExecuteServerCommandAsyncTest() Assert.Equal(default, x.ArgAt(5)); return Task.CompletedTask; }); - _ = client.ExecuteServerCommandAsync(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + _ = client.ExecuteServerEnumerableAsync(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) .Returns(x => { Assert.Equal(target, x.ArgAt(0)); @@ -53,7 +53,7 @@ public async Task ExecuteServerCommandAsyncTest() Assert.Equal(default, x.ArgAt(3)); return result.AsEnumerableAsync(x.ArgAt(3)); }); - _ = client.ExecuteServerCommandAsync(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + _ = client.ExecuteServerEnumerableAsync(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) .Returns(x => { Assert.Equal(target, x.ArgAt(0)); @@ -70,8 +70,8 @@ public async Task ExecuteServerCommandAsyncTest() await client.ExecuteServerCommandAsync(target, command, socket, predicate); await client.ExecuteServerCommandAsync(target, command, predicate, encoding); await client.ExecuteServerCommandAsync(target, command, socket, predicate, encoding); - Assert.Equal(result, await AdbClientExtensions.ExecuteServerCommandAsync(client, target, command).ToListAsync()); - Assert.Equal(result, await AdbClientExtensions.ExecuteServerCommandAsync(client, target, command, socket).ToListAsync()); + Assert.Equal(result, await client.ExecuteServerEnumerableAsync(target, command).ToListAsync()); + Assert.Equal(result, await client.ExecuteServerEnumerableAsync(target, command, socket).ToListAsync()); } [Fact] @@ -95,7 +95,7 @@ public async Task ExecuteRemoteCommandAsyncTest() Assert.Equal(default, x.ArgAt(4)); return Task.CompletedTask; }); - _ = client.ExecuteRemoteCommandAsync(Arg.Any(), device, Arg.Any(), Arg.Any()) + _ = client.ExecuteRemoteEnumerableAsync(Arg.Any(), device, Arg.Any(), Arg.Any()) .Returns(x => { Assert.Equal(command, x.ArgAt(0)); @@ -108,7 +108,7 @@ public async Task ExecuteRemoteCommandAsyncTest() await client.ExecuteRemoteCommandAsync(command, device, receiver); await client.ExecuteRemoteCommandAsync(command, device, predicate); await client.ExecuteRemoteCommandAsync(command, device, predicate, encoding); - Assert.Equal(result, await AdbClientExtensions.ExecuteRemoteCommandAsync(client, command, device).ToListAsync()); + Assert.Equal(result, await client.ExecuteRemoteEnumerableAsync(command, device).ToListAsync()); } [Fact] diff --git a/AdvancedSharpAdbClient.Tests/Extensions/AdbClientExtensionsTests.cs b/AdvancedSharpAdbClient.Tests/Extensions/AdbClientExtensionsTests.cs index 5333a83..14b11fd 100644 --- a/AdvancedSharpAdbClient.Tests/Extensions/AdbClientExtensionsTests.cs +++ b/AdvancedSharpAdbClient.Tests/Extensions/AdbClientExtensionsTests.cs @@ -41,7 +41,7 @@ public void ExecuteServerCommandTest() Assert.Equal(receiver, x.ArgAt(3)); Assert.Equal(encoding, x.ArgAt(4)); }); - _ = client.ExecuteServerCommand(Arg.Any(), Arg.Any(), Arg.Any()) + _ = client.ExecuteServerEnumerable(Arg.Any(), Arg.Any(), Arg.Any()) .Returns(x => { Assert.Equal(target, x.ArgAt(0)); @@ -49,7 +49,7 @@ public void ExecuteServerCommandTest() Assert.Equal(encoding, x.ArgAt(2)); return result; }); - _ = client.ExecuteServerCommand(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + _ = client.ExecuteServerEnumerable(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) .Returns(x => { Assert.Equal(target, x.ArgAt(0)); @@ -65,8 +65,8 @@ public void ExecuteServerCommandTest() client.ExecuteServerCommand(target, command, socket, predicate); client.ExecuteServerCommand(target, command, predicate, encoding); client.ExecuteServerCommand(target, command, socket, predicate, encoding); - Assert.Equal(result, AdbClientExtensions.ExecuteServerCommand(client, target, command)); - Assert.Equal(result, AdbClientExtensions.ExecuteServerCommand(client, target, command, socket)); + Assert.Equal(result, client.ExecuteServerEnumerable(target, command)); + Assert.Equal(result, client.ExecuteServerEnumerable(target, command, socket)); } [Fact] @@ -88,7 +88,7 @@ public void ExecuteRemoteCommandTest() Assert.Equal(receiver, x.ArgAt(2)); Assert.Equal(encoding, x.ArgAt(3)); }); - _ = client.ExecuteRemoteCommand(Arg.Any(), device, Arg.Any()) + _ = client.ExecuteRemoteEnumerable(Arg.Any(), device, Arg.Any()) .Returns(x => { Assert.Equal(command, x.ArgAt(0)); @@ -100,7 +100,7 @@ public void ExecuteRemoteCommandTest() client.ExecuteRemoteCommand(command, device, receiver); client.ExecuteRemoteCommand(command, device, predicate); client.ExecuteRemoteCommand(command, device, predicate, encoding); - Assert.Equal(result, AdbClientExtensions.ExecuteRemoteCommand(client, command, device)); + Assert.Equal(result, client.ExecuteRemoteEnumerable(command, device)); } [Fact] diff --git a/AdvancedSharpAdbClient.Tests/Extensions/FactoriesLocker.cs b/AdvancedSharpAdbClient.Tests/Extensions/FactoriesLocker.cs index c04988f..bccccc1 100644 --- a/AdvancedSharpAdbClient.Tests/Extensions/FactoriesLocker.cs +++ b/AdvancedSharpAdbClient.Tests/Extensions/FactoriesLocker.cs @@ -7,7 +7,7 @@ namespace AdvancedSharpAdbClient.Tests /// /// Locker for the class. /// - public class FactoriesLocker : IDisposable + public partial class FactoriesLocker : IDisposable { public static SemaphoreSlim SlimLocker { get; } = new(1, 1); diff --git a/AdvancedSharpAdbClient.Tests/Models/FramebufferHeaderTests.cs b/AdvancedSharpAdbClient.Tests/Models/FramebufferHeaderTests.cs index e6fb001..8886933 100644 --- a/AdvancedSharpAdbClient.Tests/Models/FramebufferHeaderTests.cs +++ b/AdvancedSharpAdbClient.Tests/Models/FramebufferHeaderTests.cs @@ -1,6 +1,4 @@ using System; -using System.Drawing; -using System.Drawing.Imaging; using System.IO; using Xunit; @@ -71,7 +69,7 @@ public void ReadFramebufferV2Test() Assert.Equal(data.AsSpan(), [.. header]); } -#if WINDOWS +#if HAS_IMAGING [Fact] public void ToImageTest() { diff --git a/AdvancedSharpAdbClient.Tests/Models/FramebufferTests.cs b/AdvancedSharpAdbClient.Tests/Models/FramebufferTests.cs index 93d453a..ba88bd5 100644 --- a/AdvancedSharpAdbClient.Tests/Models/FramebufferTests.cs +++ b/AdvancedSharpAdbClient.Tests/Models/FramebufferTests.cs @@ -1,6 +1,4 @@ using System; -using System.Drawing; -using System.Drawing.Imaging; using System.IO; using System.Net; using System.Threading.Tasks; @@ -69,7 +67,7 @@ public void RefreshTest() Assert.Equal(1u, header.Version); Assert.Equal(0u, header.ColorSpace); -#if WINDOWS +#if HAS_IMAGING if (!OperatingSystem.IsWindows()) { return; } using Bitmap image = (Bitmap)framebuffer; @@ -132,7 +130,7 @@ public async Task RefreshAsyncTest() Assert.Equal(1u, header.Version); Assert.Equal(0u, header.ColorSpace); -#if WINDOWS +#if HAS_IMAGING if (!OperatingSystem.IsWindows()) { return; } using Bitmap image = (Bitmap)framebuffer; diff --git a/AdvancedSharpAdbClient.Tests/Properties/GlobalUsings.cs b/AdvancedSharpAdbClient.Tests/Properties/GlobalUsings.cs index 0765899..a22aa63 100644 --- a/AdvancedSharpAdbClient.Tests/Properties/GlobalUsings.cs +++ b/AdvancedSharpAdbClient.Tests/Properties/GlobalUsings.cs @@ -13,7 +13,7 @@ global using AdvancedSharpAdbClient.Logs.Tests; #endregion -#if WINDOWS10_0_17763_0_OR_GREATER +#if WINDOWS10_0_18362_0_OR_GREATER global using Windows.ApplicationModel; global using System.Runtime.InteropServices.WindowsRuntime; global using Windows.Storage; diff --git a/AdvancedSharpAdbClient.Tests/SyncServiceTests.Async.cs b/AdvancedSharpAdbClient.Tests/SyncServiceTests.Async.cs index b92b5a4..c17cb2c 100644 --- a/AdvancedSharpAdbClient.Tests/SyncServiceTests.Async.cs +++ b/AdvancedSharpAdbClient.Tests/SyncServiceTests.Async.cs @@ -252,7 +252,7 @@ await RunTestAsync( Assert.True(service.IsProcessing); _ = await Assert.ThrowsAsync(() => service.PushAsync((Stream)null, null, default, default)); _ = await Assert.ThrowsAsync(() => service.PullAsync(null, (Stream)null)); -#if WINDOWS10_0_17763_0_OR_GREATER +#if WINDOWS10_0_18362_0_OR_GREATER _ = await Assert.ThrowsAsync(() => service.PushAsync((IInputStream)null, null, default, default)); _ = await Assert.ThrowsAsync(() => service.PullAsync(null, (IOutputStream)null)); #endif @@ -264,7 +264,7 @@ await RunTestAsync( }); } -#if WINDOWS10_0_17763_0_OR_GREATER +#if WINDOWS10_0_18362_0_OR_GREATER /// /// Tests the method. /// @@ -313,7 +313,7 @@ public async Task PushWinRTAsyncTest() { if (!OperatingSystem.IsWindowsVersionAtLeast(10)) { return; } - StorageFile storageFile = await StorageFile.GetFileFromPathAsync(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Assets\Fstab.bin")); + StorageFile storageFile = await StorageFile.GetFileFromPathAsync(Path.GetFullPath("Assets/Fstab.bin")); using IRandomAccessStreamWithContentType stream = await storageFile.OpenReadAsync(); byte[] content = await File.ReadAllBytesAsync("Assets/Fstab.bin"); byte[] contentMessage = diff --git a/AdvancedSharpAdbClient.Tests/SyncServiceTests.cs b/AdvancedSharpAdbClient.Tests/SyncServiceTests.cs index 60f998e..0cc2bff 100644 --- a/AdvancedSharpAdbClient.Tests/SyncServiceTests.cs +++ b/AdvancedSharpAdbClient.Tests/SyncServiceTests.cs @@ -233,7 +233,7 @@ public void CloneTest() socket.Responses.Enqueue(AdbResponse.OK); using SyncService syncService = new(socket, Device); Assert.True(syncService is ICloneable); -#if WINDOWS10_0_17763_0_OR_GREATER +#if WINDOWS10_0_18362_0_OR_GREATER Assert.True(syncService is ICloneable); #endif using SyncService service = syncService.Clone(); diff --git a/AdvancedSharpAdbClient/AdbClient.Async.cs b/AdvancedSharpAdbClient/AdbClient.Async.cs index 9da6a00..c44267f 100644 --- a/AdvancedSharpAdbClient/AdbClient.Async.cs +++ b/AdvancedSharpAdbClient/AdbClient.Async.cs @@ -178,6 +178,29 @@ public virtual async Task ExecuteServerCommandAsync(string target, string comman await socket.SendAdbRequestAsync(request.ToString(), cancellationToken); await socket.ReadAdbResponseAsync(cancellationToken).ConfigureAwait(false); + + try + { + using StreamReader reader = new(socket.GetShellStream()); + // Previously, we would loop while reader.Peek() >= 0. Turns out that this would + // break too soon in certain cases (about every 10 loops, so it appears to be a timing + // issue). Checking for reader.ReadLine() to return null appears to be much more robust + // -- one of the integration test fetches output 1000 times and found no truncations. + while (!cancellationToken.IsCancellationRequested) + { + if (await reader.ReadLineAsync(cancellationToken).ConfigureAwait(false) == null) { break; } + } + } + catch (Exception e) + { + // If a cancellation was requested, this main loop is interrupted with an exception + // because the socket is closed. In that case, we don't need to throw a ShellCommandUnresponsiveException. + // In all other cases, something went wrong, and we want to report it to the user. + if (!cancellationToken.IsCancellationRequested) + { + throw new ShellCommandUnresponsiveException(e); + } + } } /// @@ -258,18 +281,18 @@ public async Task ExecuteRemoteCommandAsync(string command, DeviceData device, I #if COMP_NETSTANDARD2_1 /// - public async IAsyncEnumerable ExecuteServerCommandAsync(string target, string command, Encoding encoding, [EnumeratorCancellation] CancellationToken cancellationToken = default) + public async IAsyncEnumerable ExecuteServerEnumerableAsync(string target, string command, Encoding encoding, [EnumeratorCancellation] CancellationToken cancellationToken = default) { ExceptionExtensions.ThrowIfNull(encoding); using IAdbSocket socket = CreateAdbSocket(); - await foreach (string? line in ExecuteServerCommandAsync(target, command, socket, encoding, cancellationToken).ConfigureAwait(false)) + await foreach (string? line in ExecuteServerEnumerableAsync(target, command, socket, encoding, cancellationToken).ConfigureAwait(false)) { yield return line; } } /// - public virtual async IAsyncEnumerable ExecuteServerCommandAsync(string target, string command, IAdbSocket socket, Encoding encoding, [EnumeratorCancellation] CancellationToken cancellationToken = default) + public virtual async IAsyncEnumerable ExecuteServerEnumerableAsync(string target, string command, IAdbSocket socket, Encoding encoding, [EnumeratorCancellation] CancellationToken cancellationToken = default) { ExceptionExtensions.ThrowIfNull(encoding); @@ -311,7 +334,7 @@ public virtual async IAsyncEnumerable ExecuteServerCommandAsync(string t } /// - public async IAsyncEnumerable ExecuteRemoteCommandAsync(string command, DeviceData device, Encoding encoding, [EnumeratorCancellation] CancellationToken cancellationToken = default) + public async IAsyncEnumerable ExecuteRemoteEnumerableAsync(string command, DeviceData device, Encoding encoding, [EnumeratorCancellation] CancellationToken cancellationToken = default) { EnsureDevice(device); ExceptionExtensions.ThrowIfNull(encoding); @@ -319,7 +342,7 @@ public async IAsyncEnumerable ExecuteRemoteCommandAsync(string command, using IAdbSocket socket = CreateAdbSocket(); await socket.SetDeviceAsync(device, cancellationToken); - await foreach (string? line in ExecuteServerCommandAsync("shell", command, socket, encoding, cancellationToken).ConfigureAwait(false)) + await foreach (string? line in ExecuteServerEnumerableAsync("shell", command, socket, encoding, cancellationToken).ConfigureAwait(false)) { yield return line; } @@ -653,8 +676,7 @@ void OnSplitSyncProgressChanged(string? sender, double args) } } - int i = 0; - await splitAPKs.Select(splitAPK => InstallWriteAsync(device, splitAPK, $"{nameof(splitAPK)}{i++}", session, OnSplitSyncProgressChanged, cancellationToken)).WhenAll().ConfigureAwait(false); + await splitAPKs.Select((splitAPK, index) => InstallWriteAsync(device, splitAPK, $"{nameof(splitAPK)}{index}", session, OnSplitSyncProgressChanged, cancellationToken)).WhenAll().ConfigureAwait(false); callback?.Invoke(new InstallProgressEventArgs(PackageInstallProgressState.Installing)); await InstallCommitAsync(device, session, cancellationToken).ConfigureAwait(false); @@ -697,8 +719,7 @@ void OnSyncProgressChanged(string? sender, double args) } } - int i = 0; - await splitAPKs.Select(splitAPK => InstallWriteAsync(device, splitAPK, $"{nameof(splitAPK)}{i++}", session, OnSyncProgressChanged, cancellationToken)).WhenAll().ConfigureAwait(false); + await splitAPKs.Select((splitAPK, index) => InstallWriteAsync(device, splitAPK, $"{nameof(splitAPK)}{index}", session, OnSyncProgressChanged, cancellationToken)).WhenAll().ConfigureAwait(false); callback?.Invoke(new InstallProgressEventArgs(PackageInstallProgressState.Installing)); await InstallCommitAsync(device, session, cancellationToken).ConfigureAwait(false); @@ -934,7 +955,9 @@ public async Task InstallCommitAsync(DeviceData device, string session, Cancella #if HAS_WINRT /// - [ContractVersion(typeof(UniversalApiContract), 65536u)] +#if NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public virtual async Task InstallAsync(DeviceData device, IRandomAccessStream apk, Action? callback = null, CancellationToken cancellationToken = default, params string[] arguments) { callback?.Invoke(new InstallProgressEventArgs(PackageInstallProgressState.Preparing)); @@ -1003,6 +1026,9 @@ public virtual async Task InstallAsync(DeviceData device, IRandomAccessStream ap } /// +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public async Task InstallMultipleAsync(DeviceData device, IRandomAccessStream baseAPK, IEnumerable splitAPKs, Action? callback = null, CancellationToken cancellationToken = default, params string[] arguments) { callback?.Invoke(new InstallProgressEventArgs(PackageInstallProgressState.Preparing)); @@ -1048,8 +1074,7 @@ void OnSplitSyncProgressChanged(string? sender, double args) } } - int i = 0; - await splitAPKs.Select(splitAPK => InstallWriteAsync(device, splitAPK, $"{nameof(splitAPK)}{i++}", session, OnSplitSyncProgressChanged, cancellationToken)).WhenAll().ConfigureAwait(false); + await splitAPKs.Select((splitAPK, index) => InstallWriteAsync(device, splitAPK, $"{nameof(splitAPK)}{index}", session, OnSplitSyncProgressChanged, cancellationToken)).WhenAll().ConfigureAwait(false); callback?.Invoke(new InstallProgressEventArgs(PackageInstallProgressState.Installing)); await InstallCommitAsync(device, session, cancellationToken).ConfigureAwait(false); @@ -1057,6 +1082,9 @@ void OnSplitSyncProgressChanged(string? sender, double args) } /// +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public async Task InstallMultipleAsync(DeviceData device, IEnumerable splitAPKs, string packageName, Action? callback = null, CancellationToken cancellationToken = default, params string[] arguments) { callback?.Invoke(new InstallProgressEventArgs(PackageInstallProgressState.Preparing)); @@ -1092,8 +1120,7 @@ void OnSyncProgressChanged(string? sender, double args) } } - int i = 0; - await splitAPKs.Select(splitAPK => InstallWriteAsync(device, splitAPK, $"{nameof(splitAPK)}{i++}", session, OnSyncProgressChanged, cancellationToken)).WhenAll().ConfigureAwait(false); + await splitAPKs.Select((splitAPK, index) => InstallWriteAsync(device, splitAPK, $"{nameof(splitAPK)}{index}", session, OnSyncProgressChanged, cancellationToken)).WhenAll().ConfigureAwait(false); callback?.Invoke(new InstallProgressEventArgs(PackageInstallProgressState.Installing)); await InstallCommitAsync(device, session, cancellationToken).ConfigureAwait(false); @@ -1101,6 +1128,9 @@ void OnSyncProgressChanged(string? sender, double args) } /// +#if NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public virtual async Task InstallWriteAsync(DeviceData device, IRandomAccessStream apk, string apkName, string session, Action? callback = null, CancellationToken cancellationToken = default) { callback?.Invoke(0); @@ -1173,6 +1203,9 @@ public virtual async Task InstallWriteAsync(DeviceData device, IRandomAccessStre /// The progress is reported as a value between 0 and 100, representing the percentage of the apk which has been transferred. /// A which can be used to cancel the asynchronous operation. /// A which represents the asynchronous operation. +#if NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif protected virtual async Task InstallWriteAsync(DeviceData device, IRandomAccessStream apk, string apkName, string session, Action? callback, CancellationToken cancellationToken = default) { callback?.Invoke(apkName, 0); diff --git a/AdvancedSharpAdbClient/AdbClient.cs b/AdvancedSharpAdbClient/AdbClient.cs index e2ae127..e4b32f6 100644 --- a/AdvancedSharpAdbClient/AdbClient.cs +++ b/AdvancedSharpAdbClient/AdbClient.cs @@ -339,6 +339,20 @@ public virtual void ExecuteServerCommand(string target, string command, IAdbSock socket.SendAdbRequest(request.ToString()); _ = socket.ReadAdbResponse(); + + try + { + using StreamReader reader = new(socket.GetShellStream()); + // Previously, we would loop while reader.Peek() >= 0. Turns out that this would + // break too soon in certain cases (about every 10 loops, so it appears to be a timing + // issue). Checking for reader.ReadLine() to return null appears to be much more robust + // -- one of the integration test fetches output 1000 times and found no truncations. + while (reader.ReadLine() != null) ; + } + catch (Exception e) + { + throw new ShellCommandUnresponsiveException(e); + } } /// @@ -411,18 +425,18 @@ public void ExecuteRemoteCommand(string command, DeviceData device, IShellOutput } /// - public IEnumerable ExecuteServerCommand(string target, string command, Encoding encoding) + public IEnumerable ExecuteServerEnumerable(string target, string command, Encoding encoding) { ExceptionExtensions.ThrowIfNull(encoding); using IAdbSocket socket = CreateAdbSocket(); - foreach (string line in ExecuteServerCommand(target, command, socket, encoding)) + foreach (string line in ExecuteServerEnumerable(target, command, socket, encoding)) { yield return line; } } /// - public virtual IEnumerable ExecuteServerCommand(string target, string command, IAdbSocket socket, Encoding encoding) + public virtual IEnumerable ExecuteServerEnumerable(string target, string command, IAdbSocket socket, Encoding encoding) { ExceptionExtensions.ThrowIfNull(encoding); @@ -458,14 +472,14 @@ public virtual IEnumerable ExecuteServerCommand(string target, string co } /// - public IEnumerable ExecuteRemoteCommand(string command, DeviceData device, Encoding encoding) + public IEnumerable ExecuteRemoteEnumerable(string command, DeviceData device, Encoding encoding) { EnsureDevice(device); using IAdbSocket socket = CreateAdbSocket(); socket.SetDevice(device); - foreach (string line in ExecuteServerCommand("shell", command, socket, encoding)) + foreach (string line in ExecuteServerEnumerable("shell", command, socket, encoding)) { yield return line; } diff --git a/AdvancedSharpAdbClient/AdbCommandLineClient.Async.cs b/AdvancedSharpAdbClient/AdbCommandLineClient.Async.cs index 3aa0e8c..dfda3c9 100644 --- a/AdvancedSharpAdbClient/AdbCommandLineClient.Async.cs +++ b/AdvancedSharpAdbClient/AdbCommandLineClient.Async.cs @@ -76,9 +76,12 @@ public async Task StartServerAsync(CancellationToken cancellationToken = default } /// +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public virtual Task CheckAdbFileExistsAsync(string adbPath, CancellationToken cancellationToken = default) => adbPath == "adb" ? TaskExExtensions.FromResult(true) : -#if WINDOWS_UWP - StorageFile.GetFileFromPathAsync(adbPath).AsTask(cancellationToken).ContinueWith(x => x.Result != null && x.Result.IsOfType(StorageItemTypes.File)); +#if HAS_WINRT + StorageFile.GetFileFromPathAsync(Extensions.GetFullPath(adbPath)).AsTask(cancellationToken).ContinueWith(x => x.Result != null && x.Result.IsOfType(StorageItemTypes.File)); #else TaskExExtensions.FromResult(File.Exists(adbPath)); #endif diff --git a/AdvancedSharpAdbClient/AdbCommandLineClient.cs b/AdvancedSharpAdbClient/AdbCommandLineClient.cs index 5e7ea60..29a5e25 100644 --- a/AdvancedSharpAdbClient/AdbCommandLineClient.cs +++ b/AdvancedSharpAdbClient/AdbCommandLineClient.cs @@ -36,6 +36,9 @@ public partial class AdbCommandLineClient : IAdbCommandLineClient /// The path to the adb.exe executable. /// Doesn't check adb file when . /// The logger to use when logging. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public AdbCommandLineClient(string adbPath, bool isForce = false, ILogger? logger = null) { if (StringExtensions.IsNullOrWhiteSpace(adbPath)) @@ -123,9 +126,12 @@ public virtual List ExecuteAdbCommand(string command, int timeout = 5000 } /// +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public virtual bool CheckAdbFileExists(string adbPath) => adbPath == "adb" || -#if WINDOWS_UWP - StorageFile.GetFileFromPathAsync(adbPath).AwaitByTaskCompleteSource() is StorageFile file && file.IsOfType(StorageItemTypes.File); +#if HAS_WINRT + (StorageFile.GetFileFromPathAsync(Extensions.GetFullPath(adbPath)).AwaitByTaskCompleteSource() is StorageFile file && file.IsOfType(StorageItemTypes.File)); #else File.Exists(adbPath); #endif diff --git a/AdvancedSharpAdbClient/AdvancedSharpAdbClient.csproj b/AdvancedSharpAdbClient/AdvancedSharpAdbClient.csproj index 7af8766..49e39e9 100644 --- a/AdvancedSharpAdbClient/AdvancedSharpAdbClient.csproj +++ b/AdvancedSharpAdbClient/AdvancedSharpAdbClient.csproj @@ -19,8 +19,8 @@ $(NoWarn);NU1603;NU1605;NU1902;NU1903 - net6.0;net8.0;netcoreapp2.1;netcoreapp3.1;netstandard1.3;netstandard2.0;netstandard2.1 - $(TargetFrameworks);net2.0;net3.5-client;net4.0-client;net4.5;net4.6.1;net4.8;net6.0-windows10.0.17763.0;net8.0-windows10.0.17763.0 + net6.0;net8.0;net9.0;netcoreapp2.1;netcoreapp3.1;netstandard1.3;netstandard2.0;netstandard2.1 + $(TargetFrameworks);net2.0;net3.5-client;net4.0-client;net4.5;net4.6.1;net4.8;net8.0-windows10.0.17763.0;net9.0-windows10.0.17763.0 $(TargetFrameworks);netcore5.0;uap10.0;uap10.0.15138.0 @@ -59,6 +59,10 @@ 10.0.15138.0 + + True + + @@ -71,7 +75,7 @@ - + - + - - - - $(DefineConstants);COMP_NETSTANDARD2_1 @@ -132,9 +132,12 @@ or $([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net5.0-windows10.0.17763.0'))"> $(DefineConstants);HAS_WINRT + + + $(DefineConstants);HAS_WUXC + - + $(DefineConstants);HAS_IMAGING diff --git a/AdvancedSharpAdbClient/DeviceCommands/DeviceClient.Async.cs b/AdvancedSharpAdbClient/DeviceCommands/DeviceClient.Async.cs index 195512c..4aaf664 100644 --- a/AdvancedSharpAdbClient/DeviceCommands/DeviceClient.Async.cs +++ b/AdvancedSharpAdbClient/DeviceCommands/DeviceClient.Async.cs @@ -68,7 +68,6 @@ public async Task DumpScreenStringAsync(CancellationToken cancellationTo #if NET [SupportedOSPlatform("Windows10.0.10240.0")] #endif - [ContractVersion(typeof(UniversalApiContract), 65536u)] public async Task DumpScreenWinRTAsync(CancellationToken cancellationToken = default) { string xmlString = await DumpScreenStringAsync(cancellationToken).ConfigureAwait(false); diff --git a/AdvancedSharpAdbClient/DeviceCommands/DeviceClient.cs b/AdvancedSharpAdbClient/DeviceCommands/DeviceClient.cs index 5454d5e..7b6d387 100644 --- a/AdvancedSharpAdbClient/DeviceCommands/DeviceClient.cs +++ b/AdvancedSharpAdbClient/DeviceCommands/DeviceClient.cs @@ -19,7 +19,7 @@ namespace AdvancedSharpAdbClient.DeviceCommands /// The to use to communicate with the Android Debug Bridge. /// The device on which to process command. [DebuggerDisplay($"{{{nameof(ToString)}(),nq}}")] - public partial record class DeviceClient(IAdbClient AdbClient, DeviceData Device) + public partial record class DeviceClient(IAdbClient AdbClient, DeviceData Device) : ICloneable, ICloneable { /// /// The to use when communicating with the device. @@ -98,7 +98,6 @@ public string DumpScreenString() #if NET [SupportedOSPlatform("Windows10.0.10240.0")] #endif - [ContractVersion(typeof(UniversalApiContract), 65536u)] public Windows.Data.Xml.Dom.XmlDocument? DumpScreenWinRT() { Windows.Data.Xml.Dom.XmlDocument doc = new(); @@ -444,6 +443,12 @@ public void Deconstruct(out IAdbClient client, out DeviceData device) device = Device; } + /// + DeviceClient ICloneable.Clone() => this with { }; + + /// + object ICloneable.Clone() => ((ICloneable)this).Clone(); + #if !NET40_OR_GREATER && !NETCOREAPP2_0_OR_GREATER && !NETSTANDARD2_0_OR_GREATER && !UAP10_0_15138_0 /// public override int GetHashCode() => HashCode.Combine(EqualityContract, AdbClient, Device); diff --git a/AdvancedSharpAdbClient/DeviceCommands/DeviceExtensions.Async.cs b/AdvancedSharpAdbClient/DeviceCommands/DeviceExtensions.Async.cs index f530785..f9c3603 100644 --- a/AdvancedSharpAdbClient/DeviceCommands/DeviceExtensions.Async.cs +++ b/AdvancedSharpAdbClient/DeviceCommands/DeviceExtensions.Async.cs @@ -337,6 +337,9 @@ public static async Task> GetEnvironmentVariablesAsyn /// A which can be used to cancel the asynchronous operation. /// The arguments to pass to adb install. /// A which represents the asynchronous operation. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public static Task InstallPackageAsync(this IAdbClient client, DeviceData device, string packageFilePath, Action? callback = null, CancellationToken cancellationToken = default, params string[] arguments) { PackageManager manager = new(client, device, skipInit: true); @@ -355,6 +358,9 @@ public static Task InstallPackageAsync(this IAdbClient client, DeviceData device /// A which can be used to cancel the asynchronous operation. /// The arguments to pass to pm install-create. /// A which represents the asynchronous operation. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public static Task InstallMultiplePackageAsync(this IAdbClient client, DeviceData device, string basePackageFilePath, IEnumerable splitPackageFilePaths, Action? callback = null, CancellationToken cancellationToken = default, params string[] arguments) { PackageManager manager = new(client, device, skipInit: true); @@ -373,6 +379,9 @@ public static Task InstallMultiplePackageAsync(this IAdbClient client, DeviceDat /// A which can be used to cancel the asynchronous operation. /// The arguments to pass to pm install-create. /// A which represents the asynchronous operation. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public static Task InstallMultiplePackageAsync(this IAdbClient client, DeviceData device, IEnumerable splitPackageFilePaths, string packageName, Action? callback = null, CancellationToken cancellationToken = default, params string[] arguments) { PackageManager manager = new(client, device, skipInit: true); @@ -431,6 +440,9 @@ public static async Task PushAsync(this IAdbClient client, DeviceData device, /// A which can be used to cancel the asynchronous operation. /// The arguments to pass to adb install. /// A which represents the asynchronous operation. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public static Task InstallPackageAsync(this IAdbClient client, DeviceData device, string packageFilePath, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) { PackageManager manager = new(client, device, skipInit: true); @@ -449,6 +461,9 @@ public static Task InstallPackageAsync(this IAdbClient client, DeviceData device /// A which can be used to cancel the asynchronous operation. /// The arguments to pass to pm install-create. /// A which represents the asynchronous operation. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public static Task InstallMultiplePackageAsync(this IAdbClient client, DeviceData device, string basePackageFilePath, IEnumerable splitPackageFilePaths, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) { PackageManager manager = new(client, device, skipInit: true); @@ -467,6 +482,9 @@ public static Task InstallMultiplePackageAsync(this IAdbClient client, DeviceDat /// A which can be used to cancel the asynchronous operation. /// The arguments to pass to pm install-create. /// A which represents the asynchronous operation. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public static Task InstallMultiplePackageAsync(this IAdbClient client, DeviceData device, IEnumerable splitPackageFilePaths, string packageName, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) { PackageManager manager = new(client, device, skipInit: true); diff --git a/AdvancedSharpAdbClient/DeviceCommands/DeviceExtensions.cs b/AdvancedSharpAdbClient/DeviceCommands/DeviceExtensions.cs index 842cdba..e9da616 100644 --- a/AdvancedSharpAdbClient/DeviceCommands/DeviceExtensions.cs +++ b/AdvancedSharpAdbClient/DeviceCommands/DeviceExtensions.cs @@ -288,6 +288,9 @@ public static Dictionary GetEnvironmentVariables(this IAdbClient /// An optional parameter which, when specified, returns progress notifications. /// The progress is reported as , representing the state of installation. /// The arguments to pass to adb install. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public static void InstallPackage(this IAdbClient client, DeviceData device, string packageFilePath, Action? callback = null, params string[] arguments) { PackageManager manager = new(client, device, skipInit: true); @@ -304,6 +307,9 @@ public static void InstallPackage(this IAdbClient client, DeviceData device, str /// An optional parameter which, when specified, returns progress notifications. /// The progress is reported as , representing the state of installation. /// The arguments to pass to pm install-create. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public static void InstallMultiplePackage(this IAdbClient client, DeviceData device, string basePackageFilePath, IEnumerable splitPackageFilePaths, Action? callback = null, params string[] arguments) { PackageManager manager = new(client, device, skipInit: true); @@ -320,6 +326,9 @@ public static void InstallMultiplePackage(this IAdbClient client, DeviceData dev /// An optional parameter which, when specified, returns progress notifications. /// The progress is reported as , representing the state of installation. /// The arguments to pass to pm install-create. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public static void InstallMultiplePackage(this IAdbClient client, DeviceData device, IEnumerable splitPackageFilePaths, string packageName, Action? callback = null, params string[] arguments) { PackageManager manager = new(client, device, skipInit: true); @@ -375,6 +384,9 @@ public static void Push(this IAdbClient client, DeviceData device, /// An optional parameter which, when specified, returns progress notifications. /// The progress is reported as , representing the state of installation. /// The arguments to pass to adb install. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public static void InstallPackage(this IAdbClient client, DeviceData device, string packageFilePath, IProgress? progress = null, params string[] arguments) { PackageManager manager = new(client, device, skipInit: true); @@ -391,6 +403,9 @@ public static void InstallPackage(this IAdbClient client, DeviceData device, str /// An optional parameter which, when specified, returns progress notifications. /// The progress is reported as , representing the state of installation. /// The arguments to pass to pm install-create. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public static void InstallMultiplePackage(this IAdbClient client, DeviceData device, string basePackageFilePath, IEnumerable splitPackageFilePaths, IProgress? progress = null, params string[] arguments) { PackageManager manager = new(client, device, skipInit: true); @@ -407,6 +422,9 @@ public static void InstallMultiplePackage(this IAdbClient client, DeviceData dev /// An optional parameter which, when specified, returns progress notifications. /// The progress is reported as , representing the state of installation. /// The arguments to pass to pm install-create. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public static void InstallMultiplePackage(this IAdbClient client, DeviceData device, IEnumerable splitPackageFilePaths, string packageName, IProgress? progress = null, params string[] arguments) { PackageManager manager = new(client, device, skipInit: true); diff --git a/AdvancedSharpAdbClient/DeviceCommands/Models/Element.cs b/AdvancedSharpAdbClient/DeviceCommands/Models/Element.cs index 1522dcd..ce3d772 100644 --- a/AdvancedSharpAdbClient/DeviceCommands/Models/Element.cs +++ b/AdvancedSharpAdbClient/DeviceCommands/Models/Element.cs @@ -92,7 +92,6 @@ static IEnumerable FindElements(IAdbClient client, DeviceData device, X /// The of the element. #if NET [SupportedOSPlatform("Windows10.0.10240.0")] - [ContractVersion(typeof(UniversalApiContract), 65536u)] #endif public Element(IAdbClient client, DeviceData device, Windows.Data.Xml.Dom.IXmlNode xmlNode) { @@ -223,7 +222,6 @@ static IEnumerable FindElements(IAdbClient client, DeviceData device, W #if NET [SupportedOSPlatform("Windows10.0.10240.0")] #endif - [ContractVersion(typeof(UniversalApiContract), 65536u)] public static Element? FromIXmlNode(IAdbClient client, DeviceData device, Windows.Data.Xml.Dom.IXmlNode xmlNode) => xmlNode.Attributes?.GetNamedItem("bounds") != null ? new Element(client, device, xmlNode) : null; #endif diff --git a/AdvancedSharpAdbClient/DeviceCommands/Models/VersionInfo.cs b/AdvancedSharpAdbClient/DeviceCommands/Models/VersionInfo.cs index c097d55..abdeeba 100644 --- a/AdvancedSharpAdbClient/DeviceCommands/Models/VersionInfo.cs +++ b/AdvancedSharpAdbClient/DeviceCommands/Models/VersionInfo.cs @@ -73,7 +73,6 @@ public readonly bool TryAsVersion(out Version? version) #if NET [SupportedOSPlatform("Windows10.0.10240.0")] #endif - [ContractVersion(typeof(UniversalApiContract), 65536u)] public readonly bool TryAsPackageVersion(out PackageVersion version) { ushort[] numbs = GetVersionNumbers(VersionName).Split('.', StringSplitOptions.RemoveEmptyEntries).Select(ushort.Parse).Take(4).ToArray(); diff --git a/AdvancedSharpAdbClient/DeviceCommands/PackageManager.Async.cs b/AdvancedSharpAdbClient/DeviceCommands/PackageManager.Async.cs index 8f4e547..9e2b0b8 100644 --- a/AdvancedSharpAdbClient/DeviceCommands/PackageManager.Async.cs +++ b/AdvancedSharpAdbClient/DeviceCommands/PackageManager.Async.cs @@ -47,6 +47,9 @@ public Task RefreshPackagesAsync(CancellationToken cancellationToken = default) /// A which can be used to cancel the asynchronous operation. /// The arguments to pass to adb install. /// A which represents the asynchronous operation. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public async Task InstallPackageAsync(string packageFilePath, Action? callback = null, CancellationToken cancellationToken = default, params string[] arguments) { callback?.Invoke(new InstallProgressEventArgs(PackageInstallProgressState.Preparing)); @@ -114,6 +117,9 @@ public async Task InstallRemotePackageAsync(string remoteFilePath, ActionA which can be used to cancel the asynchronous operation. /// The arguments to pass to pm install-create. /// A which represents the asynchronous operation. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public async Task InstallMultiplePackageAsync(string basePackageFilePath, IEnumerable splitPackageFilePaths, Action? callback = null, CancellationToken cancellationToken = default, params string[] arguments) { callback?.Invoke(new InstallProgressEventArgs(PackageInstallProgressState.Preparing)); @@ -160,13 +166,12 @@ void OnSplitSyncProgressChanged(string? sender, SyncProgressChangedEventArgs arg await InstallMultipleRemotePackageAsync(baseRemoteFilePath, splitRemoteFilePaths, callback, cancellationToken, arguments); - callback?.Invoke(new InstallProgressEventArgs(0, splitRemoteFilePaths.Length + 1, PackageInstallProgressState.PostInstall)); int count = 0; + callback?.Invoke(new InstallProgressEventArgs(0, splitRemoteFilePaths.Length + 1, PackageInstallProgressState.PostInstall)); await splitRemoteFilePaths.Select(async x => { - count++; await RemoveRemotePackageAsync(x, cancellationToken).ConfigureAwait(false); - callback?.Invoke(new InstallProgressEventArgs(count, splitRemoteFilePaths.Length + 1, PackageInstallProgressState.PostInstall)); + callback?.Invoke(new InstallProgressEventArgs(++count, splitRemoteFilePaths.Length + 1, PackageInstallProgressState.PostInstall)); }).WhenAll().ConfigureAwait(false); if (count < splitRemoteFilePaths.Length) @@ -190,6 +195,9 @@ await splitRemoteFilePaths.Select(async x => /// A which can be used to cancel the asynchronous operation. /// The arguments to pass to pm install-create. /// A which represents the asynchronous operation. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public async Task InstallMultiplePackageAsync(IEnumerable splitPackageFilePaths, string packageName, Action? callback = null, CancellationToken cancellationToken = default, params string[] arguments) { callback?.Invoke(new InstallProgressEventArgs(PackageInstallProgressState.Preparing)); @@ -231,13 +239,12 @@ void OnSyncProgressChanged(string? sender, SyncProgressChangedEventArgs args) await InstallMultipleRemotePackageAsync(splitRemoteFilePaths, packageName, callback, cancellationToken, arguments); - callback?.Invoke(new InstallProgressEventArgs(0, splitRemoteFilePaths.Length, PackageInstallProgressState.PostInstall)); int count = 0; + callback?.Invoke(new InstallProgressEventArgs(0, splitRemoteFilePaths.Length, PackageInstallProgressState.PostInstall)); await splitRemoteFilePaths.Select(async x => { - count++; await RemoveRemotePackageAsync(x, cancellationToken).ConfigureAwait(false); - callback?.Invoke(new InstallProgressEventArgs(count, splitRemoteFilePaths.Length, PackageInstallProgressState.PostInstall)); + callback?.Invoke(new InstallProgressEventArgs(++count, splitRemoteFilePaths.Length, PackageInstallProgressState.PostInstall)); }).WhenAll().ConfigureAwait(false); if (count < splitRemoteFilePaths.Length) @@ -275,10 +282,10 @@ public async Task InstallMultipleRemotePackageAsync(string baseRemoteFilePath, I callback?.Invoke(new InstallProgressEventArgs(1, splitRemoteFileCount + 1, PackageInstallProgressState.WriteSession)); int count = 0; - await splitRemoteFilePaths.Select(async splitRemoteFilePath => + await splitRemoteFilePaths.Select(async (splitRemoteFilePath, index) => { - await WriteInstallSessionAsync(session, $"split{count++}", splitRemoteFilePath, cancellationToken).ConfigureAwait(false); - callback?.Invoke(new InstallProgressEventArgs(count, splitRemoteFileCount + 1, PackageInstallProgressState.WriteSession)); + await WriteInstallSessionAsync(session, $"split{index}", splitRemoteFilePath, cancellationToken).ConfigureAwait(false); + callback?.Invoke(new InstallProgressEventArgs(++count, splitRemoteFileCount + 1, PackageInstallProgressState.WriteSession)); }).WhenAll().ConfigureAwait(false); if (count < splitRemoteFileCount) @@ -320,10 +327,10 @@ public async Task InstallMultipleRemotePackageAsync(IEnumerable splitRem callback?.Invoke(new InstallProgressEventArgs(0, splitRemoteFileCount, PackageInstallProgressState.WriteSession)); int count = 0; - await splitRemoteFilePaths.Select(async splitRemoteFilePath => + await splitRemoteFilePaths.Select(async (splitRemoteFilePath, index) => { - await WriteInstallSessionAsync(session, $"split{count++}", splitRemoteFilePath, cancellationToken).ConfigureAwait(false); - callback?.Invoke(new InstallProgressEventArgs(count, splitRemoteFileCount, PackageInstallProgressState.WriteSession)); + await WriteInstallSessionAsync(session, $"split{index}", splitRemoteFilePath, cancellationToken).ConfigureAwait(false); + callback?.Invoke(new InstallProgressEventArgs(++count, splitRemoteFileCount, PackageInstallProgressState.WriteSession)); }).WhenAll().ConfigureAwait(false); if (count < splitRemoteFileCount) @@ -352,6 +359,9 @@ await splitRemoteFilePaths.Select(async splitRemoteFilePath => /// A which can be used to cancel the asynchronous operation. /// The arguments to pass to adb install. /// A which represents the asynchronous operation. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public async Task InstallPackageAsync(string packageFilePath, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) => await InstallPackageAsync(packageFilePath, progress.AsAction(), cancellationToken, arguments).ConfigureAwait(false); @@ -377,6 +387,9 @@ public async Task InstallRemotePackageAsync(string remoteFilePath, IProgressA which can be used to cancel the asynchronous operation. /// The arguments to pass to pm install-create. /// A which represents the asynchronous operation. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public async Task InstallMultiplePackageAsync(string basePackageFilePath, IEnumerable splitPackageFilePaths, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) => await InstallMultiplePackageAsync(basePackageFilePath, splitPackageFilePaths, progress.AsAction(), cancellationToken, arguments).ConfigureAwait(false); @@ -390,6 +403,9 @@ public async Task InstallMultiplePackageAsync(string basePackageFilePath, IEnume /// A which can be used to cancel the asynchronous operation. /// The arguments to pass to pm install-create. /// A which represents the asynchronous operation. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public async Task InstallMultiplePackageAsync(IEnumerable splitPackageFilePaths, string packageName, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) => await InstallMultiplePackageAsync(splitPackageFilePaths, packageName, progress.AsAction(), cancellationToken, arguments).ConfigureAwait(false); @@ -545,9 +561,12 @@ protected async Task WriteInstallSessionAsync(string session, string apkName, st /// The file to be opened for reading. /// A which can be used to cancel the asynchronous operation. /// A which returns a read-only on the specified path. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif protected virtual Task GetFileStreamAsync(string path, CancellationToken cancellationToken = default) => -#if WINDOWS_UWP - StorageFile.GetFileFromPathAsync(path).AsTask(cancellationToken).ContinueWith(x => x.Result.OpenStreamForReadAsync()).Unwrap(); +#if HAS_WINRT + StorageFile.GetFileFromPathAsync(Extensions.GetFullPath(path)).AsTask(cancellationToken).ContinueWith(x => x.Result.OpenStreamForReadAsync()).Unwrap(); #else TaskExExtensions.FromResult(File.OpenRead(path)); #endif @@ -560,6 +579,9 @@ protected virtual Task GetFileStreamAsync(string path, CancellationToken /// A which can be used to cancel the asynchronous operation. /// A which returns the destination path on device for file. /// If fatal error occurred when pushing file. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif protected virtual async Task SyncPackageToDeviceAsync(string localFilePath, Action? callback, CancellationToken cancellationToken = default) { callback?.Invoke(localFilePath, new SyncProgressChangedEventArgs(0, 100)); diff --git a/AdvancedSharpAdbClient/DeviceCommands/PackageManager.cs b/AdvancedSharpAdbClient/DeviceCommands/PackageManager.cs index 013ccbb..34a6cb8 100644 --- a/AdvancedSharpAdbClient/DeviceCommands/PackageManager.cs +++ b/AdvancedSharpAdbClient/DeviceCommands/PackageManager.cs @@ -153,6 +153,9 @@ public void RefreshPackages() /// An optional parameter which, when specified, returns progress notifications. /// The progress is reported as , representing the state of installation. /// The arguments to pass to adb install. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public void InstallPackage(string packageFilePath, Action? callback = null, params string[] arguments) { callback?.Invoke(new InstallProgressEventArgs(PackageInstallProgressState.Preparing)); @@ -216,6 +219,9 @@ public void InstallRemotePackage(string remoteFilePath, ActionAn optional parameter which, when specified, returns progress notifications. /// The progress is reported as , representing the state of installation. /// The arguments to pass to pm install-create. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public void InstallMultiplePackage(string basePackageFilePath, IEnumerable splitPackageFilePaths, Action? callback = null, params string[] arguments) { callback?.Invoke(new InstallProgressEventArgs(PackageInstallProgressState.Preparing)); @@ -278,6 +284,9 @@ void OnSplitSyncProgressChanged(string? sender, SyncProgressChangedEventArgs arg /// An optional parameter which, when specified, returns progress notifications. /// The progress is reported as , representing the state of installation. /// The arguments to pass to pm install-create. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public void InstallMultiplePackage(IEnumerable splitPackageFilePaths, string packageName, Action? callback = null, params string[] arguments) { callback?.Invoke(new InstallProgressEventArgs(PackageInstallProgressState.Preparing)); @@ -313,8 +322,8 @@ void OnSyncProgressChanged(string? sender, SyncProgressChangedEventArgs args) InstallMultipleRemotePackage(splitRemoteFilePaths, packageName, callback, arguments); - callback?.Invoke(new InstallProgressEventArgs(0, splitRemoteFilePaths.Length, PackageInstallProgressState.PostInstall)); int count = 0; + callback?.Invoke(new InstallProgressEventArgs(0, splitRemoteFilePaths.Length, PackageInstallProgressState.PostInstall)); foreach (string splitRemoteFilePath in splitRemoteFilePaths) { RemoveRemotePackage(splitRemoteFilePath); @@ -412,6 +421,9 @@ public void InstallMultipleRemotePackage(IEnumerable splitRemoteFilePath /// An optional parameter which, when specified, returns progress notifications. /// The progress is reported as , representing the state of installation. /// The arguments to pass to adb install. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public void InstallPackage(string packageFilePath, IProgress? progress = null, params string[] arguments) => InstallPackage(packageFilePath, progress.AsAction(), arguments); @@ -433,6 +445,9 @@ public void InstallRemotePackage(string remoteFilePath, IProgressAn optional parameter which, when specified, returns progress notifications. /// The progress is reported as , representing the state of installation. /// The arguments to pass to pm install-create. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public void InstallMultiplePackage(string basePackageFilePath, IEnumerable splitPackageFilePaths, IProgress? progress = null, params string[] arguments) => InstallMultiplePackage(basePackageFilePath, splitPackageFilePaths, progress.AsAction(), arguments); @@ -444,6 +459,9 @@ public void InstallMultiplePackage(string basePackageFilePath, IEnumerableAn optional parameter which, when specified, returns progress notifications. /// The progress is reported as , representing the state of installation. /// The arguments to pass to pm install-create. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public void InstallMultiplePackage(IEnumerable splitPackageFilePaths, string packageName, IProgress? progress = null, params string[] arguments) => InstallMultiplePackage(splitPackageFilePaths, packageName, progress.AsAction(), arguments); @@ -593,9 +611,12 @@ protected void WriteInstallSession(string session, string apkName, string path) /// /// The file to be opened for reading. /// A read-only on the specified path. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif protected virtual Stream GetFileStream(string path) => -#if WINDOWS_UWP - StorageFile.GetFileFromPathAsync(path).AwaitByTaskCompleteSource().OpenStreamForReadAsync().AwaitByTaskCompleteSource(); +#if HAS_WINRT + StorageFile.GetFileFromPathAsync(Extensions.GetFullPath(path)).AwaitByTaskCompleteSource().OpenStreamForReadAsync().AwaitByTaskCompleteSource(); #else File.OpenRead(path); #endif @@ -607,6 +628,9 @@ protected virtual Stream GetFileStream(string path) => /// An optional parameter which, when specified, returns progress notifications. /// Destination path on device for file. /// If fatal error occurred when pushing file. +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif protected virtual string SyncPackageToDevice(string localFilePath, Action? callback) { callback?.Invoke(localFilePath, new SyncProgressChangedEventArgs(0, 100)); diff --git a/AdvancedSharpAdbClient/DeviceCommands/Receivers/PackageManagerReceiver.cs b/AdvancedSharpAdbClient/DeviceCommands/Receivers/PackageManagerReceiver.cs index 9f2b50a..cdd6ac4 100644 --- a/AdvancedSharpAdbClient/DeviceCommands/Receivers/PackageManagerReceiver.cs +++ b/AdvancedSharpAdbClient/DeviceCommands/Receivers/PackageManagerReceiver.cs @@ -25,7 +25,7 @@ public class PackageManagerReceiver(PackageManager packageManager) : MultiLineRe public PackageManager PackageManager => packageManager; /// - protected override void ProcessNewLines(IEnumerable lines) + protected override void ProcessNewLines(params IEnumerable lines) { PackageManager.Packages.Clear(); diff --git a/AdvancedSharpAdbClient/DeviceMonitor.Async.cs b/AdvancedSharpAdbClient/DeviceMonitor.Async.cs index 195bbd9..9520f9b 100644 --- a/AdvancedSharpAdbClient/DeviceMonitor.Async.cs +++ b/AdvancedSharpAdbClient/DeviceMonitor.Async.cs @@ -19,7 +19,11 @@ public partial class DeviceMonitor /// is used to block the method until the /// has processed the first list of devices. /// +#if NET + protected TaskCompletionSource? FirstDeviceListParsed; +#else protected TaskCompletionSource? FirstDeviceListParsed; +#endif /// /// A that can be used to cancel the . @@ -39,11 +43,11 @@ public async Task StartAsync(CancellationToken cancellationToken = default) { try { - FirstDeviceListParsed = new TaskCompletionSource(); + FirstDeviceListParsed = new(); using CancellationTokenRegistration cancellationTokenRegistration = cancellationToken.Register(() => FirstDeviceListParsed.SetCanceled()); MonitorTask = DeviceMonitorLoopAsync(MonitorTaskCancellationTokenSource.Token); // Wait for the worker thread to have read the first list of devices. - _ = await FirstDeviceListParsed.Task.ConfigureAwait(false); + await FirstDeviceListParsed.Task.ConfigureAwait(false); } finally { @@ -133,7 +137,15 @@ protected virtual async Task DeviceMonitorLoopAsync(CancellationToken cancellati if (FirstDeviceListParsed != null) { // Switch to the background thread to avoid blocking the caller. - _ = Task.Factory.StartNew(() => FirstDeviceListParsed?.TrySetResult(null), default, TaskCreationOptions.None, TaskScheduler.Default); + _ = Task.Factory.StartNew( +#if NET + () => FirstDeviceListParsed?.TrySetResult(), +#else + () => FirstDeviceListParsed?.TrySetResult(null), +#endif + default, + TaskCreationOptions.None, + TaskScheduler.Default); } } catch (TaskCanceledException ex) diff --git a/AdvancedSharpAdbClient/DeviceMonitor.cs b/AdvancedSharpAdbClient/DeviceMonitor.cs index 2d3d7d5..44a228e 100644 --- a/AdvancedSharpAdbClient/DeviceMonitor.cs +++ b/AdvancedSharpAdbClient/DeviceMonitor.cs @@ -162,10 +162,10 @@ public void Start() { try { - FirstDeviceListParsed = new TaskCompletionSource(); + FirstDeviceListParsed = new(); MonitorTask = DeviceMonitorLoopAsync(MonitorTaskCancellationTokenSource.Token); // Wait for the worker thread to have read the first list of devices. - _ = FirstDeviceListParsed.Task.AwaitByTaskCompleteSource(); + FirstDeviceListParsed.Task.AwaitByTaskCompleteSource(); } finally { @@ -345,7 +345,7 @@ private void ProcessIncomingDeviceData(string result) /// /// Processes the incoming . /// - protected virtual void UpdateDevices(IEnumerable collection) + protected virtual void UpdateDevices(params IEnumerable collection) { lock (devices) { diff --git a/AdvancedSharpAdbClient/Exceptions/JavaException.cs b/AdvancedSharpAdbClient/Exceptions/JavaException.cs index 85f2921..1ebc89b 100644 --- a/AdvancedSharpAdbClient/Exceptions/JavaException.cs +++ b/AdvancedSharpAdbClient/Exceptions/JavaException.cs @@ -103,7 +103,7 @@ public JavaException(SerializationInfo serializationInfo, StreamingContext conte /// /// A which represents a . /// The equivalent . - public static JavaException Parse(IEnumerable lines) + public static JavaException Parse(params IEnumerable lines) { string exception = string.Empty, message = string.Empty; StringBuilder stackTrace = new(); diff --git a/AdvancedSharpAdbClient/Extensions/AdbClientExtensions.Async.cs b/AdvancedSharpAdbClient/Extensions/AdbClientExtensions.Async.cs index 2eb2fd2..1fa47ba 100644 --- a/AdvancedSharpAdbClient/Extensions/AdbClientExtensions.Async.cs +++ b/AdvancedSharpAdbClient/Extensions/AdbClientExtensions.Async.cs @@ -220,8 +220,8 @@ public static Task ExecuteRemoteCommandAsync(this IAdbClient client, string comm /// The command to execute. /// A which can be used to cancel the asynchronous operation. /// A of strings, each representing a line of output from the command. - public static IAsyncEnumerable ExecuteServerCommandAsync(this IAdbClient client, string target, string command, CancellationToken cancellationToken = default) => - client.ExecuteServerCommandAsync(target, command, AdbClient.Encoding, cancellationToken); + public static IAsyncEnumerable ExecuteServerEnumerableAsync(this IAdbClient client, string target, string command, CancellationToken cancellationToken = default) => + client.ExecuteServerEnumerableAsync(target, command, AdbClient.Encoding, cancellationToken); /// /// Asynchronously executes a command on the adb server and returns the output. @@ -233,8 +233,8 @@ public static IAsyncEnumerable ExecuteServerCommandAsync(this IAdbClient /// The to send command. /// A which can be used to cancel the asynchronous operation. /// A of strings, each representing a line of output from the command. - public static IAsyncEnumerable ExecuteServerCommandAsync(this IAdbClient client, string target, string command, IAdbSocket socket, CancellationToken cancellationToken = default) => - client.ExecuteServerCommandAsync(target, command, socket, AdbClient.Encoding, cancellationToken); + public static IAsyncEnumerable ExecuteServerEnumerableAsync(this IAdbClient client, string target, string command, IAdbSocket socket, CancellationToken cancellationToken = default) => + client.ExecuteServerEnumerableAsync(target, command, socket, AdbClient.Encoding, cancellationToken); /// /// Asynchronously executes a command on the device and returns the output. @@ -244,8 +244,8 @@ public static IAsyncEnumerable ExecuteServerCommandAsync(this IAdbClient /// The device on which to run the command. /// A which can be used to cancel the asynchronous operation. /// A of strings, each representing a line of output from the command. - public static IAsyncEnumerable ExecuteRemoteCommandAsync(this IAdbClient client, string command, DeviceData device, CancellationToken cancellationToken = default) => - client.ExecuteRemoteCommandAsync(command, device, AdbClient.Encoding, cancellationToken); + public static IAsyncEnumerable ExecuteRemoteEnumerableAsync(this IAdbClient client, string command, DeviceData device, CancellationToken cancellationToken = default) => + client.ExecuteRemoteEnumerableAsync(command, device, AdbClient.Encoding, cancellationToken); /// /// Asynchronously runs the event log service on a device and returns it. @@ -515,7 +515,6 @@ public static Task DisconnectAsync(this IAdbClient client, DnsEndPoint e /// A which can be used to cancel the asynchronous operation. /// The arguments to pass to adb install. /// A which represents the asynchronous operation. - [ContractVersion(typeof(UniversalApiContract), 65536u)] public static Task InstallAsync(this IAdbClient.IWinRT client, DeviceData device, IRandomAccessStream apk, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) => client.InstallAsync(device, apk, progress.AsAction(), cancellationToken, arguments); @@ -531,7 +530,6 @@ public static Task InstallAsync(this IAdbClient.IWinRT client, DeviceData device /// A which can be used to cancel the asynchronous operation. /// The arguments to pass to adb install-create. /// A which represents the asynchronous operation. - [ContractVersion(typeof(UniversalApiContract), 65536u)] public static Task InstallMultipleAsync(this IAdbClient.IWinRT client, DeviceData device, IRandomAccessStream baseAPK, IEnumerable splitAPKs, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) => client.InstallMultipleAsync(device, baseAPK, splitAPKs, progress.AsAction(), cancellationToken, arguments); @@ -547,7 +545,6 @@ public static Task InstallMultipleAsync(this IAdbClient.IWinRT client, DeviceDat /// A which can be used to cancel the asynchronous operation. /// The arguments to pass to adb install-create. /// A which represents the asynchronous operation. - [ContractVersion(typeof(UniversalApiContract), 65536u)] public static Task InstallMultipleAsync(this IAdbClient.IWinRT client, DeviceData device, IEnumerable splitAPKs, string packageName, IProgress? progress = null, CancellationToken cancellationToken = default, params string[] arguments) => client.InstallMultipleAsync(device, splitAPKs, packageName, progress.AsAction(), cancellationToken, arguments); @@ -563,7 +560,6 @@ public static Task InstallMultipleAsync(this IAdbClient.IWinRT client, DeviceDat /// The progress is reported as a value between 0 and 100, representing the percentage of the apk which has been transferred. /// A which can be used to cancel the asynchronous operation. /// A which represents the asynchronous operation. - [ContractVersion(typeof(UniversalApiContract), 65536u)] public static Task InstallWriteAsync(this IAdbClient.IWinRT client, DeviceData device, IRandomAccessStream apk, string apkName, string session, IProgress? progress = null, CancellationToken cancellationToken = default) => client.InstallWriteAsync(device, apk, apkName, session, progress.AsAction(), cancellationToken); #endif diff --git a/AdvancedSharpAdbClient/Extensions/AdbClientExtensions.cs b/AdvancedSharpAdbClient/Extensions/AdbClientExtensions.cs index 74540e6..dfbab01 100644 --- a/AdvancedSharpAdbClient/Extensions/AdbClientExtensions.cs +++ b/AdvancedSharpAdbClient/Extensions/AdbClientExtensions.cs @@ -191,8 +191,8 @@ public static void ExecuteRemoteCommand(this IAdbClient client, string command, /// localreserved, localabstract, jdwp, track-jdwp, sync, reverse and so on. /// The command to execute. /// A of strings, each representing a line of output from the command. - public static IEnumerable ExecuteServerCommand(this IAdbClient client, string target, string command) => - client.ExecuteServerCommand(target, command, AdbClient.Encoding); + public static IEnumerable ExecuteServerEnumerable(this IAdbClient client, string target, string command) => + client.ExecuteServerEnumerable(target, command, AdbClient.Encoding); /// /// Executes a command on the adb server and returns the output. @@ -203,8 +203,8 @@ public static IEnumerable ExecuteServerCommand(this IAdbClient client, s /// The command to execute. /// The to send command. /// A of strings, each representing a line of output from the command. - public static IEnumerable ExecuteServerCommand(this IAdbClient client, string target, string command, IAdbSocket socket) => - client.ExecuteServerCommand(target, command, socket, AdbClient.Encoding); + public static IEnumerable ExecuteServerEnumerable(this IAdbClient client, string target, string command, IAdbSocket socket) => + client.ExecuteServerEnumerable(target, command, socket, AdbClient.Encoding); /// /// Executes a shell command on the device and returns the output. @@ -213,8 +213,8 @@ public static IEnumerable ExecuteServerCommand(this IAdbClient client, s /// The command to execute. /// The device on which to run the command. /// A of strings, each representing a line of output from the command. - public static IEnumerable ExecuteRemoteCommand(this IAdbClient client, string command, DeviceData device) => - client.ExecuteRemoteCommand(command, device, AdbClient.Encoding); + public static IEnumerable ExecuteRemoteEnumerable(this IAdbClient client, string command, DeviceData device) => + client.ExecuteRemoteEnumerable(command, device, AdbClient.Encoding); /// /// Runs the event log service on a device. diff --git a/AdvancedSharpAdbClient/Extensions/EnumerableBuilder.cs b/AdvancedSharpAdbClient/Extensions/EnumerableBuilder.cs index dff31a4..51a8200 100644 --- a/AdvancedSharpAdbClient/Extensions/EnumerableBuilder.cs +++ b/AdvancedSharpAdbClient/Extensions/EnumerableBuilder.cs @@ -21,7 +21,7 @@ public static class EnumerableBuilder /// /// The data that feeds the struct. /// A new instance of struct. - public static AdbCommandLineStatus AdbCommandLineStatusCreator(ReadOnlySpan values) => + public static AdbCommandLineStatus AdbCommandLineStatusCreator(params ReadOnlySpan values) => AdbCommandLineStatus.GetVersionFromOutput(values); /// @@ -236,7 +236,7 @@ public static UnixFileStatus UnixFileStatusCreator(ReadOnlySpan values) => }; } - static void ReadLogEntry(BinaryReader reader, ICollection parent) + static void ReadLogEntry(BinaryReader reader, params ICollection parent) { EventLogType type = (EventLogType)reader.ReadByte(); @@ -276,13 +276,13 @@ static void ReadLogEntry(BinaryReader reader, ICollection parent) ushort? ReadUInt16(in ReadOnlySpan bytes) { ReadOnlySpan data = ReadBytesSafe(bytes, 2); - return data == null ? null : (ushort)(data[0] | (data[1] << 8)); + return data.IsEmpty ? null : (ushort)(data[0] | (data[1] << 8)); } uint? ReadUInt32(in ReadOnlySpan bytes) { ReadOnlySpan data = ReadBytesSafe(bytes, 4); - return data == null ? null : (uint)(data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24)); + return data.IsEmpty ? null : (uint)(data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24)); } int? ReadInt32(in ReadOnlySpan bytes) diff --git a/AdvancedSharpAdbClient/Extensions/Extensions.cs b/AdvancedSharpAdbClient/Extensions/Extensions.cs index a61dfcd..40509e2 100644 --- a/AdvancedSharpAdbClient/Extensions/Extensions.cs +++ b/AdvancedSharpAdbClient/Extensions/Extensions.cs @@ -147,6 +147,22 @@ public static void Dispose(this WaitHandle waitHandle) progress == null ? null : progress.Report; #endif +#if HAS_WINRT + /// + /// Returns the absolute path for the specified path string. + /// + /// The file or directory for which to obtain absolute path information. + /// The fully qualified location of , such as "C:\MyFile.txt". + public static string GetFullPath(string path) => + Uri.TryCreate(path, UriKind.Absolute, out Uri? uri) + ? uri switch + { + { IsFile: true } => uri.LocalPath, + _ => uri.ToString(), + } + : Path.GetFullPath(path); +#endif + #if NET [SupportedOSPlatformGuard("Windows")] #endif diff --git a/AdvancedSharpAdbClient/Extensions/Factories.cs b/AdvancedSharpAdbClient/Extensions/Factories.cs index baf35f8..ed11bdb 100644 --- a/AdvancedSharpAdbClient/Extensions/Factories.cs +++ b/AdvancedSharpAdbClient/Extensions/Factories.cs @@ -13,6 +13,9 @@ namespace AdvancedSharpAdbClient /// public static class Factories { +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif static Factories() => Reset(); /// @@ -49,6 +52,9 @@ public static class Factories nameof(AdbClientFactory), nameof(AdbCommandLineClientFactory), nameof(SyncServiceFactory))] +#if HAS_WINRT && NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public static void Reset() { AdbSocketFactory = endPoint => new AdbSocket(endPoint); diff --git a/AdvancedSharpAdbClient/Extensions/SyncServiceExtensions.Async.cs b/AdvancedSharpAdbClient/Extensions/SyncServiceExtensions.Async.cs index d3b08de..f2df095 100644 --- a/AdvancedSharpAdbClient/Extensions/SyncServiceExtensions.Async.cs +++ b/AdvancedSharpAdbClient/Extensions/SyncServiceExtensions.Async.cs @@ -49,7 +49,6 @@ public static Task PullAsync(this ISyncService service, string remotePath, Strea /// An optional parameter which, when specified, returns progress notifications. The progress is reported as , representing the state of the file which has been transferred. /// A that can be used to cancel the task. /// A which represents the asynchronous operation. - [ContractVersion(typeof(UniversalApiContract), 65536u)] public static Task PushAsync(this ISyncService.IWinRT service, IInputStream stream, string remotePath, UnixFileStatus permissions, DateTimeOffset timestamp, IProgress? progress = null, CancellationToken cancellationToken = default) => service.PushAsync(stream, remotePath, permissions, timestamp, progress.AsAction(), cancellationToken); @@ -62,7 +61,6 @@ public static Task PushAsync(this ISyncService.IWinRT service, IInputStream stre /// An optional parameter which, when specified, returns progress notifications. The progress is reported as , representing the state of the file which has been transferred. /// A that can be used to cancel the task. /// A which represents the asynchronous operation. - [ContractVersion(typeof(UniversalApiContract), 65536u)] public static Task PullAsync(this ISyncService.IWinRT service, string remotePath, IOutputStream stream, IProgress? progress = null, CancellationToken cancellationToken = default) => service.PullAsync(remotePath, stream, progress.AsAction(), cancellationToken); #endif diff --git a/AdvancedSharpAdbClient/Extensions/UnixFileStatusExtensions.cs b/AdvancedSharpAdbClient/Extensions/UnixFileStatusExtensions.cs index 4e4ac82..5797dbc 100644 --- a/AdvancedSharpAdbClient/Extensions/UnixFileStatusExtensions.cs +++ b/AdvancedSharpAdbClient/Extensions/UnixFileStatusExtensions.cs @@ -216,7 +216,7 @@ public static string ToPermissionCode(this UnixFileStatus mode) #else char[] code = new char[10]; #endif - BitArray array = new(new[] { (int)mode }); + BitArray array = new([(int)mode]); code[9] = array[0] ? array[9] ? 't' : 'x' diff --git a/AdvancedSharpAdbClient/Interfaces/IAdbClient.Async.cs b/AdvancedSharpAdbClient/Interfaces/IAdbClient.Async.cs index 35c9e7f..e6a6c5c 100644 --- a/AdvancedSharpAdbClient/Interfaces/IAdbClient.Async.cs +++ b/AdvancedSharpAdbClient/Interfaces/IAdbClient.Async.cs @@ -230,7 +230,7 @@ public partial interface IAdbClient #if COMP_NETSTANDARD2_1 /// - /// Asynchronously executes a command on the adb server and returns the output. + /// Asynchronously executes a command on the adb server and returns the output. /// /// The target of command, such as shell, remount, dev, tcp, local, /// localreserved, localabstract, jdwp, track-jdwp, sync, reverse and so on. @@ -238,11 +238,11 @@ public partial interface IAdbClient /// The encoding to use when parsing the command output. /// A which can be used to cancel the asynchronous operation. /// A of strings, each representing a line of output from the command. - IAsyncEnumerable ExecuteServerCommandAsync(string target, string command, Encoding encoding, CancellationToken cancellationToken) => - ExecuteServerCommand(target, command, encoding).AsEnumerableAsync(cancellationToken); + IAsyncEnumerable ExecuteServerEnumerableAsync(string target, string command, Encoding encoding, CancellationToken cancellationToken) => + ExecuteServerEnumerable(target, command, encoding).AsEnumerableAsync(cancellationToken); /// - /// Asynchronously executes a command on the adb server and returns the output. + /// Asynchronously executes a command on the adb server and returns the output. /// /// The target of command, such as shell, remount, dev, tcp, local, /// localreserved, localabstract, jdwp, track-jdwp, sync, reverse and so on. @@ -251,19 +251,19 @@ IAsyncEnumerable ExecuteServerCommandAsync(string target, string command /// The encoding to use when parsing the command output. /// A which can be used to cancel the asynchronous operation. /// A of strings, each representing a line of output from the command. - IAsyncEnumerable ExecuteServerCommandAsync(string target, string command, IAdbSocket socket, Encoding encoding, CancellationToken cancellationToken) => - ExecuteServerCommand(target, command, socket, encoding).AsEnumerableAsync(cancellationToken); + IAsyncEnumerable ExecuteServerEnumerableAsync(string target, string command, IAdbSocket socket, Encoding encoding, CancellationToken cancellationToken) => + ExecuteServerEnumerable(target, command, socket, encoding).AsEnumerableAsync(cancellationToken); /// - /// Asynchronously executes a command on the device and returns the output. + /// Asynchronously executes a command on the device and returns the output. /// /// The command to execute. /// The device on which to run the command. /// The encoding to use when parsing the command output. /// A which can be used to cancel the asynchronous operation. /// A of strings, each representing a line of output from the command. - IAsyncEnumerable ExecuteRemoteCommandAsync(string command, DeviceData device, Encoding encoding, CancellationToken cancellationToken) => - ExecuteRemoteCommand(command, device, encoding).AsEnumerableAsync(cancellationToken); + IAsyncEnumerable ExecuteRemoteEnumerableAsync(string command, DeviceData device, Encoding encoding, CancellationToken cancellationToken) => + ExecuteRemoteEnumerable(command, device, encoding).AsEnumerableAsync(cancellationToken); /// /// Asynchronously runs the event log service on a device and returns it. @@ -464,7 +464,6 @@ public interface IWinRT /// A which can be used to cancel the asynchronous operation. /// The arguments to pass to adb install. /// A which represents the asynchronous operation. - [ContractVersion(typeof(UniversalApiContract), 65536u)] Task InstallAsync(DeviceData device, IRandomAccessStream apk, Action? callback, CancellationToken cancellationToken, params string[] arguments); /// @@ -478,7 +477,6 @@ public interface IWinRT /// A which can be used to cancel the asynchronous operation. /// The arguments to pass to adb install-create. /// A which represents the asynchronous operation. - [ContractVersion(typeof(UniversalApiContract), 65536u)] Task InstallMultipleAsync(DeviceData device, IRandomAccessStream baseAPK, IEnumerable splitAPKs, Action? callback, CancellationToken cancellationToken, params string[] arguments); /// @@ -492,7 +490,6 @@ public interface IWinRT /// A which can be used to cancel the asynchronous operation. /// The arguments to pass to adb install-create. /// A which represents the asynchronous operation. - [ContractVersion(typeof(UniversalApiContract), 65536u)] Task InstallMultipleAsync(DeviceData device, IEnumerable splitAPKs, string packageName, Action? callback, CancellationToken cancellationToken, params string[] arguments); /// @@ -506,7 +503,6 @@ public interface IWinRT /// The progress is reported as a value between 0 and 100, representing the percentage of the apk which has been transferred. /// A which can be used to cancel the asynchronous operation. /// A which represents the asynchronous operation. - [ContractVersion(typeof(UniversalApiContract), 65536u)] Task InstallWriteAsync(DeviceData device, IRandomAccessStream apk, string apkName, string session, Action? callback, CancellationToken cancellationToken); } #endif diff --git a/AdvancedSharpAdbClient/Interfaces/IAdbClient.cs b/AdvancedSharpAdbClient/Interfaces/IAdbClient.cs index 63751b5..2e180cc 100644 --- a/AdvancedSharpAdbClient/Interfaces/IAdbClient.cs +++ b/AdvancedSharpAdbClient/Interfaces/IAdbClient.cs @@ -239,17 +239,17 @@ public partial interface IAdbClient void ExecuteRemoteCommand(string command, DeviceData device, IShellOutputReceiver? receiver, Encoding encoding); /// - /// Executes a command on the adb server and returns the output. + /// Executes a command on the adb server and returns the output. /// /// The target of command, such as shell, remount, dev, tcp, local, /// localreserved, localabstract, jdwp, track-jdwp, sync, reverse and so on. /// The command to execute. /// The encoding to use when parsing the command output. /// A of strings, each representing a line of output from the command. - IEnumerable ExecuteServerCommand(string target, string command, Encoding encoding); + IEnumerable ExecuteServerEnumerable(string target, string command, Encoding encoding); /// - /// Executes a command on the adb server and returns the output. + /// Executes a command on the adb server and returns the output. /// /// The target of command, such as shell, remount, dev, tcp, local, /// localreserved, localabstract, jdwp, track-jdwp, sync, reverse and so on. @@ -257,16 +257,16 @@ public partial interface IAdbClient /// The to send command. /// The encoding to use when parsing the command output. /// A of strings, each representing a line of output from the command. - IEnumerable ExecuteServerCommand(string target, string command, IAdbSocket socket, Encoding encoding); + IEnumerable ExecuteServerEnumerable(string target, string command, IAdbSocket socket, Encoding encoding); /// - /// Executes a shell command on the device and returns the output. + /// Executes a shell command on the device and returns the output. /// /// The command to execute. /// The device on which to run the command. /// The encoding to use when parsing the command output. /// A of strings, each representing a line of output from the command. - IEnumerable ExecuteRemoteCommand(string command, DeviceData device, Encoding encoding); + IEnumerable ExecuteRemoteEnumerable(string command, DeviceData device, Encoding encoding); /// /// Runs the event log service on a device and returns it. diff --git a/AdvancedSharpAdbClient/Interfaces/ISyncService.Async.cs b/AdvancedSharpAdbClient/Interfaces/ISyncService.Async.cs index 0bb369d..93e7292 100644 --- a/AdvancedSharpAdbClient/Interfaces/ISyncService.Async.cs +++ b/AdvancedSharpAdbClient/Interfaces/ISyncService.Async.cs @@ -91,7 +91,6 @@ public interface IWinRT /// An optional parameter which, when specified, returns progress notifications. The progress is reported as , representing the state of the file which has been transferred. /// A that can be used to cancel the task. /// A which represents the asynchronous operation. - [ContractVersion(typeof(UniversalApiContract), 65536u)] Task PushAsync(IInputStream stream, string remotePath, UnixFileStatus permissions, DateTimeOffset timestamp, Action? callback, CancellationToken cancellationToken); /// @@ -102,7 +101,6 @@ public interface IWinRT /// An optional parameter which, when specified, returns progress notifications. The progress is reported as , representing the state of the file which has been transferred. /// A that can be used to cancel the task. /// A which represents the asynchronous operation. - [ContractVersion(typeof(UniversalApiContract), 65536u)] Task PullAsync(string remotePath, IOutputStream stream, Action? callback, CancellationToken cancellationToken); } #endif diff --git a/AdvancedSharpAdbClient/Logs/Interfaces/ILogger.cs b/AdvancedSharpAdbClient/Logs/Interfaces/ILogger.cs index 3d1b30c..4b93efd 100644 --- a/AdvancedSharpAdbClient/Logs/Interfaces/ILogger.cs +++ b/AdvancedSharpAdbClient/Logs/Interfaces/ILogger.cs @@ -28,5 +28,9 @@ public interface ILogger /// Generally used to enable activation of a named from dependency injection. /// /// The type whose name is used for the logger category name. - public interface ILogger : ILogger; + public interface ILogger : ILogger +#if NET9_0_OR_GREATER + where TCategoryName : allows ref struct +#endif + ; } diff --git a/AdvancedSharpAdbClient/Logs/Interfaces/ILoggerFactory.cs b/AdvancedSharpAdbClient/Logs/Interfaces/ILoggerFactory.cs index 7228f00..cb7b362 100644 --- a/AdvancedSharpAdbClient/Logs/Interfaces/ILoggerFactory.cs +++ b/AdvancedSharpAdbClient/Logs/Interfaces/ILoggerFactory.cs @@ -21,6 +21,10 @@ public interface ILoggerFactory /// /// The category name for messages produced by the logger. /// The . - ILogger CreateLogger(); + ILogger CreateLogger() +#if NET9_0_OR_GREATER + where T : allows ref struct +#endif + ; } } diff --git a/AdvancedSharpAdbClient/Logs/LogReader.cs b/AdvancedSharpAdbClient/Logs/LogReader.cs index 645d5a1..d906fad 100644 --- a/AdvancedSharpAdbClient/Logs/LogReader.cs +++ b/AdvancedSharpAdbClient/Logs/LogReader.cs @@ -190,7 +190,7 @@ public partial class LogReader(Stream stream) /// /// Reads a single log entry from the stream. /// - protected static void ReadLogEntry(BinaryReader reader, ICollection parent) + protected static void ReadLogEntry(BinaryReader reader, params ICollection parent) { EventLogType type = (EventLogType)reader.ReadByte(); diff --git a/AdvancedSharpAdbClient/Logs/LoggerProvider.cs b/AdvancedSharpAdbClient/Logs/LoggerProvider.cs index cc537f4..b52d748 100644 --- a/AdvancedSharpAdbClient/Logs/LoggerProvider.cs +++ b/AdvancedSharpAdbClient/Logs/LoggerProvider.cs @@ -32,6 +32,10 @@ public static class LoggerProvider /// /// The type. /// The that was created - public static ILogger CreateLogger() => _loggerFactory == null ? NullLogger.Instance : _loggerFactory.CreateLogger(); + public static ILogger CreateLogger() +#if NET9_0_OR_GREATER + where T : allows ref struct +#endif + => _loggerFactory == null ? NullLogger.Instance : _loggerFactory.CreateLogger(); } } diff --git a/AdvancedSharpAdbClient/Logs/NullLogger.cs b/AdvancedSharpAdbClient/Logs/NullLogger.cs index 48fa3bc..104581f 100644 --- a/AdvancedSharpAdbClient/Logs/NullLogger.cs +++ b/AdvancedSharpAdbClient/Logs/NullLogger.cs @@ -24,6 +24,9 @@ public void Log(LogLevel logLevel, Exception? exception, string? message, params /// Minimalistic logger that does nothing. /// public class NullLogger : NullLogger, ILogger +#if NET9_0_OR_GREATER + where T : allows ref struct +#endif { /// /// Returns an instance of . diff --git a/AdvancedSharpAdbClient/Models/AdbCommandLineStatus.cs b/AdvancedSharpAdbClient/Models/AdbCommandLineStatus.cs index bd7236a..0d051db 100644 --- a/AdvancedSharpAdbClient/Models/AdbCommandLineStatus.cs +++ b/AdvancedSharpAdbClient/Models/AdbCommandLineStatus.cs @@ -45,7 +45,7 @@ public readonly partial record struct AdbCommandLineStatus(Version? AdbVersion, /// /// The output of the adb.exe version command. /// A object that represents the version and path of the adb command line client. - public static AdbCommandLineStatus GetVersionFromOutput(IEnumerable output) + public static AdbCommandLineStatus GetVersionFromOutput(params IEnumerable output) { int index = 0; Version? adbVersion = null; @@ -92,7 +92,7 @@ public static AdbCommandLineStatus GetVersionFromOutput(IEnumerable outp /// /// The output of the adb.exe version command. /// A object that represents the version and path of the adb command line client. - public static AdbCommandLineStatus GetVersionFromOutput(ReadOnlySpan output) + public static AdbCommandLineStatus GetVersionFromOutput(params ReadOnlySpan output) { int index = 0; Version? adbVersion = null; @@ -149,7 +149,7 @@ public readonly IEnumerator GetEnumerator() } /// - public override string ToString() => string.Join(Environment.NewLine, [.. this]); + public override string ToString() => string.Join(Environment.NewLine, (string[])[.. this]); #if NET7_0_OR_GREATER [GeneratedRegex(VersionPattern)] diff --git a/AdvancedSharpAdbClient/Models/DeviceData.EventArgs.cs b/AdvancedSharpAdbClient/Models/DeviceData.EventArgs.cs index 11b7625..91d2be8 100644 --- a/AdvancedSharpAdbClient/Models/DeviceData.EventArgs.cs +++ b/AdvancedSharpAdbClient/Models/DeviceData.EventArgs.cs @@ -44,7 +44,7 @@ public override string ToString() /// /// The list of device. [DebuggerDisplay($"{nameof(DeviceDataNotifyEventArgs)} \\{{ {nameof(Devices)} = {{{nameof(Devices)}}} }}")] - public sealed class DeviceDataNotifyEventArgs(IEnumerable devices) : EventArgs + public sealed class DeviceDataNotifyEventArgs(params IEnumerable devices) : EventArgs { /// /// Gets the list of device where the change occurred. diff --git a/AdvancedSharpAdbClient/Models/Framebuffer.cs b/AdvancedSharpAdbClient/Models/Framebuffer.cs index e96d997..9ab1f03 100644 --- a/AdvancedSharpAdbClient/Models/Framebuffer.cs +++ b/AdvancedSharpAdbClient/Models/Framebuffer.cs @@ -19,7 +19,7 @@ namespace AdvancedSharpAdbClient.Models /// The at which the adb server is listening. /// The to create . [DebuggerDisplay($"{nameof(Framebuffer)} \\{{ {nameof(Header)} = {{{nameof(Header)}}}, {nameof(Data)} = {{{nameof(Data)}}}, {nameof(Device)} = {{{nameof(Device)}}}, {nameof(EndPoint)} = {{{nameof(EndPoint)}}} }}")] - public sealed class Framebuffer(DeviceData device, EndPoint endPoint, Func adbSocketFactory) : IDisposable, ICloneable, ICloneable + public sealed partial class Framebuffer(DeviceData device, EndPoint endPoint, Func adbSocketFactory) : IDisposable, ICloneable, ICloneable { /// /// The of s which contains the framebuffer header. @@ -234,13 +234,15 @@ public async Task RefreshAsync(bool reset = false, CancellationToken cancellatio public static explicit operator Bitmap?(Framebuffer value) => value.ToImage(); #endif -#if WINDOWS_UWP +#if HAS_WUXC /// /// Converts the framebuffer data to a . /// /// A which can be used to cancel the asynchronous task. /// An which represents the framebuffer data. - [ContractVersion(typeof(UniversalApiContract), 65536u)] +#if NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public Task ToBitmapAsync(CancellationToken cancellationToken = default) { EnsureNotDisposed(); @@ -253,7 +255,9 @@ public async Task RefreshAsync(bool reset = false, CancellationToken cancellatio /// The target to invoke the code on. /// A which can be used to cancel the asynchronous task. /// An which represents the framebuffer data. - [ContractVersion(typeof(UniversalApiContract), 65536u)] +#if NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public Task ToBitmapAsync(CoreDispatcher dispatcher, CancellationToken cancellationToken = default) { EnsureNotDisposed(); @@ -266,7 +270,10 @@ public async Task RefreshAsync(bool reset = false, CancellationToken cancellatio /// The target to invoke the code on. /// A which can be used to cancel the asynchronous task. /// An which represents the framebuffer data. - [ContractVersion(typeof(UniversalApiContract), 327680u)] +#if NET + [SupportedOSPlatform("Windows10.0.16299.0")] +#endif + [ContractVersion(typeof(UniversalApiContract), 0x50000u)] public Task ToBitmapAsync(DispatcherQueue dispatcher, CancellationToken cancellationToken = default) { EnsureNotDisposed(); diff --git a/AdvancedSharpAdbClient/Models/FramebufferHeader.cs b/AdvancedSharpAdbClient/Models/FramebufferHeader.cs index d1ea553..1c4c553 100644 --- a/AdvancedSharpAdbClient/Models/FramebufferHeader.cs +++ b/AdvancedSharpAdbClient/Models/FramebufferHeader.cs @@ -11,7 +11,7 @@ using System.Runtime.InteropServices; using System.Text; -#if WINDOWS_UWP +#if HAS_WUXC using System.Threading; #endif @@ -342,7 +342,7 @@ private PixelFormat StandardizePixelFormat(ref byte[] buffer) int blueIndex = (int)Blue.Offset / 8; int greenIndex = (int)Green.Offset / 8; int alphaIndex = (int)Alpha.Offset / 8; - + byte[] array = new byte[(int)Size * 4]; // Loop over the array and re-order as required for (int i = 0; i < (int)Size; i += 4) @@ -408,7 +408,18 @@ private PixelFormat StandardizePixelFormat(ref byte[] buffer) } #endif -#if WINDOWS_UWP +#if HAS_WUXC + /// + /// Gets is supported. + /// +#if NET + [SupportedOSPlatform("Windows10.0.10240.0")] + [SupportedOSPlatformGuard("Windows10.0.18362.0")] +#endif +#pragma warning disable CA1416 + public static bool IsHasThreadAccessSupported { get; } = ApiInformation.IsMethodPresent("Windows.System.DispatcherQueue", "HasThreadAccess"); +#pragma warning restore CA1416 + /// /// Converts a array containing the raw frame buffer data to a . /// @@ -417,7 +428,9 @@ private PixelFormat StandardizePixelFormat(ref byte[] buffer) /// A which can be used to cancel the asynchronous task. /// A that represents the image contained in the frame buffer, or /// if the framebuffer does not contain any data. This can happen when DRM is enabled on the device. - [ContractVersion(typeof(UniversalApiContract), 65536u)] +#if NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public Task ToBitmapAsync(byte[] buffer, CoreDispatcher dispatcher, CancellationToken cancellationToken = default) { if (dispatcher.HasThreadAccess) @@ -452,10 +465,13 @@ private PixelFormat StandardizePixelFormat(ref byte[] buffer) /// A which can be used to cancel the asynchronous task. /// A that represents the image contained in the frame buffer, or /// if the framebuffer does not contain any data. This can happen when DRM is enabled on the device. - [ContractVersion(typeof(UniversalApiContract), 327680u)] +#if NET + [SupportedOSPlatform("Windows10.0.16299.0")] +#endif + [ContractVersion(typeof(UniversalApiContract), 0x50000u)] public Task ToBitmapAsync(byte[] buffer, DispatcherQueue dispatcher, CancellationToken cancellationToken = default) { - if (ApiInformation.IsMethodPresent("Windows.System.DispatcherQueue", "HasThreadAccess") && dispatcher.HasThreadAccess) + if (IsHasThreadAccessSupported && dispatcher.HasThreadAccess) { return ToBitmapAsync(buffer, cancellationToken); } @@ -489,7 +505,9 @@ private PixelFormat StandardizePixelFormat(ref byte[] buffer) /// A which can be used to cancel the asynchronous task. /// A that represents the image contained in the frame buffer, or /// if the framebuffer does not contain any data. This can happen when DRM is enabled on the device. - [ContractVersion(typeof(UniversalApiContract), 65536u)] +#if NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public async Task ToBitmapAsync(byte[] buffer, CancellationToken cancellationToken = default) { ExceptionExtensions.ThrowIfNull(buffer); @@ -523,7 +541,9 @@ private PixelFormat StandardizePixelFormat(ref byte[] buffer) /// A byte array in which the images are stored according to this . /// A which describes how the alpha channel is stored. /// A that describes how the image data is represented in this . - [ContractVersion(typeof(UniversalApiContract), 65536u)] +#if NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif private BitmapPixelFormat StandardizePixelFormat(byte[] buffer, out BitmapAlphaMode alphaMode) { // Initial parameter validation. diff --git a/AdvancedSharpAdbClient/Models/ShellStream.cs b/AdvancedSharpAdbClient/Models/ShellStream.cs index 8b4d642..9882975 100644 --- a/AdvancedSharpAdbClient/Models/ShellStream.cs +++ b/AdvancedSharpAdbClient/Models/ShellStream.cs @@ -15,7 +15,7 @@ namespace AdvancedSharpAdbClient.Models /// CR LF character. This stream undoes that change. /// [DebuggerDisplay($"{{{nameof(ToString)}(),nq}}")] - public class ShellStream : Stream + public partial class ShellStream : Stream { /// /// The value which indicates whether the should close the stream when closed. diff --git a/AdvancedSharpAdbClient/Polyfills/Extensions/EnumerableExtensions.cs b/AdvancedSharpAdbClient/Polyfills/Extensions/EnumerableExtensions.cs index d6722c6..dce6803 100644 --- a/AdvancedSharpAdbClient/Polyfills/Extensions/EnumerableExtensions.cs +++ b/AdvancedSharpAdbClient/Polyfills/Extensions/EnumerableExtensions.cs @@ -26,7 +26,7 @@ internal static class EnumerableExtensions /// The collection itself cannot be , but it can contain elements that are /// , if type is a reference type. /// or is null. - public static void AddRange(this ICollection source, IEnumerable collection) + public static void AddRange(this ICollection source, params IEnumerable collection) { ExceptionExtensions.ThrowIfNull(source); ExceptionExtensions.ThrowIfNull(collection); diff --git a/AdvancedSharpAdbClient/Polyfills/Extensions/ExceptionExtensions.cs b/AdvancedSharpAdbClient/Polyfills/Extensions/ExceptionExtensions.cs index dec2900..ec05e08 100644 --- a/AdvancedSharpAdbClient/Polyfills/Extensions/ExceptionExtensions.cs +++ b/AdvancedSharpAdbClient/Polyfills/Extensions/ExceptionExtensions.cs @@ -76,15 +76,15 @@ public static void ThrowIfLessThan(T value, T other, [CallerArgumentExpressio /// /// The argument to validate as non-negative. /// The name of the parameter with which corresponds. -#if NET8_0_OR_GREATER public static void ThrowIfNegative(T value, [CallerArgumentExpression(nameof(value))] string? paramName = null) +#if NET8_0_OR_GREATER where T : INumberBase { ArgumentOutOfRangeException.ThrowIfNegative(value, paramName); #else - public static void ThrowIfNegative(double value, [CallerArgumentExpression(nameof(value))] string? paramName = null) + where T : struct, IComparable { - if (value < 0) + if (value.CompareTo(default) < 0) { throw new ArgumentOutOfRangeException(paramName, value, $"{paramName} ('{value}') must be a non-negative value."); } diff --git a/AdvancedSharpAdbClient/Polyfills/Extensions/StringExtensions.cs b/AdvancedSharpAdbClient/Polyfills/Extensions/StringExtensions.cs index ef146bf..0afed78 100644 --- a/AdvancedSharpAdbClient/Polyfills/Extensions/StringExtensions.cs +++ b/AdvancedSharpAdbClient/Polyfills/Extensions/StringExtensions.cs @@ -63,7 +63,7 @@ public static bool Contains(this string text, string value, StringComparison com /// A bitwise combination of the enumeration values that specifies whether to trim substrings and include empty substrings. /// An array whose elements contain the substrings from this instance that are delimited by . public static string[] Split(this string text, char separator, StringSplitOptions options = StringSplitOptions.None) => - text.Split(new[] { separator }, options); + text.Split([separator], options); /// /// Splits a string into a maximum number of substrings based on a specified delimiting @@ -77,7 +77,7 @@ public static string[] Split(this string text, char separator, StringSplitOption /// A bitwise combination of the enumeration values that specifies whether to trim substrings and include empty substrings. /// An array that contains at most count substrings from this instance that are delimited by . public static string[] Split(this string text, char separator, int count, StringSplitOptions options = StringSplitOptions.None) => - text.Split(new[] { separator }, count, options); + text.Split([separator], count, options); /// /// Determines whether this string instance starts with the specified character. diff --git a/AdvancedSharpAdbClient/Polyfills/Extensions/TaskExExtensions.cs b/AdvancedSharpAdbClient/Polyfills/Extensions/TaskExExtensions.cs index 29d4f39..9d7eb6c 100644 --- a/AdvancedSharpAdbClient/Polyfills/Extensions/TaskExExtensions.cs +++ b/AdvancedSharpAdbClient/Polyfills/Extensions/TaskExExtensions.cs @@ -8,6 +8,7 @@ using System.ComponentModel; using System.Runtime.CompilerServices; using System.Threading; +using System.Threading.Tasks; #if NET40 using Microsoft.Runtime.CompilerServices; @@ -100,7 +101,7 @@ public static Task FromResult(TResult result) => #endif .FromResult(result); -#if WINDOWS_UWP +#if HAS_WINRT /// /// Wait a synchronously by and return the result. /// @@ -108,7 +109,9 @@ public static Task FromResult(TResult result) => /// The to wait. /// A cancellation token that can be used to cancel the work if it has not yet started. /// The result of the completed task. - [ContractVersion(typeof(UniversalApiContract), 65536u)] +#if NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public static TResult AwaitByTaskCompleteSource(this IAsyncOperation function, CancellationToken cancellationToken = default) { TaskCompletionSource taskCompletionSource = new(); @@ -137,21 +140,31 @@ public static TResult AwaitByTaskCompleteSource(this IAsyncOperationA cancellation token that can be used to cancel the work if it has not yet started. public static void AwaitByTaskCompleteSource(this Task function, CancellationToken cancellationToken = default) { +#if NET + TaskCompletionSource taskCompletionSource = new(); +#else TaskCompletionSource taskCompletionSource = new(); - Task task = taskCompletionSource.Task; +#endif +#pragma warning disable IDE0008 + var task = taskCompletionSource.Task; +#pragma warning restore IDE0008 _ = Task.Factory.StartNew(async () => { try { await function.ConfigureAwait(false); +#if NET + _ = taskCompletionSource.TrySetResult(); +#else _ = taskCompletionSource.TrySetResult(null); +#endif } catch (Exception e) { _ = taskCompletionSource.TrySetException(e); } }, cancellationToken); - _ = task.Result; + task.Wait(cancellationToken); } /// diff --git a/AdvancedSharpAdbClient/Polyfills/Interfaces/ICloneable.cs b/AdvancedSharpAdbClient/Polyfills/Interfaces/ICloneable.cs index dd1a7b6..93ace10 100644 --- a/AdvancedSharpAdbClient/Polyfills/Interfaces/ICloneable.cs +++ b/AdvancedSharpAdbClient/Polyfills/Interfaces/ICloneable.cs @@ -2,8 +2,6 @@ // Copyright (c) The Android Open Source Project, Ryan Conrad, Quamotion, yungd1plomat, wherewhere. All rights reserved. // -using System; - #if !NETFRAMEWORK && !NETCOREAPP2_0_OR_GREATER && !NETSTANDARD2_0_OR_GREATER && !UAP10_0_15138_0 // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. @@ -22,6 +20,9 @@ internal interface ICloneable object Clone(); } } +#else +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.ICloneable))] +#endif namespace AdvancedSharpAdbClient.Polyfills { @@ -30,6 +31,9 @@ namespace AdvancedSharpAdbClient.Polyfills /// /// The type of the class. public interface ICloneable +#if NET9_0_OR_GREATER + where T : allows ref struct +#endif { /// /// Creates a new object that is a copy of the current instance. @@ -38,20 +42,3 @@ public interface ICloneable T Clone(); } } -#else -namespace AdvancedSharpAdbClient.Polyfills -{ - /// - /// Supports cloning, which creates a new instance of a class with the same value as an existing instance. - /// - /// The type of the class. - public interface ICloneable : ICloneable - { - /// - /// Creates a new object that is a copy of the current instance. - /// - /// A new object that is a copy of this instance. - new T Clone(); - } -} -#endif \ No newline at end of file diff --git a/AdvancedSharpAdbClient/Polyfills/Interfaces/IReadOnlyCollection.cs b/AdvancedSharpAdbClient/Polyfills/Interfaces/IReadOnlyCollection.cs index 08935d3..c690da1 100644 --- a/AdvancedSharpAdbClient/Polyfills/Interfaces/IReadOnlyCollection.cs +++ b/AdvancedSharpAdbClient/Polyfills/Interfaces/IReadOnlyCollection.cs @@ -20,4 +20,6 @@ internal interface IReadOnlyCollection : IEnumerable int Count { get; } } } +#else +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Collections.Generic.IReadOnlyCollection<>))] #endif \ No newline at end of file diff --git a/AdvancedSharpAdbClient/Polyfills/Interfaces/IReadOnlyList.cs b/AdvancedSharpAdbClient/Polyfills/Interfaces/IReadOnlyList.cs index 7d97e23..477e5a6 100644 --- a/AdvancedSharpAdbClient/Polyfills/Interfaces/IReadOnlyList.cs +++ b/AdvancedSharpAdbClient/Polyfills/Interfaces/IReadOnlyList.cs @@ -21,4 +21,6 @@ internal interface IReadOnlyList : IReadOnlyCollection T this[int index] { get; } } } +#else +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Collections.Generic.IReadOnlyList<>))] #endif \ No newline at end of file diff --git a/AdvancedSharpAdbClient/Polyfills/StringHandler.cs b/AdvancedSharpAdbClient/Polyfills/StringHandler.cs index b3ed7a8..b719d16 100644 --- a/AdvancedSharpAdbClient/Polyfills/StringHandler.cs +++ b/AdvancedSharpAdbClient/Polyfills/StringHandler.cs @@ -251,7 +251,7 @@ public void AppendFormatted(string? value, int alignment = 0, string? format = n /// Writes the specified character span to the handler. /// /// The span to write. - public void AppendFormatted(ReadOnlySpan value) => _ = _builder.Append(value); + public void AppendFormatted(params ReadOnlySpan value) => _ = _builder.Append(value); /// /// Writes the specified string of chars to the handler. @@ -361,4 +361,6 @@ private void AppendOrInsertAlignmentIfNeeded(int startingPos, int alignment) } } } +#else +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.CompilerServices.DefaultInterpolatedStringHandler))] #endif \ No newline at end of file diff --git a/AdvancedSharpAdbClient/Properties/GlobalUsings.cs b/AdvancedSharpAdbClient/Properties/GlobalUsings.cs index c63910e..1c5a383 100644 --- a/AdvancedSharpAdbClient/Properties/GlobalUsings.cs +++ b/AdvancedSharpAdbClient/Properties/GlobalUsings.cs @@ -17,33 +17,24 @@ global using System.Numerics; #endif -#if WINDOWS_UWP +#if HAS_WINRT global using System.Runtime.InteropServices.WindowsRuntime; global using Windows.ApplicationModel; global using Windows.Foundation; global using Windows.Foundation.Metadata; -global using Windows.Graphics.Imaging; global using Windows.Storage; global using Windows.Storage.Streams; -global using Windows.System; -global using Windows.UI.Core; -global using Windows.UI.Xaml.Media.Imaging; global using Buffer = System.Buffer; global using DateTime = System.DateTime; global using Point = System.Drawing.Point; global using TimeSpan = System.TimeSpan; #endif -#if WINDOWS10_0_17763_0_OR_GREATER -global using System.Runtime.InteropServices.WindowsRuntime; -global using Windows.ApplicationModel; -global using Windows.Foundation; -global using Windows.Foundation.Metadata; -global using Windows.Storage.Streams; -global using Buffer = System.Buffer; -global using DateTime = System.DateTime; -global using Point = System.Drawing.Point; -global using TimeSpan = System.TimeSpan; +#if HAS_WUXC +global using Windows.Graphics.Imaging; +global using Windows.System; +global using Windows.UI.Core; +global using Windows.UI.Xaml.Media.Imaging; #endif #if HAS_TASK diff --git a/AdvancedSharpAdbClient/Receivers/ConsoleOutputReceiver.cs b/AdvancedSharpAdbClient/Receivers/ConsoleOutputReceiver.cs index 74e00ce..b82af86 100644 --- a/AdvancedSharpAdbClient/Receivers/ConsoleOutputReceiver.cs +++ b/AdvancedSharpAdbClient/Receivers/ConsoleOutputReceiver.cs @@ -92,7 +92,7 @@ protected override void ThrowOnError(string line) /// Processes the new lines. /// /// The lines. - protected override void ProcessNewLines(IEnumerable lines) + protected override void ProcessNewLines(params IEnumerable lines) { foreach (string line in lines) { diff --git a/AdvancedSharpAdbClient/Receivers/MultiLineReceiver.cs b/AdvancedSharpAdbClient/Receivers/MultiLineReceiver.cs index 76b6ac0..db6765d 100644 --- a/AdvancedSharpAdbClient/Receivers/MultiLineReceiver.cs +++ b/AdvancedSharpAdbClient/Receivers/MultiLineReceiver.cs @@ -71,6 +71,6 @@ protected virtual void ThrowOnError(string line) /// Processes the new lines. /// /// The lines. - protected abstract void ProcessNewLines(IEnumerable lines); + protected abstract void ProcessNewLines(params IEnumerable lines); } } diff --git a/AdvancedSharpAdbClient/SyncService.Async.cs b/AdvancedSharpAdbClient/SyncService.Async.cs index 38b7ad6..1707cfc 100644 --- a/AdvancedSharpAdbClient/SyncService.Async.cs +++ b/AdvancedSharpAdbClient/SyncService.Async.cs @@ -212,7 +212,9 @@ public virtual async Task PullAsync(string remotePath, Stream stream, Action - [ContractVersion(typeof(UniversalApiContract), 65536u)] +#if NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public virtual async Task PushAsync(IInputStream stream, string remotePath, UnixFileStatus permission, DateTimeOffset timestamp, Action? progress = null, CancellationToken cancellationToken = default) { if (IsProcessing) { throw new InvalidOperationException($"The {nameof(SyncService)} is currently processing a request. Please {nameof(Clone)} a new {nameof(ISyncService)} or wait until the process is finished."); } @@ -322,6 +324,9 @@ public virtual async Task PushAsync(IInputStream stream, string remotePath, Unix } /// +#if NET + [SupportedOSPlatform("Windows10.0.10240.0")] +#endif public virtual async Task PullAsync(string remotePath, IOutputStream stream, Action? progress = null, CancellationToken cancellationToken = default) { if (IsProcessing) { throw new InvalidOperationException($"The {nameof(SyncService)} is currently processing a request. Please {nameof(Clone)} a new {nameof(ISyncService)} or wait until the process is finished."); } @@ -385,7 +390,7 @@ public virtual async Task PullAsync(string remotePath, IOutputStream stream, Act cancellationToken.ThrowIfCancellationRequested(); } - finish: return; + finish: return; } finally { @@ -475,7 +480,7 @@ public async IAsyncEnumerable GetDirectoryAsyncListing(string re try { - start: + start: // create the stat request message. await Socket.SendSyncRequestAsync(SyncCommand.LIST, remotePath, cancellationToken).ConfigureAwait(false); IsProcessing = true; @@ -505,7 +510,7 @@ public async IAsyncEnumerable GetDirectoryAsyncListing(string re isLocked = true; } - finish: + finish: yield break; } finally diff --git a/Directory.Build.props b/Directory.Build.props index 20c0ce1..890791c 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -23,7 +23,7 @@ https://github.com/SharpAdb/AdvancedSharpAdbClient snupkg .NET client for adb, Android Debug Bridge (AdvancedSharpAdbClient) - 3.3.13 + 3.3.14 @@ -59,5 +59,9 @@ UAP 10.0.22621.0 + + + 10.0 +