Fix a few things
This commit is contained in:
Родитель
72a3039011
Коммит
21cb3c162a
|
@ -7,7 +7,7 @@
|
||||||
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<RootNamespace>DeviceTests.Droid</RootNamespace>
|
<RootNamespace>DeviceTests.Droid</RootNamespace>
|
||||||
<AssemblyName>XamarinEssentialsDeviceTestsAndroid</AssemblyName>
|
<AssemblyName>DeviceTestsAndroid</AssemblyName>
|
||||||
<TargetFrameworkVersion>v10.0</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v10.0</TargetFrameworkVersion>
|
||||||
<AndroidApplication>True</AndroidApplication>
|
<AndroidApplication>True</AndroidApplication>
|
||||||
<AndroidUseIntermediateDesignerFile>true</AndroidUseIntermediateDesignerFile>
|
<AndroidUseIntermediateDesignerFile>true</AndroidUseIntermediateDesignerFile>
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
This file was in the app bundle.
|
|
|
@ -1 +0,0 @@
|
||||||
This file was in the app bundle.
|
|
|
@ -8,7 +8,7 @@
|
||||||
<OutputType>AppContainerExe</OutputType>
|
<OutputType>AppContainerExe</OutputType>
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>DeviceTests.UWP</RootNamespace>
|
<RootNamespace>DeviceTests.UWP</RootNamespace>
|
||||||
<AssemblyName>XamarinEssentialsDeviceTestsUWP</AssemblyName>
|
<AssemblyName>DeviceTestsUWP</AssemblyName>
|
||||||
<DefaultLanguage>en-US</DefaultLanguage>
|
<DefaultLanguage>en-US</DefaultLanguage>
|
||||||
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
|
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
|
||||||
<TargetPlatformVersion>10.0.16299.0</TargetPlatformVersion>
|
<TargetPlatformVersion>10.0.16299.0</TargetPlatformVersion>
|
||||||
|
@ -17,7 +17,9 @@
|
||||||
<EnableDotNetNativeCompatibleProfile>true</EnableDotNetNativeCompatibleProfile>
|
<EnableDotNetNativeCompatibleProfile>true</EnableDotNetNativeCompatibleProfile>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
<AppxPackageSigningEnabled>false</AppxPackageSigningEnabled>
|
<AppxPackageSigningEnabled>True</AppxPackageSigningEnabled>
|
||||||
|
<PackageCertificateThumbprint>7301D596D36DC7AD797E01BBF93CC2789AEA96C0</PackageCertificateThumbprint>
|
||||||
|
<PackageCertificateKeyFile>DeviceTests.UWP_TemporaryKey.pfx</PackageCertificateKeyFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
@ -113,25 +115,14 @@
|
||||||
<Prefer32Bit>true</Prefer32Bit>
|
<Prefer32Bit>true</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="UnitTests.HeadlessRunner" Version="2.0.0" />
|
|
||||||
<PackageReference Include="Xamarin.Forms" Version="4.8.0.1451" />
|
<PackageReference Include="Xamarin.Forms" Version="4.8.0.1451" />
|
||||||
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform" Version="6.2.9" />
|
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform" Version="6.2.9" />
|
||||||
<PackageReference Include="xunit" Version="2.4.1" />
|
<PackageReference Include="xunit" Version="2.4.1" />
|
||||||
<PackageReference Include="xunit.runner.devices" Version="2.5.25" />
|
<PackageReference Include="xunit.runner.devices" Version="2.5.25" />
|
||||||
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<SDKReference Include="WindowsMobile, Version=10.0.16299.0">
|
|
||||||
<Name>Windows Mobile Extensions for the UWP</Name>
|
|
||||||
</SDKReference>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\Xamarin.Essentials\Xamarin.Essentials.csproj">
|
|
||||||
<Project>{63a4f6a1-48bf-4d32-aed7-82f605edb042}</Project>
|
|
||||||
<Name>Xamarin.Essentials</Name>
|
|
||||||
</ProjectReference>
|
|
||||||
<ProjectReference Include="..\DeviceTests\DeviceTests.csproj">
|
<ProjectReference Include="..\DeviceTests\DeviceTests.csproj">
|
||||||
<Project>{be0de9a3-d92c-47c5-9ec4-dfb546bbdf77}</Project>
|
<Project>{E049A504-C168-41DC-80DF-0C4C6F363761}</Project>
|
||||||
<Name>DeviceTests</Name>
|
<Name>DeviceTests</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -153,9 +144,6 @@
|
||||||
</AppxManifest>
|
</AppxManifest>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="AppBundleFile.txt" />
|
|
||||||
<Content Include="Folder\AppBundleFile_Nested.txt" />
|
|
||||||
<Content Include="AppBundleFile_NoExtension" />
|
|
||||||
<Content Include="Properties\Default.rd.xml" />
|
<Content Include="Properties\Default.rd.xml" />
|
||||||
<Content Include="Assets\LockScreenLogo.scale-100.png" />
|
<Content Include="Assets\LockScreenLogo.scale-100.png" />
|
||||||
<Content Include="Assets\LockScreenLogo.scale-125.png" />
|
<Content Include="Assets\LockScreenLogo.scale-125.png" />
|
||||||
|
@ -190,10 +178,10 @@
|
||||||
<Content Include="Assets\Wide310x150Logo.scale-400.png" />
|
<Content Include="Assets\Wide310x150Logo.scale-400.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="DeviceTests.UWP_TemporaryKey.pfx" />
|
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
|
<None Include="DeviceTests.UWP_TemporaryKey.pfx" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||||
<VisualStudioVersion>14.0</VisualStudioVersion>
|
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
This file was in the app bundle.
|
|
|
@ -1,10 +1,10 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" IgnorableNamespaces="uap mp">
|
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" IgnorableNamespaces="uap mp">
|
||||||
<Identity Name="ec0cc741-fd3e-485c-81be-68815c480690" Publisher="CN=Microsoft" Version="1.0.1.0" />
|
<Identity Name="ec0cc741-fd3e-485c-81be-68815c480690" Publisher="CN=dotnet-devices" Version="1.0.1.0" />
|
||||||
<mp:PhoneIdentity PhoneProductId="ec0cc741-fd3e-485c-81be-68815c480690" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
|
<mp:PhoneIdentity PhoneProductId="ec0cc741-fd3e-485c-81be-68815c480690" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
|
||||||
<Properties>
|
<Properties>
|
||||||
<DisplayName>Tests</DisplayName>
|
<DisplayName>Tests</DisplayName>
|
||||||
<PublisherDisplayName>Microsoft</PublisherDisplayName>
|
<PublisherDisplayName>dotnet-devices</PublisherDisplayName>
|
||||||
<Logo>Assets\StoreLogo.png</Logo>
|
<Logo>Assets\StoreLogo.png</Logo>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Dependencies>
|
<Dependencies>
|
||||||
|
@ -31,8 +31,5 @@
|
||||||
</Applications>
|
</Applications>
|
||||||
<Capabilities>
|
<Capabilities>
|
||||||
<Capability Name="internetClient" />
|
<Capability Name="internetClient" />
|
||||||
<Capability Name="internetClientServer" />
|
|
||||||
<Capability Name="privateNetworkClientServer" />
|
|
||||||
<DeviceCapability Name="location" />
|
|
||||||
</Capabilities>
|
</Capabilities>
|
||||||
</Package>
|
</Package>
|
|
@ -10,9 +10,4 @@
|
||||||
<PackageReference Include="xunit.runner.devices" Version="2.5.25" />
|
<PackageReference Include="xunit.runner.devices" Version="2.5.25" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Update="CombinedWriter.cs">
|
|
||||||
<SubType></SubType>
|
|
||||||
</Compile>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
</Project>
|
|
@ -1,92 +1,246 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 15
|
# Visual Studio Version 16
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotnet-devices", "dotnet-devices\dotnet-devices.csproj", "{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}"
|
VisualStudioVersion = 16.0.30523.141
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-devices", "dotnet-devices\dotnet-devices.csproj", "{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotnet-devices.Tests", "dotnet-devices.Tests\dotnet-devices.Tests.csproj", "{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-devices.Tests", "dotnet-devices.Tests\dotnet-devices.Tests.csproj", "{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DeviceTests", "DeviceTests", "{BDAAACF1-1483-412C-A14C-A7976D0FBF3D}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DeviceTests", "DeviceTests", "{BDAAACF1-1483-412C-A14C-A7976D0FBF3D}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceTests", "DeviceTests\DeviceTests\DeviceTests.csproj", "{E049A504-C168-41DC-80DF-0C4C6F363761}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DeviceTests", "DeviceTests\DeviceTests\DeviceTests.csproj", "{E049A504-C168-41DC-80DF-0C4C6F363761}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceTests.iOS", "DeviceTests\DeviceTests.iOS\DeviceTests.iOS.csproj", "{EE8FC716-27FC-405B-BD27-AF17E01A6671}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceTests.iOS", "DeviceTests\DeviceTests.iOS\DeviceTests.iOS.csproj", "{EE8FC716-27FC-405B-BD27-AF17E01A6671}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceTests.Android", "DeviceTests\DeviceTests.Android\DeviceTests.Android.csproj", "{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceTests.Android", "DeviceTests\DeviceTests.Android\DeviceTests.Android.csproj", "{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceTests.UWP", "DeviceTests\DeviceTests.UWP\DeviceTests.UWP.csproj", "{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
Release|Any CPU = Release|Any CPU
|
Debug|ARM = Debug|ARM
|
||||||
Debug|iPhoneSimulator = Debug|iPhoneSimulator
|
Debug|ARM64 = Debug|ARM64
|
||||||
Release|iPhoneSimulator = Release|iPhoneSimulator
|
|
||||||
Debug|iPhone = Debug|iPhone
|
Debug|iPhone = Debug|iPhone
|
||||||
|
Debug|iPhoneSimulator = Debug|iPhoneSimulator
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
Release|ARM = Release|ARM
|
||||||
|
Release|ARM64 = Release|ARM64
|
||||||
Release|iPhone = Release|iPhone
|
Release|iPhone = Release|iPhone
|
||||||
|
Release|iPhoneSimulator = Release|iPhoneSimulator
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||||
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Release|Any CPU.Build.0 = Release|Any CPU
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||||
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Debug|ARM64.ActiveCfg = Debug|Any CPU
|
||||||
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Debug|ARM64.Build.0 = Debug|Any CPU
|
||||||
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
|
||||||
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
|
||||||
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||||
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Debug|iPhone.Build.0 = Debug|Any CPU
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||||
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||||
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||||
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||||
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Release|ARM.Build.0 = Release|Any CPU
|
||||||
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Release|ARM64.ActiveCfg = Release|Any CPU
|
||||||
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Release|ARM64.Build.0 = Release|Any CPU
|
||||||
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Release|iPhone.ActiveCfg = Release|Any CPU
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||||
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Release|iPhone.Build.0 = Release|Any CPU
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Release|iPhone.Build.0 = Release|Any CPU
|
||||||
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||||
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||||
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{09DD6E17-FEEC-4E1E-8823-7D6046D735F5}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||||
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Release|Any CPU.Build.0 = Release|Any CPU
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||||
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Debug|ARM64.ActiveCfg = Debug|Any CPU
|
||||||
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Debug|ARM64.Build.0 = Debug|Any CPU
|
||||||
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
|
||||||
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
|
||||||
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||||
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Debug|iPhone.Build.0 = Debug|Any CPU
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||||
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||||
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||||
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||||
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Release|ARM.Build.0 = Release|Any CPU
|
||||||
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Release|ARM64.ActiveCfg = Release|Any CPU
|
||||||
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Release|ARM64.Build.0 = Release|Any CPU
|
||||||
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Release|iPhone.ActiveCfg = Release|Any CPU
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||||
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Release|iPhone.Build.0 = Release|Any CPU
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Release|iPhone.Build.0 = Release|Any CPU
|
||||||
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||||
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||||
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{1F459FB5-8D2D-4649-90EF-5CC54FB10A88}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{E049A504-C168-41DC-80DF-0C4C6F363761}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{E049A504-C168-41DC-80DF-0C4C6F363761}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{E049A504-C168-41DC-80DF-0C4C6F363761}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||||
{E049A504-C168-41DC-80DF-0C4C6F363761}.Release|Any CPU.Build.0 = Release|Any CPU
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||||
{E049A504-C168-41DC-80DF-0C4C6F363761}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Debug|ARM64.ActiveCfg = Debug|Any CPU
|
||||||
{E049A504-C168-41DC-80DF-0C4C6F363761}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Debug|ARM64.Build.0 = Debug|Any CPU
|
||||||
{E049A504-C168-41DC-80DF-0C4C6F363761}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
|
||||||
{E049A504-C168-41DC-80DF-0C4C6F363761}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
|
||||||
{E049A504-C168-41DC-80DF-0C4C6F363761}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||||
{E049A504-C168-41DC-80DF-0C4C6F363761}.Debug|iPhone.Build.0 = Debug|Any CPU
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||||
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||||
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||||
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||||
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Release|ARM.Build.0 = Release|Any CPU
|
||||||
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Release|ARM64.ActiveCfg = Release|Any CPU
|
||||||
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Release|ARM64.Build.0 = Release|Any CPU
|
||||||
{E049A504-C168-41DC-80DF-0C4C6F363761}.Release|iPhone.ActiveCfg = Release|Any CPU
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||||
{E049A504-C168-41DC-80DF-0C4C6F363761}.Release|iPhone.Build.0 = Release|Any CPU
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Release|iPhone.Build.0 = Release|Any CPU
|
||||||
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||||
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||||
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{E049A504-C168-41DC-80DF-0C4C6F363761}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator
|
||||||
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Debug|Any CPU.Build.0 = Debug|iPhoneSimulator
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Debug|Any CPU.Build.0 = Debug|iPhoneSimulator
|
||||||
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Release|Any CPU.ActiveCfg = Release|iPhoneSimulator
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Debug|ARM.ActiveCfg = Debug|iPhone
|
||||||
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Release|Any CPU.Build.0 = Release|iPhoneSimulator
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Debug|ARM.Build.0 = Debug|iPhone
|
||||||
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Debug|ARM64.ActiveCfg = Debug|iPhone
|
||||||
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Debug|ARM64.Build.0 = Debug|iPhone
|
||||||
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
|
|
||||||
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
|
|
||||||
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Debug|iPhone.ActiveCfg = Debug|iPhone
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Debug|iPhone.ActiveCfg = Debug|iPhone
|
||||||
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Debug|iPhone.Build.0 = Debug|iPhone
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Debug|iPhone.Build.0 = Debug|iPhone
|
||||||
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
|
||||||
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
|
||||||
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Debug|x64.ActiveCfg = Debug|iPhoneSimulator
|
||||||
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Debug|x64.Build.0 = Debug|iPhoneSimulator
|
||||||
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Debug|x86.ActiveCfg = Debug|iPhoneSimulator
|
||||||
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Debug|x86.Build.0 = Debug|iPhoneSimulator
|
||||||
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Release|Any CPU.ActiveCfg = Release|iPhoneSimulator
|
||||||
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Release|Any CPU.Build.0 = Release|iPhoneSimulator
|
||||||
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Release|ARM.ActiveCfg = Release|iPhone
|
||||||
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Release|ARM.Build.0 = Release|iPhone
|
||||||
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Release|ARM64.ActiveCfg = Release|iPhone
|
||||||
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Release|ARM64.Build.0 = Release|iPhone
|
||||||
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Release|iPhone.ActiveCfg = Release|iPhone
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Release|iPhone.ActiveCfg = Release|iPhone
|
||||||
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Release|iPhone.Build.0 = Release|iPhone
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Release|iPhone.Build.0 = Release|iPhone
|
||||||
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
|
||||||
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
|
||||||
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Release|x64.ActiveCfg = Release|iPhoneSimulator
|
||||||
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Release|x64.Build.0 = Release|iPhoneSimulator
|
||||||
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Release|x86.ActiveCfg = Release|iPhoneSimulator
|
||||||
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671}.Release|x86.Build.0 = Release|iPhoneSimulator
|
||||||
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||||
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|Any CPU.Build.0 = Release|Any CPU
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||||
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||||
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|ARM.Deploy.0 = Debug|Any CPU
|
||||||
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|ARM64.ActiveCfg = Debug|Any CPU
|
||||||
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|ARM64.Build.0 = Debug|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|ARM64.Deploy.0 = Debug|Any CPU
|
||||||
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||||
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|iPhone.Build.0 = Debug|Any CPU
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|iPhone.Deploy.0 = Debug|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|x64.Deploy.0 = Debug|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Debug|x86.Deploy.0 = Debug|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|ARM.Build.0 = Release|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|ARM.Deploy.0 = Release|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|ARM64.ActiveCfg = Release|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|ARM64.Build.0 = Release|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|ARM64.Deploy.0 = Release|Any CPU
|
||||||
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|iPhone.ActiveCfg = Release|Any CPU
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||||
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|iPhone.Build.0 = Release|Any CPU
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|iPhone.Build.0 = Release|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|iPhone.Deploy.0 = Release|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|x64.Deploy.0 = Release|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1}.Release|x86.Deploy.0 = Release|Any CPU
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Debug|Any CPU.Build.0 = Debug|x86
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Debug|Any CPU.Deploy.0 = Debug|x86
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Debug|ARM.Build.0 = Debug|ARM
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Debug|ARM.Deploy.0 = Debug|ARM
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Debug|ARM64.Deploy.0 = Debug|ARM64
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Debug|iPhone.ActiveCfg = Debug|ARM
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Debug|iPhone.Build.0 = Debug|ARM
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Debug|iPhone.Deploy.0 = Debug|ARM
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Debug|iPhoneSimulator.ActiveCfg = Debug|x86
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Debug|iPhoneSimulator.Build.0 = Debug|x86
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Debug|iPhoneSimulator.Deploy.0 = Debug|x86
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Debug|x64.Deploy.0 = Debug|x64
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Debug|x86.Deploy.0 = Debug|x86
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Release|Any CPU.ActiveCfg = Release|x86
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Release|Any CPU.Build.0 = Release|x86
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Release|Any CPU.Deploy.0 = Release|x86
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Release|ARM.ActiveCfg = Release|ARM
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Release|ARM.Build.0 = Release|ARM
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Release|ARM.Deploy.0 = Release|ARM
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Release|ARM64.Deploy.0 = Release|ARM64
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Release|iPhone.ActiveCfg = Release|ARM
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Release|iPhone.Build.0 = Release|ARM
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Release|iPhone.Deploy.0 = Release|ARM
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Release|iPhoneSimulator.ActiveCfg = Release|x86
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Release|iPhoneSimulator.Build.0 = Release|x86
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Release|iPhoneSimulator.Deploy.0 = Release|x86
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Release|x64.Build.0 = Release|x64
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Release|x64.Deploy.0 = Release|x64
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Release|x86.Build.0 = Release|x86
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Release|x86.Deploy.0 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(NestedProjects) = preSolution
|
GlobalSection(NestedProjects) = preSolution
|
||||||
{E049A504-C168-41DC-80DF-0C4C6F363761} = {BDAAACF1-1483-412C-A14C-A7976D0FBF3D}
|
{E049A504-C168-41DC-80DF-0C4C6F363761} = {BDAAACF1-1483-412C-A14C-A7976D0FBF3D}
|
||||||
{EE8FC716-27FC-405B-BD27-AF17E01A6671} = {BDAAACF1-1483-412C-A14C-A7976D0FBF3D}
|
{EE8FC716-27FC-405B-BD27-AF17E01A6671} = {BDAAACF1-1483-412C-A14C-A7976D0FBF3D}
|
||||||
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1} = {BDAAACF1-1483-412C-A14C-A7976D0FBF3D}
|
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1} = {BDAAACF1-1483-412C-A14C-A7976D0FBF3D}
|
||||||
|
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B} = {BDAAACF1-1483-412C-A14C-A7976D0FBF3D}
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {14623120-794D-4BBB-8509-B49876E6AF2A}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using System;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
namespace DotNetDevices.Android
|
namespace DotNetDevices.Android
|
||||||
{
|
{
|
||||||
|
@ -24,11 +24,12 @@ namespace DotNetDevices.Android
|
||||||
return sdkRoot;
|
return sdkRoot;
|
||||||
|
|
||||||
var path = Path.Combine(sdkRoot, toolPath);
|
var path = Path.Combine(sdkRoot, toolPath);
|
||||||
if (!File.Exists(path))
|
var foundPath = FindFuzzyPath(path);
|
||||||
|
if (foundPath == null)
|
||||||
throw new FileNotFoundException($"Path to tool '{toolPath}' was not found in the SDK '{sdkRoot}'.", path);
|
throw new FileNotFoundException($"Path to tool '{toolPath}' was not found in the SDK '{sdkRoot}'.", path);
|
||||||
|
|
||||||
// return the full path to the tool
|
// return the full path to the tool
|
||||||
return path;
|
return foundPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var envvar in envvars)
|
foreach (var envvar in envvars)
|
||||||
|
@ -48,17 +49,34 @@ namespace DotNetDevices.Android
|
||||||
return varSdkRoot;
|
return varSdkRoot;
|
||||||
|
|
||||||
var path = Path.Combine(varSdkRoot, toolPath);
|
var path = Path.Combine(varSdkRoot, toolPath);
|
||||||
if (!File.Exists(path))
|
var foundPath = FindFuzzyPath(path);
|
||||||
|
if (foundPath == null)
|
||||||
{
|
{
|
||||||
logger?.LogWarning($"Found SDK at '{varSdkRoot}', but it did not contan the tool '{toolPath}'.");
|
logger?.LogWarning($"Found SDK at '{varSdkRoot}', but it did not contan the tool '{toolPath}'.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return the full path to the tool
|
// return the full path to the tool
|
||||||
return path;
|
return foundPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string? FindFuzzyPath(string path)
|
||||||
|
{
|
||||||
|
if (File.Exists(path))
|
||||||
|
return path;
|
||||||
|
|
||||||
|
var otherPath = Path.ChangeExtension(path, ".exe");
|
||||||
|
if (File.Exists(otherPath))
|
||||||
|
return otherPath;
|
||||||
|
|
||||||
|
otherPath = Path.ChangeExtension(path, ".bat");
|
||||||
|
if (File.Exists(otherPath))
|
||||||
|
return otherPath;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,109 +1,109 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using DotNetDevices.Processes;
|
using DotNetDevices.Processes;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace DotNetDevices.Android
|
namespace DotNetDevices.Android
|
||||||
{
|
{
|
||||||
public class EmulatorManager
|
public class EmulatorManager
|
||||||
{
|
{
|
||||||
private static readonly Regex consoleListeningRegex = new Regex(@"emulator: control console listening on port (\d+), ADB on port (\d+)");
|
private static readonly Regex consoleListeningRegex = new Regex(@"emulator: control console listening on port (\d+), ADB on port (\d+)");
|
||||||
private static readonly Regex adbConnectedRegex = new Regex(@"emulator: onGuestSendCommand: \[(.+)\] Adb connected, start proxing data");
|
private static readonly Regex adbConnectedRegex = new Regex(@"emulator: onGuestSendCommand: \[(.+)\] Adb connected, start proxing data");
|
||||||
private static readonly Regex alreadyBootedRegex = new Regex(@"emulator: ERROR: Running multiple emulators with the same AVD is an experimental feature\.");
|
private static readonly Regex alreadyBootedRegex = new Regex(@"emulator: ERROR: Running multiple emulators with the same AVD is an experimental feature\.");
|
||||||
|
|
||||||
private readonly ProcessRunner processRunner;
|
private readonly ProcessRunner processRunner;
|
||||||
private readonly ILogger? logger;
|
private readonly ILogger? logger;
|
||||||
private readonly string emulator;
|
private readonly string emulator;
|
||||||
|
|
||||||
public EmulatorManager(string? sdkRoot = null, ILogger? logger = null)
|
public EmulatorManager(string? sdkRoot = null, ILogger? logger = null)
|
||||||
{
|
{
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
processRunner = new ProcessRunner(logger);
|
processRunner = new ProcessRunner(logger);
|
||||||
emulator = AndroidSDK.FindPath(sdkRoot, Path.Combine("emulator", "emulator"), logger)
|
emulator = AndroidSDK.FindPath(sdkRoot, Path.Combine("emulator", "emulator"), logger)
|
||||||
?? throw new ArgumentException($"Unable to locate the Android Emulator. Make sure that ANDROID_HOME or ANDROID_SDK_ROOT is set.");
|
?? throw new ArgumentException($"Unable to locate the Android Emulator. Make sure that ANDROID_HOME or ANDROID_SDK_ROOT is set.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> BootVirtualDeviceAsync(string name, BootVirtualDeviceOptions? options = null, CancellationToken cancellationToken = default)
|
public async Task<int> BootVirtualDeviceAsync(string name, BootVirtualDeviceOptions? options = null, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (name == null)
|
if (name == null)
|
||||||
throw new ArgumentNullException(nameof(name));
|
throw new ArgumentNullException(nameof(name));
|
||||||
|
|
||||||
logger?.LogInformation($"Booting virtual device '{name}'...");
|
logger?.LogInformation($"Booting virtual device '{name}'...");
|
||||||
|
|
||||||
var args = $"-avd {name} -verbose";
|
var args = $"-avd {name} -verbose";
|
||||||
if (options?.NoWindow == true)
|
if (options?.NoWindow == true)
|
||||||
args += " -no-boot-anim -no-window";
|
args += " -no-boot-anim -no-window";
|
||||||
if (options?.NoSnapshots == true)
|
if (options?.NoSnapshots == true)
|
||||||
args += " -no-snapshot";
|
args += " -no-snapshot";
|
||||||
if (options?.WipeData == true)
|
if (options?.WipeData == true)
|
||||||
args += " -wipe-data";
|
args += " -wipe-data";
|
||||||
|
|
||||||
var port = -1;
|
var port = -1;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await processRunner.RunAsync(emulator, args, FindComplete, cancellationToken).ConfigureAwait(false);
|
await processRunner.RunAsync(emulator, args, FindComplete, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (ProcessResultException ex) when (IsAlreadyLaunched(ex))
|
catch (ProcessResultException ex) when (IsAlreadyLaunched(ex))
|
||||||
{
|
{
|
||||||
// no-op
|
// no-op
|
||||||
}
|
}
|
||||||
|
|
||||||
return port;
|
return port;
|
||||||
|
|
||||||
bool FindComplete(ProcessOutput output)
|
bool FindComplete(ProcessOutput output)
|
||||||
{
|
{
|
||||||
if (!output.IsError && output.Data is string o)
|
if (!output.IsError && output.Data is string o)
|
||||||
{
|
{
|
||||||
if (port <= 0)
|
if (port <= 0)
|
||||||
{
|
{
|
||||||
// first find port
|
// first find port
|
||||||
var match = consoleListeningRegex.Match(o);
|
var match = consoleListeningRegex.Match(o);
|
||||||
if (match.Success)
|
if (match.Success)
|
||||||
port = int.Parse(match.Groups[1].Value);
|
port = int.Parse(match.Groups[1].Value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// then wait for the boot finished
|
// then wait for the boot finished
|
||||||
var match = adbConnectedRegex.Match(o);
|
var match = adbConnectedRegex.Match(o);
|
||||||
if (match.Success)
|
if (match.Success)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsAlreadyLaunched(ProcessResultException ex)
|
bool IsAlreadyLaunched(ProcessResultException ex)
|
||||||
{
|
{
|
||||||
foreach (var output in ex.ProcessResult.GetOutput())
|
foreach (var output in ex.ProcessResult.GetOutput())
|
||||||
{
|
{
|
||||||
var match = alreadyBootedRegex.Match(output);
|
var match = alreadyBootedRegex.Match(output);
|
||||||
if (match.Success)
|
if (match.Success)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<VirtualDevice>> GetVirtualDevicesAsync(CancellationToken cancellationToken = default)
|
public async Task<IEnumerable<VirtualDevice>> GetVirtualDevicesAsync(CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
logger?.LogInformation("Retrieving all the virtual devices...");
|
logger?.LogInformation("Retrieving all the virtual devices...");
|
||||||
|
|
||||||
var args = $"-list-avds";
|
var args = $"-list-avds";
|
||||||
|
|
||||||
var result = await processRunner.RunAsync(emulator, args, null, cancellationToken).ConfigureAwait(false);
|
var result = await processRunner.RunAsync(emulator, args, null, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
var avd = new List<VirtualDevice>(result.OutputCount);
|
var avd = new List<VirtualDevice>(result.OutputCount);
|
||||||
foreach (var output in result.GetOutput())
|
foreach (var output in result.GetOutput())
|
||||||
{
|
{
|
||||||
avd.Add(new VirtualDevice(output));
|
avd.Add(new VirtualDevice(output));
|
||||||
}
|
}
|
||||||
return avd;
|
return avd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,214 +1,214 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.CommandLine;
|
using System.CommandLine;
|
||||||
using System.CommandLine.Invocation;
|
using System.CommandLine.Invocation;
|
||||||
using System.CommandLine.Parsing;
|
using System.CommandLine.Parsing;
|
||||||
using System.CommandLine.Rendering;
|
using System.CommandLine.Rendering;
|
||||||
using System.CommandLine.Rendering.Views;
|
using System.CommandLine.Rendering.Views;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using DotNetDevices.Android;
|
using DotNetDevices.Android;
|
||||||
using DotNetDevices.Apple;
|
using DotNetDevices.Apple;
|
||||||
using DotNetDevices.Logging;
|
using DotNetDevices.Logging;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace DotNetDevices.Commands
|
namespace DotNetDevices.Commands
|
||||||
{
|
{
|
||||||
public class AndroidCommand
|
public class AndroidCommand
|
||||||
{
|
{
|
||||||
public static Command Create()
|
public static Command Create()
|
||||||
{
|
{
|
||||||
return new Command("android", "Work with Android virtual devices.")
|
return new Command("android", "Work with Android virtual devices.")
|
||||||
{
|
{
|
||||||
new Command("list", "List the virtual devices.")
|
new Command("list", "List the virtual devices.")
|
||||||
{
|
{
|
||||||
new Option<string?>(new[] { "--sdk" }, "Whether or not to only include the available simulators."),
|
new Option<string?>(new[] { "--sdk" }, "Whether or not to only include the available simulators."),
|
||||||
new Option(new[] { "--available" }, "Whether or not to only include the available simulators."),
|
new Option(new[] { "--available" }, "Whether or not to only include the available simulators."),
|
||||||
new Option(new[] { "--booted" }, "Whether or not to only include the booted simulators."),
|
new Option(new[] { "--booted" }, "Whether or not to only include the booted simulators."),
|
||||||
new Option<SimulatorRuntime>(new[] { "--runtime" }, "The runtime to use when filtering."),
|
new Option<SimulatorRuntime>(new[] { "--runtime" }, "The runtime to use when filtering."),
|
||||||
new Option<string?>(new[] { "--version" }, description: "The runtime version to use when filtering. This could be in either <major> or <major>.<minor> version formats.",
|
new Option<string?>(new[] { "--version" }, description: "The runtime version to use when filtering. This could be in either <major> or <major>.<minor> version formats.",
|
||||||
parseArgument: CommandLine.ParseVersion),
|
parseArgument: CommandLine.ParseVersion),
|
||||||
CommandLine.CreateVerbosity(),
|
CommandLine.CreateVerbosity(),
|
||||||
new Argument<string?>("TERM", "The search term to use when filtering simulators. This could be any number of properties (UDID, runtime, version, availability, or state) as well as part of the simulator name.")
|
new Argument<string?>("TERM", "The search term to use when filtering simulators. This could be any number of properties (UDID, runtime, version, availability, or state) as well as part of the simulator name.")
|
||||||
{ Arity = ArgumentArity.ZeroOrOne },
|
{ Arity = ArgumentArity.ZeroOrOne },
|
||||||
}.WithHandler(CommandHandler.Create(typeof(AndroidCommand).GetMethod(nameof(HandleListAsync))!)),
|
}.WithHandler(CommandHandler.Create(typeof(AndroidCommand).GetMethod(nameof(HandleListAsync))!)),
|
||||||
new Command("create", "Create a new virtual device.")
|
new Command("create", "Create a new virtual device.")
|
||||||
{
|
{
|
||||||
new Option<string?>(new[] { "--sdk" }, "The path to the Android SDK directory."),
|
new Option<string?>(new[] { "--sdk" }, "The path to the Android SDK directory."),
|
||||||
new Option(new[] { "--replace" }, "Replace any existing virtual devices with the same name."),
|
new Option(new[] { "--replace" }, "Replace any existing virtual devices with the same name."),
|
||||||
CommandLine.CreateVerbosity(),
|
CommandLine.CreateVerbosity(),
|
||||||
new Argument<string?>("NAME", "The name of the new virtual device."),
|
new Argument<string?>("NAME", "The name of the new virtual device."),
|
||||||
new Argument<string?>("PACKAGE", "The package to use for the new virtual device."),
|
new Argument<string?>("PACKAGE", "The package to use for the new virtual device."),
|
||||||
}.WithHandler(CommandHandler.Create(typeof(AndroidCommand).GetMethod(nameof(HandleCreateAsync))!)),
|
}.WithHandler(CommandHandler.Create(typeof(AndroidCommand).GetMethod(nameof(HandleCreateAsync))!)),
|
||||||
new Command("boot", "Boot a particular simulator.")
|
new Command("boot", "Boot a particular simulator.")
|
||||||
{
|
{
|
||||||
new Option<string?>(new[] { "--sdk" }, "Whether or not to only include the available simulators."),
|
new Option<string?>(new[] { "--sdk" }, "Whether or not to only include the available simulators."),
|
||||||
CommandLine.CreateVerbosity(),
|
CommandLine.CreateVerbosity(),
|
||||||
new Argument<string?>("NAME", "The UDID of the simulator to boot."),
|
new Argument<string?>("NAME", "The UDID of the simulator to boot."),
|
||||||
}.WithHandler(CommandHandler.Create(typeof(AndroidCommand).GetMethod(nameof(HandleBootAsync))!)),
|
}.WithHandler(CommandHandler.Create(typeof(AndroidCommand).GetMethod(nameof(HandleBootAsync))!)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task HandleListAsync(
|
public static async Task HandleListAsync(
|
||||||
string? term = null,
|
string? term = null,
|
||||||
string? sdk = null,
|
string? sdk = null,
|
||||||
bool available = false,
|
bool available = false,
|
||||||
bool booted = false,
|
bool booted = false,
|
||||||
SimulatorRuntime? runtime = null,
|
SimulatorRuntime? runtime = null,
|
||||||
string? version = null,
|
string? version = null,
|
||||||
string? verbosity = null,
|
string? verbosity = null,
|
||||||
IConsole console = null!,
|
IConsole console = null!,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var logger = console.CreateLogger(verbosity);
|
var logger = console.CreateLogger(verbosity);
|
||||||
var avdmanager = new AVDManager(sdk, logger);
|
var avdmanager = new AVDManager(sdk, logger);
|
||||||
|
|
||||||
var devices = await avdmanager.GetDevicesAsync();
|
var devices = await avdmanager.GetDevicesAsync();
|
||||||
foreach (var device in devices)
|
foreach (var device in devices)
|
||||||
{
|
{
|
||||||
logger?.LogInformation(" - " + device.ToString());
|
logger?.LogInformation(" - " + device.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
var targets = await avdmanager.GetTargetsAsync();
|
var targets = await avdmanager.GetTargetsAsync();
|
||||||
foreach (var target in targets)
|
foreach (var target in targets)
|
||||||
{
|
{
|
||||||
logger?.LogInformation(" - " + target.ToString());
|
logger?.LogInformation(" - " + target.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
var avds = await avdmanager.GetVirtualDevicesAsync();
|
var avds = await avdmanager.GetVirtualDevicesAsync();
|
||||||
foreach (var avd in avds)
|
foreach (var avd in avds)
|
||||||
{
|
{
|
||||||
logger?.LogInformation(" - " + avd.ToString());
|
logger?.LogInformation(" - " + avd.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await avdmanager.DeleteVirtualDeviceAsync("TESTING");
|
await avdmanager.DeleteVirtualDeviceAsync("TESTING");
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await avdmanager.DeleteVirtualDeviceAsync("TESTED");
|
await avdmanager.DeleteVirtualDeviceAsync("TESTED");
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
|
||||||
await avdmanager.CreateVirtualDeviceAsync("TESTING", "system-images;android-28;google_apis_playstore;x86_64");
|
await avdmanager.CreateVirtualDeviceAsync("TESTING", "system-images;android-28;google_apis_playstore;x86_64");
|
||||||
|
|
||||||
await avdmanager.CreateVirtualDeviceAsync("TESTING", "system-images;android-28;google_apis_playstore;x86_64", new VirtualDeviceCreateOptions { Overwrite = true });
|
await avdmanager.CreateVirtualDeviceAsync("TESTING", "system-images;android-28;google_apis_playstore;x86_64", new VirtualDeviceCreateOptions { Overwrite = true });
|
||||||
|
|
||||||
await avdmanager.RenameVirtualDeviceAsync("TESTING", "TESTED");
|
await avdmanager.RenameVirtualDeviceAsync("TESTING", "TESTED");
|
||||||
await avdmanager.MoveVirtualDeviceAsync("TESTED", "/Users/matthew/.android/avd/tested.avd");
|
await avdmanager.MoveVirtualDeviceAsync("TESTED", "/Users/matthew/.android/avd/tested.avd");
|
||||||
|
|
||||||
//await avdmanager.DeleteVirtualDeviceAsync("TESTING");
|
//await avdmanager.DeleteVirtualDeviceAsync("TESTING");
|
||||||
|
|
||||||
//term = term?.ToLowerInvariant()?.Trim();
|
//term = term?.ToLowerInvariant()?.Trim();
|
||||||
|
|
||||||
//var simctl = new SimulatorControl(logger);
|
//var simctl = new SimulatorControl(logger);
|
||||||
//var simulators = await simctl.GetSimulatorsAsync(cancellationToken);
|
//var simulators = await simctl.GetSimulatorsAsync(cancellationToken);
|
||||||
|
|
||||||
//var filtered = (IEnumerable<Simulator>)simulators;
|
//var filtered = (IEnumerable<Simulator>)simulators;
|
||||||
//if (!string.IsNullOrWhiteSpace(term))
|
//if (!string.IsNullOrWhiteSpace(term))
|
||||||
//{
|
//{
|
||||||
// if (Guid.TryParse(term, out var guid))
|
// if (Guid.TryParse(term, out var guid))
|
||||||
// filtered = filtered.Where(s => s.Udid.ToLowerInvariant() == guid.ToString("d"));
|
// filtered = filtered.Where(s => s.Udid.ToLowerInvariant() == guid.ToString("d"));
|
||||||
// else if (Version.TryParse(term, out var versionFull))
|
// else if (Version.TryParse(term, out var versionFull))
|
||||||
// filtered = filtered.Where(s => s.Version == versionFull);
|
// filtered = filtered.Where(s => s.Version == versionFull);
|
||||||
// else if (int.TryParse(term, out var versionMjor))
|
// else if (int.TryParse(term, out var versionMjor))
|
||||||
// filtered = filtered.Where(s => s.Version.Major == versionMjor);
|
// filtered = filtered.Where(s => s.Version.Major == versionMjor);
|
||||||
// else if (Enum.TryParse<SimulatorRuntime>(term, true, out var r))
|
// else if (Enum.TryParse<SimulatorRuntime>(term, true, out var r))
|
||||||
// filtered = filtered.Where(s => s.Runtime == r);
|
// filtered = filtered.Where(s => s.Runtime == r);
|
||||||
// else if (Enum.TryParse<SimulatorState>(term, true, out var state))
|
// else if (Enum.TryParse<SimulatorState>(term, true, out var state))
|
||||||
// filtered = filtered.Where(s => s.State == state);
|
// filtered = filtered.Where(s => s.State == state);
|
||||||
// else if (Enum.TryParse<SimulatorAvailability>(term, true, out var availability))
|
// else if (Enum.TryParse<SimulatorAvailability>(term, true, out var availability))
|
||||||
// filtered = filtered.Where(s => s.Availability == availability);
|
// filtered = filtered.Where(s => s.Availability == availability);
|
||||||
// else if (Enum.TryParse<SimulatorType>(term, true, out var type))
|
// else if (Enum.TryParse<SimulatorType>(term, true, out var type))
|
||||||
// filtered = filtered.Where(s => s.Type == type);
|
// filtered = filtered.Where(s => s.Type == type);
|
||||||
// else
|
// else
|
||||||
// filtered = filtered.Where(s => s.Name.ToLowerInvariant().Contains(term));
|
// filtered = filtered.Where(s => s.Name.ToLowerInvariant().Contains(term));
|
||||||
//}
|
//}
|
||||||
//if (booted)
|
//if (booted)
|
||||||
// filtered = filtered.Where(s => s.State == SimulatorState.Booted);
|
// filtered = filtered.Where(s => s.State == SimulatorState.Booted);
|
||||||
//if (available)
|
//if (available)
|
||||||
// filtered = filtered.Where(s => s.Availability == SimulatorAvailability.Available);
|
// filtered = filtered.Where(s => s.Availability == SimulatorAvailability.Available);
|
||||||
//if (runtime != null)
|
//if (runtime != null)
|
||||||
// filtered = filtered.Where(s => s.Runtime == runtime);
|
// filtered = filtered.Where(s => s.Runtime == runtime);
|
||||||
//if (version != null)
|
//if (version != null)
|
||||||
//{
|
//{
|
||||||
// if (Version.TryParse(version, out var versionFull))
|
// if (Version.TryParse(version, out var versionFull))
|
||||||
// filtered = filtered.Where(s => s.Version == versionFull);
|
// filtered = filtered.Where(s => s.Version == versionFull);
|
||||||
// else if (int.TryParse(version, out var versionMjor))
|
// else if (int.TryParse(version, out var versionMjor))
|
||||||
// filtered = filtered.Where(s => s.Version.Major == versionMjor);
|
// filtered = filtered.Where(s => s.Version.Major == versionMjor);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//var all = filtered.ToList();
|
//var all = filtered.ToList();
|
||||||
|
|
||||||
//logger.LogInformation($"Found {all.Count} simulator[s].");
|
//logger.LogInformation($"Found {all.Count} simulator[s].");
|
||||||
|
|
||||||
//var table = new TableView<Simulator>();
|
//var table = new TableView<Simulator>();
|
||||||
//table.AddColumn(s => s.Udid, "UDID");
|
//table.AddColumn(s => s.Udid, "UDID");
|
||||||
//table.AddColumn(s => s.Name, "Name");
|
//table.AddColumn(s => s.Name, "Name");
|
||||||
//table.AddColumn(s => s.Runtime, "Runtime");
|
//table.AddColumn(s => s.Runtime, "Runtime");
|
||||||
//table.AddColumn(s => s.Version, "Version");
|
//table.AddColumn(s => s.Version, "Version");
|
||||||
//table.AddColumn(s => s.Availability, "Availability");
|
//table.AddColumn(s => s.Availability, "Availability");
|
||||||
//table.AddColumn(s => s.State, "State");
|
//table.AddColumn(s => s.State, "State");
|
||||||
//table.Items = all;
|
//table.Items = all;
|
||||||
|
|
||||||
//console.Append(new StackLayoutView { table });
|
//console.Append(new StackLayoutView { table });
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task HandleCreateAsync(
|
public static async Task HandleCreateAsync(
|
||||||
string name,
|
string name,
|
||||||
string package,
|
string package,
|
||||||
bool replace = false,
|
bool replace = false,
|
||||||
string? sdk = null,
|
string? sdk = null,
|
||||||
string? verbosity = null,
|
string? verbosity = null,
|
||||||
IConsole console = null!,
|
IConsole console = null!,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var logger = console.CreateLogger(verbosity);
|
var logger = console.CreateLogger(verbosity);
|
||||||
|
|
||||||
var avdmanager = new AVDManager(sdk, logger);
|
var avdmanager = new AVDManager(sdk, logger);
|
||||||
|
|
||||||
var options = new VirtualDeviceCreateOptions
|
var options = new VirtualDeviceCreateOptions
|
||||||
{
|
{
|
||||||
Overwrite = replace
|
Overwrite = replace
|
||||||
};
|
};
|
||||||
|
|
||||||
await avdmanager.CreateVirtualDeviceAsync(name, package, options, cancellationToken);
|
await avdmanager.CreateVirtualDeviceAsync(name, package, options, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<int> HandleBootAsync(
|
public static async Task<int> HandleBootAsync(
|
||||||
string name,
|
string name,
|
||||||
string? sdk = null,
|
string? sdk = null,
|
||||||
string? verbosity = null,
|
string? verbosity = null,
|
||||||
IConsole console = null!,
|
IConsole console = null!,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var logger = console.CreateLogger(verbosity);
|
var logger = console.CreateLogger(verbosity);
|
||||||
|
|
||||||
var emulator = new EmulatorManager(sdk, logger);
|
var emulator = new EmulatorManager(sdk, logger);
|
||||||
|
|
||||||
var avds = await emulator.GetVirtualDevicesAsync(cancellationToken);
|
var avds = await emulator.GetVirtualDevicesAsync(cancellationToken);
|
||||||
if (avds.All(a => !a.Name.Equals(name, StringComparison.OrdinalIgnoreCase)))
|
if (avds.All(a => !a.Name.Equals(name, StringComparison.OrdinalIgnoreCase)))
|
||||||
{
|
|
||||||
logger.LogError($"No virtual device with name {name} was found.");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
var options = new BootVirtualDeviceOptions
|
|
||||||
{
|
{
|
||||||
NoSnapshots = false,
|
logger.LogError($"No virtual device with name {name} was found.");
|
||||||
WipeData = true,
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
var options = new BootVirtualDeviceOptions
|
||||||
|
{
|
||||||
|
NoSnapshots = false,
|
||||||
|
WipeData = true,
|
||||||
};
|
};
|
||||||
var port = await emulator.BootVirtualDeviceAsync(name, options, cancellationToken);
|
var port = await emulator.BootVirtualDeviceAsync(name, options, cancellationToken);
|
||||||
if (port == -1)
|
if (port == -1)
|
||||||
logger.LogInformation($"Virtual device was already booted.");
|
logger.LogInformation($"Virtual device was already booted.");
|
||||||
else
|
else
|
||||||
logger.LogInformation($"device was booted to port {port}.");
|
logger.LogInformation($"device was booted to port {port}.");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,231 +1,231 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using DotNetDevices.Apple;
|
using DotNetDevices.Apple;
|
||||||
using DotNetDevices.Testing;
|
using DotNetDevices.Testing;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace DotNetDevices.Commands
|
namespace DotNetDevices.Commands
|
||||||
{
|
{
|
||||||
public class AppleTestCommand
|
public class AppleTestCommand
|
||||||
{
|
{
|
||||||
private readonly ILogger logger;
|
private readonly ILogger logger;
|
||||||
private readonly SimulatorControl simctl;
|
private readonly SimulatorControl simctl;
|
||||||
|
|
||||||
public AppleTestCommand(ILogger logger)
|
public AppleTestCommand(ILogger logger)
|
||||||
{
|
|
||||||
this.logger = logger;
|
|
||||||
|
|
||||||
simctl = new SimulatorControl(logger);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task RunTestsAsync(
|
|
||||||
string app,
|
|
||||||
string? deviceResults = null, // "TestResults.trx"
|
|
||||||
string? outputResults = null, // "TestResults.trx"
|
|
||||||
string? runtimeString = null,
|
|
||||||
string? versionString = null,
|
|
||||||
bool latest = false,
|
|
||||||
string? deviceType = null,
|
|
||||||
string? deviceName = null,
|
|
||||||
bool reset = false,
|
|
||||||
bool shutdown = false,
|
|
||||||
CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
// validate app / bundle
|
|
||||||
var plist = new PList(Path.Combine(app, "Info.plist"), logger);
|
|
||||||
var bundleId = await plist.GetBundleIdentifierAsync(cancellationToken);
|
|
||||||
|
|
||||||
// validate requested OS
|
|
||||||
var simulatorType = ParseSimulatorType(deviceType);
|
|
||||||
var runtime = ParseSimulatorRuntime(runtimeString);
|
|
||||||
var runtimeVersion = await ParseVersionAsync(versionString, runtime, cancellationToken);
|
|
||||||
|
|
||||||
logger.LogInformation($"Looking for an available {simulatorType} ({runtimeVersion}) simulator...");
|
|
||||||
var available = await GetAvailableSimulatorsAsync(simulatorType, runtime, runtimeVersion, latest, cancellationToken);
|
|
||||||
|
|
||||||
// first look for a booted device
|
|
||||||
var simulator = available.FirstOrDefault(s => s.State == SimulatorState.Booted) ?? available.FirstOrDefault();
|
|
||||||
logger.LogInformation($"Using simulator {simulator.Name} ({simulator.Runtime} {simulator.Version}): {simulator.Udid}");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (reset)
|
|
||||||
await simctl.EraseSimulatorAsync(simulator.Udid, true, cancellationToken);
|
|
||||||
|
|
||||||
await simctl.InstallAppAsync(simulator.Udid, app, true, cancellationToken);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var parser = new TestResultsParser();
|
|
||||||
|
|
||||||
var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
|
|
||||||
|
|
||||||
var launched = await simctl.LaunchAppAsync(simulator.Udid, bundleId, new LaunchAppOptions
|
|
||||||
{
|
|
||||||
CaptureOutput = true,
|
|
||||||
BootSimulator = true,
|
|
||||||
HandleOutput = output =>
|
|
||||||
{
|
|
||||||
parser.ParseTestOutput(
|
|
||||||
output,
|
|
||||||
line => logger?.LogWarning(line),
|
|
||||||
async () =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// wait a few seconds before terminating
|
|
||||||
await Task.Delay(1000, cts.Token);
|
|
||||||
|
|
||||||
await simctl.TerminateAppAsync(simulator.Udid, bundleId, cts.Token);
|
|
||||||
}
|
|
||||||
catch (OperationCanceledException)
|
|
||||||
{
|
|
||||||
// we expected this
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}, cancellationToken);
|
|
||||||
|
|
||||||
cts.Cancel();
|
|
||||||
|
|
||||||
if (deviceResults != null)
|
|
||||||
{
|
|
||||||
var dest = outputResults ?? Path.GetFileName(deviceResults);
|
|
||||||
|
|
||||||
logger.LogInformation($"Copying test results from simulator to {dest}...");
|
|
||||||
|
|
||||||
var dataPath = await simctl.GetDataDirectoryAsync(simulator.Udid, bundleId, cancellationToken);
|
|
||||||
var results = Path.Combine(dataPath, "Documents", deviceResults);
|
|
||||||
if (File.Exists(results))
|
|
||||||
File.Copy(results, dest, true);
|
|
||||||
else
|
|
||||||
logger.LogInformation($"No test results found.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logger.LogInformation($"Unable to determine the test results file.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
await simctl.UninstallAppAsync(simulator.Udid, bundleId, false, cancellationToken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (shutdown)
|
|
||||||
await simctl.ShutdownSimulatorAsync(simulator.Udid, cancellationToken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<List<Simulator>> GetAvailableSimulatorsAsync(SimulatorType type, SimulatorRuntime runtime, Version version, bool useLatest = true, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
// load all simulators
|
|
||||||
var simulators = await simctl.GetSimulatorsAsync(cancellationToken);
|
|
||||||
|
|
||||||
// find ones that can be used
|
|
||||||
var available = simulators
|
|
||||||
.Where(s => s.Availability == SimulatorAvailability.Available)
|
|
||||||
.Where(s => s.Runtime == runtime)
|
|
||||||
.Where(s => s.Type == type);
|
|
||||||
logger.LogDebug($"Found some available simulators:");
|
|
||||||
foreach (var sim in available)
|
|
||||||
{
|
|
||||||
logger.LogDebug($" {sim.Name} ({sim.Runtime} {sim.Version}): {sim.Udid}");
|
|
||||||
}
|
|
||||||
|
|
||||||
// filter by version info
|
|
||||||
string matchingPattern;
|
|
||||||
if (useLatest)
|
|
||||||
{
|
|
||||||
var min = version;
|
|
||||||
var max = new Version(min.Major + 1, 0);
|
|
||||||
available = available.Where(s => s.Version >= min && s.Version < max);
|
|
||||||
matchingPattern = $"[{min}, {max})";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
available = available.Where(s => s.Version == version);
|
|
||||||
matchingPattern = $"[{version}]";
|
|
||||||
}
|
|
||||||
|
|
||||||
var matching = available.ToList();
|
|
||||||
if (matching.Count > 0)
|
|
||||||
{
|
|
||||||
logger.LogDebug($"Found matching simulators {matchingPattern}:");
|
|
||||||
foreach (var sim in matching)
|
|
||||||
{
|
|
||||||
logger.LogDebug($" {sim.Name} ({sim.Runtime} {sim.Version}): {sim.Udid}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new Exception($"Unable to find any simulators that match version {matchingPattern}.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return matching;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<Version> ParseVersionAsync(string? version, SimulatorRuntime os, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
var osVersion = version?.ToLowerInvariant().Trim();
|
|
||||||
if (!Version.TryParse(osVersion, out var numberVersion))
|
|
||||||
{
|
|
||||||
if (int.TryParse(osVersion, out var v))
|
|
||||||
numberVersion = new Version(v, 0);
|
|
||||||
else if (string.IsNullOrEmpty(osVersion) || osVersion == "default")
|
|
||||||
numberVersion = await simctl.GetDefaultVersionAsync(os, cancellationToken);
|
|
||||||
else
|
|
||||||
throw new Exception($"Unable to determine the version for {osVersion}.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return numberVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static SimulatorRuntime ParseSimulatorRuntime(string? runtime)
|
|
||||||
{
|
{
|
||||||
var osName = runtime?.ToLowerInvariant()?.Trim();
|
this.logger = logger;
|
||||||
var os = osName switch
|
|
||||||
{
|
simctl = new SimulatorControl(logger);
|
||||||
null => SimulatorRuntime.iOS,
|
}
|
||||||
"" => SimulatorRuntime.iOS,
|
|
||||||
"ios" => SimulatorRuntime.iOS,
|
public async Task RunTestsAsync(
|
||||||
"watchos" => SimulatorRuntime.watchOS,
|
string app,
|
||||||
"tvos" => SimulatorRuntime.tvOS,
|
string? deviceResults = null, // "TestResults.trx"
|
||||||
_ => throw new Exception($"Unable to determine the OS for {runtime}.")
|
string? outputResults = null, // "TestResults.trx"
|
||||||
};
|
string? runtimeString = null,
|
||||||
return os;
|
string? versionString = null,
|
||||||
}
|
bool latest = false,
|
||||||
|
string? deviceType = null,
|
||||||
private static SimulatorType ParseSimulatorType(string? deviceType)
|
string? deviceName = null,
|
||||||
{
|
bool reset = false,
|
||||||
var deviceTypeName = deviceType?.ToLowerInvariant()?.Trim();
|
bool shutdown = false,
|
||||||
var device = deviceTypeName switch
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
// iPhone
|
// validate app / bundle
|
||||||
null => SimulatorType.iPhone,
|
var plist = new PList(Path.Combine(app, "Info.plist"), logger);
|
||||||
"" => SimulatorType.iPhone,
|
var bundleId = await plist.GetBundleIdentifierAsync(cancellationToken);
|
||||||
"iphone" => SimulatorType.iPhone,
|
|
||||||
"phone" => SimulatorType.iPhone,
|
// validate requested OS
|
||||||
// iPad
|
var simulatorType = ParseSimulatorType(deviceType);
|
||||||
"ipad" => SimulatorType.iPad,
|
var runtime = ParseSimulatorRuntime(runtimeString);
|
||||||
"tablet" => SimulatorType.iPad,
|
var runtimeVersion = await ParseVersionAsync(versionString, runtime, cancellationToken);
|
||||||
// iPod
|
|
||||||
"ipod" => SimulatorType.iPod,
|
logger.LogInformation($"Looking for an available {simulatorType} ({runtimeVersion}) simulator...");
|
||||||
// Apple TV
|
var available = await GetAvailableSimulatorsAsync(simulatorType, runtime, runtimeVersion, latest, cancellationToken);
|
||||||
"tv" => SimulatorType.AppleTV,
|
|
||||||
"appletv" => SimulatorType.AppleTV,
|
// first look for a booted device
|
||||||
// Apple Watch
|
var simulator = available.FirstOrDefault(s => s.State == SimulatorState.Booted) ?? available.FirstOrDefault();
|
||||||
"watch" => SimulatorType.AppleWatch,
|
logger.LogInformation($"Using simulator {simulator.Name} ({simulator.Runtime} {simulator.Version}): {simulator.Udid}");
|
||||||
"applewatch" => SimulatorType.AppleWatch,
|
|
||||||
//
|
try
|
||||||
_ => throw new Exception($"Unable to determine the simulator type for {deviceType}.")
|
{
|
||||||
};
|
if (reset)
|
||||||
return device;
|
await simctl.EraseSimulatorAsync(simulator.Udid, true, cancellationToken);
|
||||||
}
|
|
||||||
}
|
await simctl.InstallAppAsync(simulator.Udid, app, true, cancellationToken);
|
||||||
}
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var parser = new TestResultsParser();
|
||||||
|
|
||||||
|
var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
|
||||||
|
|
||||||
|
var launched = await simctl.LaunchAppAsync(simulator.Udid, bundleId, new LaunchAppOptions
|
||||||
|
{
|
||||||
|
CaptureOutput = true,
|
||||||
|
BootSimulator = true,
|
||||||
|
HandleOutput = output =>
|
||||||
|
{
|
||||||
|
parser.ParseTestOutput(
|
||||||
|
output,
|
||||||
|
line => logger?.LogWarning(line),
|
||||||
|
async () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// wait a few seconds before terminating
|
||||||
|
await Task.Delay(1000, cts.Token);
|
||||||
|
|
||||||
|
await simctl.TerminateAppAsync(simulator.Udid, bundleId, cts.Token);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
// we expected this
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}, cancellationToken);
|
||||||
|
|
||||||
|
cts.Cancel();
|
||||||
|
|
||||||
|
if (deviceResults != null)
|
||||||
|
{
|
||||||
|
var dest = outputResults ?? Path.GetFileName(deviceResults);
|
||||||
|
|
||||||
|
logger.LogInformation($"Copying test results from simulator to {dest}...");
|
||||||
|
|
||||||
|
var dataPath = await simctl.GetDataDirectoryAsync(simulator.Udid, bundleId, cancellationToken);
|
||||||
|
var results = Path.Combine(dataPath, "Documents", deviceResults);
|
||||||
|
if (File.Exists(results))
|
||||||
|
File.Copy(results, dest, true);
|
||||||
|
else
|
||||||
|
logger.LogInformation($"No test results found.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.LogInformation($"Unable to determine the test results file.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
await simctl.UninstallAppAsync(simulator.Udid, bundleId, false, cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (shutdown)
|
||||||
|
await simctl.ShutdownSimulatorAsync(simulator.Udid, cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<List<Simulator>> GetAvailableSimulatorsAsync(SimulatorType type, SimulatorRuntime runtime, Version version, bool useLatest = true, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
// load all simulators
|
||||||
|
var simulators = await simctl.GetSimulatorsAsync(cancellationToken);
|
||||||
|
|
||||||
|
// find ones that can be used
|
||||||
|
var available = simulators
|
||||||
|
.Where(s => s.Availability == SimulatorAvailability.Available)
|
||||||
|
.Where(s => s.Runtime == runtime)
|
||||||
|
.Where(s => s.Type == type);
|
||||||
|
logger.LogDebug($"Found some available simulators:");
|
||||||
|
foreach (var sim in available)
|
||||||
|
{
|
||||||
|
logger.LogDebug($" {sim.Name} ({sim.Runtime} {sim.Version}): {sim.Udid}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// filter by version info
|
||||||
|
string matchingPattern;
|
||||||
|
if (useLatest)
|
||||||
|
{
|
||||||
|
var min = version;
|
||||||
|
var max = new Version(min.Major + 1, 0);
|
||||||
|
available = available.Where(s => s.Version >= min && s.Version < max);
|
||||||
|
matchingPattern = $"[{min}, {max})";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
available = available.Where(s => s.Version == version);
|
||||||
|
matchingPattern = $"[{version}]";
|
||||||
|
}
|
||||||
|
|
||||||
|
var matching = available.ToList();
|
||||||
|
if (matching.Count > 0)
|
||||||
|
{
|
||||||
|
logger.LogDebug($"Found matching simulators {matchingPattern}:");
|
||||||
|
foreach (var sim in matching)
|
||||||
|
{
|
||||||
|
logger.LogDebug($" {sim.Name} ({sim.Runtime} {sim.Version}): {sim.Udid}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception($"Unable to find any simulators that match version {matchingPattern}.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return matching;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<Version> ParseVersionAsync(string? version, SimulatorRuntime os, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var osVersion = version?.ToLowerInvariant().Trim();
|
||||||
|
if (!Version.TryParse(osVersion, out var numberVersion))
|
||||||
|
{
|
||||||
|
if (int.TryParse(osVersion, out var v))
|
||||||
|
numberVersion = new Version(v, 0);
|
||||||
|
else if (string.IsNullOrEmpty(osVersion) || osVersion == "default")
|
||||||
|
numberVersion = await simctl.GetDefaultVersionAsync(os, cancellationToken);
|
||||||
|
else
|
||||||
|
throw new Exception($"Unable to determine the version for {osVersion}.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return numberVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SimulatorRuntime ParseSimulatorRuntime(string? runtime)
|
||||||
|
{
|
||||||
|
var osName = runtime?.ToLowerInvariant()?.Trim();
|
||||||
|
var os = osName switch
|
||||||
|
{
|
||||||
|
null => SimulatorRuntime.iOS,
|
||||||
|
"" => SimulatorRuntime.iOS,
|
||||||
|
"ios" => SimulatorRuntime.iOS,
|
||||||
|
"watchos" => SimulatorRuntime.watchOS,
|
||||||
|
"tvos" => SimulatorRuntime.tvOS,
|
||||||
|
_ => throw new Exception($"Unable to determine the OS for {runtime}.")
|
||||||
|
};
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SimulatorType ParseSimulatorType(string? deviceType)
|
||||||
|
{
|
||||||
|
var deviceTypeName = deviceType?.ToLowerInvariant()?.Trim();
|
||||||
|
var device = deviceTypeName switch
|
||||||
|
{
|
||||||
|
// iPhone
|
||||||
|
null => SimulatorType.iPhone,
|
||||||
|
"" => SimulatorType.iPhone,
|
||||||
|
"iphone" => SimulatorType.iPhone,
|
||||||
|
"phone" => SimulatorType.iPhone,
|
||||||
|
// iPad
|
||||||
|
"ipad" => SimulatorType.iPad,
|
||||||
|
"tablet" => SimulatorType.iPad,
|
||||||
|
// iPod
|
||||||
|
"ipod" => SimulatorType.iPod,
|
||||||
|
// Apple TV
|
||||||
|
"tv" => SimulatorType.AppleTV,
|
||||||
|
"appletv" => SimulatorType.AppleTV,
|
||||||
|
// Apple Watch
|
||||||
|
"watch" => SimulatorType.AppleWatch,
|
||||||
|
"applewatch" => SimulatorType.AppleWatch,
|
||||||
|
//
|
||||||
|
_ => throw new Exception($"Unable to determine the simulator type for {deviceType}.")
|
||||||
|
};
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче