Add usage samples for client API; Improve other doc pages to prep for 9.0.0 release (#89)
This commit is contained in:
Родитель
1625684b32
Коммит
d2723c4ceb
38
README.md
38
README.md
|
@ -4,29 +4,36 @@
|
|||
|
||||
Factory Orchestrator provides a simple and reliable way to run and manage factory line validation and fault analysis workflows. Beyond the factory floor Factory Orchestrator can be during os and hardware development to support various developer inner-loop and diagnostics activities.
|
||||
|
||||
Factory Orchestrator consists of two components:
|
||||
|
||||
* A .NET Core system service (Microsoft.FactoryOrchestrator.Service.exe): The service tracks task information, including unique per-run results and logging; even persisting task state to allow the service to be resilient to data loss due to client failure. It also provides a [robust API surface](https://microsoft.github.io/FactoryOrchestrator/use-the-factory-orchestrator-api/) for clients on the same device and/or over a network to monitor & interact with the service via C# .NET, C# UWP, or PowerShell code.
|
||||
|
||||
* [A UWP app](https://microsoft.github.io/FactoryOrchestrator/use-the-factory-orchestrator-app/): Communicates with the service to monitor & run executable tasks and commands on a device under test (DUT). This app can communicate with the service running on the same device and/or over a network. The app is optional; the service does not depend on the app.
|
||||
|
||||
Learn more about this tool and how to use it by reading the [documentation here](https://microsoft.github.io/FactoryOrchestrator/).
|
||||
|
||||
The [getting started](https://microsoft.github.io/FactoryOrchestrator/get-started-with-factory-orchestrator/) page is a great place to go once you've built the binaries for the project.
|
||||
|
||||
## **Factory Orchestrator consists of the following projects:**
|
||||
## **Factory Orchestrator consists of the following projects and binary releases:**
|
||||
|
||||
* **Microsoft.FactoryOrchestrator.Core**
|
||||
A .NET Standard library containing the core FactoryOrchestrator classes. Required in all projects.
|
||||
|
||||
* **Microsoft.FactoryOrchestrator.Server**
|
||||
A .NET Standard library containing the server-side FactoryOrchestrator classes. Required on all FactoryOrchestrator server projects.
|
||||
|
||||
* **Microsoft.FactoryOrchestrator.Service**
|
||||
.NET Core Executable project for Microsoft.FactoryOrchestrator.Service.exe, the FactoryOrchestrator server implementation. Requires administrator access to run.
|
||||
A .NET Standard library containing the core FactoryOrchestrator classes. Required in all projects. This is available as ["Microsoft.FactoryOrchestrator.Core" on NuGet](https://www.nuget.org/packages/Microsoft.FactoryOrchestrator.Core/).
|
||||
|
||||
* **Microsoft.FactoryOrchestrator.Client**
|
||||
.NET Standard library containing the client-side FactoryOrchestrator classes, required to interact with Microsoft.FactoryOrchestrator.Service. Also contains optional helper classes.
|
||||
.NET Standard library containing the client-side FactoryOrchestrator classes, required to interact with Microsoft.FactoryOrchestrator.Service. Also contains optional helper classes. This is available as ["Microsoft.FactoryOrchestrator.Client" on NuGet](https://www.nuget.org/packages/Microsoft.FactoryOrchestrator.Client/).
|
||||
|
||||
* **FactoryOrchestratorPowerShellLibrary**
|
||||
.NET Standard library containing a synchronous client-side FactoryOrchestrator class and Cmdlet wrapper classes, designed to be used via PowerShell.
|
||||
* **Microsoft.FactoryOrchestrator.UWPClient**
|
||||
UWP library containing the client-side FactoryOrchestrator classes, required to interact with Microsoft.FactoryOrchestrator.Service from a Universal Windows Platform app. This is available as ["Microsoft.FactoryOrchestrator.UWPClient" on NuGet](https://www.nuget.org/packages/Microsoft.FactoryOrchestrator.UWPClient/).
|
||||
|
||||
* **Microsoft.FactoryOrchestrator.PowerShell**
|
||||
PowerShell module containing a synchronous client-side FactoryOrchestrator class and Cmdlet wrapper classes, designed to be used WITH PowerShell 6+. This is available as ["Microsoft.FactoryOrchestrator.Client" on PowerShell Gallery](https://www.powershellgallery.com/packages/Microsoft.FactoryOrchestrator.Client/).
|
||||
|
||||
* **Microsoft.FactoryOrchestrator.Server**
|
||||
A .NET Standard library containing the server-side FactoryOrchestrator classes. Required on all FactoryOrchestrator server projects. ["Microsoft.FactoryOrchestrator.Server" on NuGet](https://www.nuget.org/packages/Microsoft.FactoryOrchestrator.Server/).
|
||||
|
||||
* **Microsoft.FactoryOrchestrator.Service**
|
||||
.NET Core Executable project for Microsoft.FactoryOrchestrator.Service.exe, the FactoryOrchestrator server implementation. Requires administrator access to run. This is available on [the GitHub Releases page as a .zip](https://github.com/microsoft/FactoryOrchestrator/releases).
|
||||
|
||||
* **Microsoft.FactoryOrchestrator.App**
|
||||
C# UWP app project for Microsoft.FactoryOrchestrator.App.exe, the UWP provides a GUI (Graphical User Interface) to manually interact with Microsoft.FactoryOrchestrator.Service.
|
||||
C# UWP app project for Microsoft.FactoryOrchestrator.App.exe, the UWP provides a GUI (Graphical User Interface) to manually interact with Microsoft.FactoryOrchestrator.Service. This is available on [the GitHub Releases page as a .msixbundle](https://github.com/microsoft/FactoryOrchestrator/releases).
|
||||
|
||||
Factory Orchestrator :green_heart: OSS.
|
||||
|
||||
|
@ -50,13 +57,14 @@ FactoryOrchestrator
|
|||
| ClientLibrary
|
||||
| ClientSample
|
||||
| CoreLibrary
|
||||
| PowerShellLibrary
|
||||
| ServerLibrary
|
||||
| Service
|
||||
| Tests
|
||||
└ UWPClientLibrary
|
||||
```
|
||||
|
||||
## Prerequisites
|
||||
## Prerequisites to build source code
|
||||
|
||||
### Install dependencies
|
||||
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
# Copyright (c) Microsoft Corporation.
|
||||
# Licensed under the MIT license.
|
||||
|
||||
# This script is used to add links to API documentation for manually authored Markdown files.
|
||||
# It attempts to be as cautious as possible to avoid mis-linking an unrelated work to a C# class/API/etc.
|
||||
# It should be run whenever you edit a manually authored Markdown file.
|
||||
$regex = '\(.*\)'
|
||||
|
||||
# Files to search
|
||||
$scriptDir = Split-Path $script:MyInvocation.MyCommand.Path
|
||||
$docPath = [System.IO.Path]::Join($scriptDir, "docs")
|
||||
$userDocs = Get-ChildItem -Path $docPath -filter "*.md"
|
||||
$apiDocs = Get-ChildItem -Path $docPath -filter "Microsoft-FactoryOrchestrator-Core-TaskList*.md" -Recurse
|
||||
$apiDocs += Get-ChildItem -Path $docPath -filter "Microsoft-FactoryOrchestrator-Core-TaskBase*.md" -Recurse
|
||||
$apiDocs += Get-ChildItem -Path $docPath -filter "Microsoft-FactoryOrchestrator-Core-UWPTask.md" -Recurse
|
||||
$apiDocs += Get-ChildItem -Path $docPath -filter "Microsoft-FactoryOrchestrator-Core-ExecutableTask.md" -Recurse
|
||||
$apiDocs += Get-ChildItem -Path $docPath -filter "Microsoft-FactoryOrchestrator-Core-PowerShellTask.md" -Recurse
|
||||
$apiDocs += Get-ChildItem -Path $docPath -filter "Microsoft-FactoryOrchestrator-Core-ExternalTask.md" -Recurse
|
||||
$apiDocs += Get-ChildItem -Path $docPath -filter "Microsoft-FactoryOrchestrator-Core-TaskRun*.md" -Recurse
|
||||
$apiDocs += Get-ChildItem -Path $docPath -filter "Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-*.md" -Recurse
|
||||
$apiDocs += Get-ChildItem -Path $docPath -filter "Microsoft-FactoryOrchestrator-Client-ServerPoller-*.md" -Recurse
|
||||
$apiDocs = $apiDocs | Sort-Object -Descending
|
||||
$apiNames = @{}
|
||||
|
||||
# Ignore these words in .md even though they map to APIs, as they are used in multiple classes or are vague words.
|
||||
$dupNames = @("Equals", "Name", "Guid", "ToString", "IsRunningOrPending", "Path", "Tasks", "Connect", "Status", "IpAddress", "EnumerateFiles", "EnumerateDirectories")
|
||||
foreach ($doc in $apiDocs)
|
||||
{
|
||||
$name = $($doc.BaseName)
|
||||
|
||||
$regex = '\(.*\)'
|
||||
$name = $name -replace $regex, ''
|
||||
|
||||
$name = $name.Split('-') | Select-Object -Last 1
|
||||
Write-Verbose "$name from $($doc.BaseName)"
|
||||
|
||||
if (-not $apiNames.ContainsKey($name))
|
||||
{
|
||||
if (-not $dupNames.Contains($name))
|
||||
{
|
||||
# Change file path to html path
|
||||
$path = $($doc.FullName).Replace($docPath, "..").Replace('\','/').Replace('(', '%28').Replace(')', '%29').Replace('.md', '/')
|
||||
$apiNames.add($name, $path)
|
||||
Write-Verbose "Added $name to $path"
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
# if a name is in two different classes, dont link it as we might link the wrong one
|
||||
Write-Verbose "Duplicate $name"
|
||||
|
||||
if (-not $dupNames.Contains($name))
|
||||
{
|
||||
$dupNames += $name
|
||||
}
|
||||
|
||||
if (-not ($apiNames[$name] -like "*()"))
|
||||
{
|
||||
$apiNames.remove($name)
|
||||
Write-Warning "Possible confusion with $name"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Add links until no more changes are found
|
||||
$changeMade = $true
|
||||
while ($changeMade -eq $true)
|
||||
{
|
||||
$changeMade = $false
|
||||
|
||||
foreach ($doc in $userDocs)
|
||||
{
|
||||
Write-Verbose "Checking $doc"
|
||||
$content = Get-Content $doc
|
||||
$edited = @()
|
||||
$incode = $false
|
||||
foreach ($line in $content)
|
||||
{
|
||||
$newline = $null
|
||||
if ($line.Contains('```'))
|
||||
{
|
||||
# sadly I didn't find a way to add links to code snippets :(
|
||||
$incode = -not $incode
|
||||
}
|
||||
|
||||
if (-not $incode)
|
||||
{
|
||||
# Split line into words and words into sections
|
||||
$words = $line.Split(' ')
|
||||
$sections = $words.Split('.')
|
||||
$sections = $sections.Split('(')
|
||||
$sections = $sections.Split(',')
|
||||
foreach ($section in $sections)
|
||||
{
|
||||
$section = $section.Replace(')', '')
|
||||
$section = $section.Replace(';', '')
|
||||
if ([System.Char]::IsUpper($section[0]))
|
||||
{
|
||||
if ($apiNames.ContainsKey($section))
|
||||
{
|
||||
$index = $line.IndexOf($section)
|
||||
|
||||
# Don't add a link if it's already a link :)
|
||||
while ($line[$index-1] -eq '[')
|
||||
{
|
||||
$index = $line.IndexOf($section, $index+1)
|
||||
if ($index -eq -1)
|
||||
{
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if ($index -eq -1)
|
||||
{
|
||||
continue
|
||||
}
|
||||
|
||||
# Ensure we are at the start of a new word, not in the middle of one.
|
||||
while (($line[$index-1] -ne ' ') -and ($line[$index-1] -ne '(') -and ($line[$index-1] -ne '.'))
|
||||
{
|
||||
$index = $line.IndexOf($section, $index+1)
|
||||
if ($index -eq -1)
|
||||
{
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ($index -eq -1)
|
||||
{
|
||||
continue
|
||||
}
|
||||
|
||||
# All checks are passed! Add the link!
|
||||
Write-Host "found $section at $index ($($line.Substring($index, $section.Length)))"
|
||||
Write-Host " $line"
|
||||
Write-Host ""
|
||||
Write-Host " $section maps to $($apiNames[$section])"
|
||||
$newline = $line.Substring(0, $index) + "[$section]($($apiNames[$section]))" + $line.Substring($index + $section.Length)
|
||||
$changeMade = $true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($null -ne $newline)
|
||||
{
|
||||
$edited += $newline
|
||||
}
|
||||
else
|
||||
{
|
||||
$edited += $line
|
||||
}
|
||||
}
|
||||
|
||||
Out-File -FilePath $doc -InputObject $edited
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
#### [Microsoft.FactoryOrchestrator.Client](./Microsoft-FactoryOrchestrator-Client.md 'Microsoft.FactoryOrchestrator.Client')
|
||||
### [Microsoft.FactoryOrchestrator.Client](./Microsoft-FactoryOrchestrator-Client.md 'Microsoft.FactoryOrchestrator.Client').[FactoryOrchestratorClient](./Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient.md 'Microsoft.FactoryOrchestrator.Client.FactoryOrchestratorClient')
|
||||
## FactoryOrchestratorClient.EnableLocalLoopbackForApp(string) Method
|
||||
Asynchronously Enables local loopback on the given UWP app.
|
||||
Asynchronously Enables local loopback on the given UWP app. Local loopback is enabled permanently for this app, persisting through reboots.
|
||||
```csharp
|
||||
public System.Threading.Tasks.Task EnableLocalLoopbackForApp(string aumid);
|
||||
```
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#### [Microsoft.FactoryOrchestrator.Core](./Microsoft-FactoryOrchestrator-Core.md 'Microsoft.FactoryOrchestrator.Core')
|
||||
### [Microsoft.FactoryOrchestrator.Core](./Microsoft-FactoryOrchestrator-Core.md 'Microsoft.FactoryOrchestrator.Core').[IFactoryOrchestratorService](./Microsoft-FactoryOrchestrator-Core-IFactoryOrchestratorService.md 'Microsoft.FactoryOrchestrator.Core.IFactoryOrchestratorService')
|
||||
## IFactoryOrchestratorService.EnableLocalLoopbackForApp(string) Method
|
||||
Enables local loopback on the given UWP app.
|
||||
Enables local loopback on the given UWP app. Local loopback is enabled permanently for this app, persisting through reboots.
|
||||
```csharp
|
||||
void EnableLocalLoopbackForApp(string aumid);
|
||||
```
|
||||
|
|
|
@ -0,0 +1,418 @@
|
|||
# Factory Orchestrator Client API Samples
|
||||
This page describes how to perform a variety of tasks with the Factory Orchestrator client APIs, using C# code snippets. There is also a complete C# client sample you can use as a starting point if you prefer.
|
||||
|
||||
All C# code snippets assume you have:
|
||||
```csharp
|
||||
using Microsoft.FactoryOrchestrator.Core;
|
||||
using Microsoft.FactoryOrchestrator.Client;
|
||||
```
|
||||
defined at the top of your .cs file.
|
||||
|
||||
Remember:
|
||||
|
||||
- All C# client APIs are asynchronous, but all PowerShell APIs are synchronous.
|
||||
- To use the C# client APIs in a UWP app, use an instance of FactoryOrchestratorUWPClient instead of [FactoryOrchestratorClient](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-FactoryOrchestratorClient%28System-Net-IPAddress_int%29/).
|
||||
- 'device' is used below to refer to the PC running the Factory Orchestrator service you connect to with the client. This could be the same PC as the client.
|
||||
|
||||
# Factory Orchestrator .NET client sample
|
||||
A sample .NET Core program that communicates with the Factory Orchestrator service is available in the Factory Orchestrator GitHub repo at: [https://github.com/microsoft/FactoryOrchestrator/tree/main/src/ClientSample](https://github.com/microsoft/FactoryOrchestrator/tree/main/src/ClientSample). You can build it with Visual Studio 2019 or the .NET Core 3.1+ SDK.
|
||||
|
||||
The sample shows you how to connect to a remote (or local) device running Factory Orchestrator service, copy test files to that device, sideload UWP apps, execute test content, and retrieve the test results from the device.
|
||||
|
||||
## Factory Orchestrator client sample usage
|
||||
Once the sample is built, create a folder on your PC with test content and a [FactoryOrchestratorXML](../tasks-and-tasklists/#author-and-manage-factory-orchestrator-tasklists) file that references the test content in the location it will execute from on the test device. Then, run the sample by calling:
|
||||
|
||||
```cmd
|
||||
dotnet ClientSample.dll <IP Address of DUT> <Folder on technician PC with test content AND FactoryOrchestratorXML files> <Destination folder on DUT> <Destination folder on this PC to save logs>
|
||||
```
|
||||
|
||||
The sample will then connect to the test device, copy test files to that device, sideload UWP apps, execute test content, and retrieve the test results from the device. You will be able to monitor the progress of the sample in the console, on the DUT (if it is running the Factory Orchestrator app), and on the Factory Orchestrator app on your PC (if it is connected to the test device).
|
||||
|
||||
# Establishing a connection to the service
|
||||
Before executing any other commands, the [Connect](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-Connect%28bool%29/)() API must be called. [Connect](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-Connect%28bool%29/)() verifies the target service is running and has a compatible version with your client. [Connect](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-Connect%28bool%29/)() throws an exeption if the connection fails. Alternately, you can use [TryConnect](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-TryConnect%28bool%29/)() which returns false if the connection fails instead.
|
||||
|
||||
## Connect to the service running on the local device (loopback)
|
||||
```csharp
|
||||
var client = new FactoryOrchestratorClient(IPAddress.Loopback);
|
||||
await client.Connect();
|
||||
```
|
||||
|
||||
```powershell
|
||||
# 127.0.0.1 == loopback
|
||||
$client = New-FactoryOrchestratorClient -IpAddress "127.0.0.1"
|
||||
$client.Connect();
|
||||
```
|
||||
|
||||
## Connect to the service running on a remote device
|
||||
C#:
|
||||
```csharp
|
||||
var client = new FactoryOrchestratorClient(IPAddress.Parse("192.168.0.100"));
|
||||
await client.Connect();
|
||||
```
|
||||
|
||||
PowerShell 7+:
|
||||
```powershell
|
||||
$client = New-FactoryOrchestratorClient -IpAddress "192.168.0.100"
|
||||
$client.Connect();
|
||||
```
|
||||
|
||||
|
||||
# Task, [TaskList](../CoreLibrary/CoreLibrary\Microsoft-FactoryOrchestrator-Core-TaskList/), & [TaskRun](../CoreLibrary/CoreLibrary\Microsoft-FactoryOrchestrator-Core-TaskRun/) creation, interaction, & manipulation
|
||||
## Load [TaskList](../CoreLibrary/CoreLibrary\Microsoft-FactoryOrchestrator-Core-TaskList/)s from a file, run the loaded TaskLists to completion. Then get the generated log files.
|
||||
[TaskList](../CoreLibrary/CoreLibrary\Microsoft-FactoryOrchestrator-Core-TaskList/)s defined in [FactoryOrchestratorXML](../tasks-and-tasklists/#author-and-manage-factory-orchestrator-tasklists) files are a great way to organize a set of operations you want Factory Orchestrator to execute. This example shows how to load [TaskList](../CoreLibrary/CoreLibrary\Microsoft-FactoryOrchestrator-Core-TaskList/)(s) from a [FactoryOrchestratorXML](../tasks-and-tasklists/#author-and-manage-factory-orchestrator-tasklists) file and then run the loaded TaskLists using [LoadTaskListsFromXmlFile](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-LoadTaskListsFromXmlFile%28string%29/) and [RunTaskList](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-RunTaskList%28System-Guid_int%29/). It also prints high-level info about the [TaskList](../CoreLibrary/CoreLibrary\Microsoft-FactoryOrchestrator-Core-TaskList/) statues with [GetTaskListSummaries](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-GetTaskListSummaries%28%29/). Depending on the attributes defined for each [TaskList](../CoreLibrary/CoreLibrary\Microsoft-FactoryOrchestrator-Core-TaskList/) they may or may not run in parallel.
|
||||
|
||||
```csharp
|
||||
// Assumes you have an existing FactoryOrchestratorXML file on the filesystem of the service at (string) FactoryOrchestratorXmlPath.
|
||||
// See "Copy a file or folder from client to device" or "Factory Orchestrator .NET client sample" for details on how to copy files to the service from a client.
|
||||
var taskListGuids = await client.LoadTaskListsFromXmlFile(FactoryOrchestratorXmlPath);
|
||||
foreach (var taskListGuid in taskListGuids)
|
||||
{
|
||||
await client.RunTaskList(taskListGuid);
|
||||
}
|
||||
|
||||
// Wait for all TaskLists to complete.
|
||||
while ((await client.GetTaskListSummaries()).Any(x => x.IsRunningOrPending))
|
||||
{
|
||||
await Task.Delay(2000);
|
||||
}
|
||||
|
||||
// Copy all logs to client-side device.
|
||||
await client.GetDirectoryFromDevice(await client.GetLogFolder(), @"C:\some_folder_on_client_for_logs");
|
||||
```
|
||||
|
||||
## Modify an existing [TaskList](../CoreLibrary/CoreLibrary\Microsoft-FactoryOrchestrator-Core-TaskList/)
|
||||
This example shows how to modify an existing [TaskList](../CoreLibrary/CoreLibrary\Microsoft-FactoryOrchestrator-Core-TaskList/) using [QueryTaskList](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-QueryTaskList%28System-Guid%29/) and [UpdateTaskList](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-UpdateTaskList%28Microsoft-FactoryOrchestrator-Core-TaskList%29/).
|
||||
```csharp
|
||||
// Assumes you have an existing TaskList in the service with a GUID of 34d0534b-ed09-46c2-b6bb-73cef9574944.
|
||||
var taskListGuid = new Guid("34d0534b-ed09-46c2-b6bb-73cef9574944");
|
||||
var taskList = await client.QueryTaskList(taskListGuid);
|
||||
|
||||
// Add new Tasks to the TaskList
|
||||
taskList.Tasks.Add(new PowerShellTask(@"C:\scripts\pwshScriptRunLast.ps1")); // Will run last
|
||||
taskList.Tasks.Insert(0, new ExecutableTask(@"C:\exes\runMeFirst.exe")); // Will run first
|
||||
|
||||
// Find an existing Task in the TaskList using LINQ and edit it
|
||||
taskList.Tasks.Where(x => x.Path == @"C:\exes\someExistingExeTask.exe").First().Arguments += " --aNewArgument";
|
||||
|
||||
// Modify TaskList properties to not allow parallel Task and TaskList execution.
|
||||
taskList.RunInParallel = false;
|
||||
taskList.AllowOtherTaskListsToRun = false;
|
||||
|
||||
// Update the TaskList on the service.
|
||||
await client.UpdateTaskList(taskList);
|
||||
```
|
||||
## Get all existing TaskLists and print out information about each [TaskList](../CoreLibrary/CoreLibrary\Microsoft-FactoryOrchestrator-Core-TaskList/).
|
||||
This example uses the [GetTaskListSummaries](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-GetTaskListSummaries%28%29/) and [QueryTaskList](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-QueryTaskList%28System-Guid%29/) methods print out information about running [TaskList](../CoreLibrary/CoreLibrary\Microsoft-FactoryOrchestrator-Core-TaskList/) instances.
|
||||
|
||||
```csharp
|
||||
var summaries = await client.GetTaskListSummaries();
|
||||
foreach (var summary in summaries)
|
||||
{
|
||||
Console.WriteLine($"TaskList with Name {summary.Name} and GUID {summary.Guid} is currently {summary.Status}...");
|
||||
|
||||
// If the TaskList is running, let's get some more details about the Tasks within it
|
||||
if (summary.Status == TaskStatus.Running)
|
||||
{
|
||||
var taskList = await client.QueryTaskList(summary.Guid);
|
||||
foreach (var task in taskList.Tasks.Where(x => x.LatestTaskRunStatus == TaskStatus.Running))
|
||||
{
|
||||
Console.WriteLine($" A {task.Type} Task with Name {task.Name} and GUID {task.Guid} has been running for {DateTime.Now - task.LatestTaskRunTimeStarted} seconds...");
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Stop executing an existing & running [TaskList](../CoreLibrary/CoreLibrary\Microsoft-FactoryOrchestrator-Core-TaskList/)
|
||||
```csharp
|
||||
// Assumes you have an existing TaskList in the service with a GUID of 34d0534b-ed09-46c2-b6bb-73cef9574944.
|
||||
await client.AbortTaskList(new Guid("34d0534b-ed09-46c2-b6bb-73cef9574944"));
|
||||
```
|
||||
|
||||
## Check for service events. Use WaitingForExternalTaskRun to handle every [ExternalTask](../CoreLibrary/Microsoft-FactoryOrchestrator-Core-ExternalTask/) requiring manual completion.
|
||||
This example uses the GetServiceEvents method to check if an [ExternalTask](../CoreLibrary/Microsoft-FactoryOrchestrator-Core-ExternalTask/) needs manual completion. If so, it uses [QueryTaskRun](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-QueryTaskRun%28System-Guid%29/) and [UpdateTaskRun](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-UpdateTaskRun%28Microsoft-FactoryOrchestrator-Core-TaskRun%29/) to complete the [ExternalTask](../CoreLibrary/Microsoft-FactoryOrchestrator-Core-ExternalTask/).
|
||||
|
||||
```csharp
|
||||
ulong lastEvent = 0;
|
||||
|
||||
// Loop, checking for new events
|
||||
while (true)
|
||||
{
|
||||
var events = await client.GetServiceEvents(lastEvent);
|
||||
foreach (var serviceEvent in events)
|
||||
{
|
||||
// update lastEvent so GetServiceEvents(lastEvent) will not return this event (or any event before it) again.
|
||||
lastEvent = serviceEvent.EventIndex;
|
||||
|
||||
// log event to console.
|
||||
Console.WriteLine($"New service event, seen at {serviceEvent.EventTime}: {serviceEvent.Message}");
|
||||
|
||||
if (serviceEvent.ServiceEventType == ServiceEventType.WaitingForExternalTaskRun)
|
||||
{
|
||||
// The service is waiting for a client to complete this TaskRun, let's do it!
|
||||
// Get the TaskRun object the event is referring to.
|
||||
var taskRun = await client.QueryTaskRun((Guid)serviceEvent.Guid);
|
||||
// Mark the TaskRun as Passed.
|
||||
taskRun.TaskStatus = TaskStatus.Passed;
|
||||
taskRun.TaskOutput.Add("Good job, this TaskRun is passed!");
|
||||
// Update the service with the now completed TaskRun.
|
||||
await client.UpdateTaskRun(taskRun);
|
||||
}
|
||||
}
|
||||
|
||||
// Wait 5 seconds before checking for new events
|
||||
await Task.Delay(5000);
|
||||
}
|
||||
```
|
||||
|
||||
## Run a program to completion and print output to console
|
||||
This example uses the [RunExecutable](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-RunExecutable%28string_string_string_bool%29/)() method to run a program outside of a [TaskList](../CoreLibrary/CoreLibrary\Microsoft-FactoryOrchestrator-Core-TaskList/). It then uses [QueryTaskRun](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-QueryTaskRun%28System-Guid%29/) to monitor the program's status.
|
||||
|
||||
```csharp
|
||||
// Start the program
|
||||
var taskRun = await client.RunExecutable(@"%windir%\system32\ping.exe","www.bing.com");
|
||||
|
||||
// Wait for program to complete
|
||||
while (!taskRun.TaskRunComplete)
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
taskRun = await client.QueryTaskRun(taskRun.Guid);
|
||||
}
|
||||
|
||||
// Program has completed.
|
||||
Console.WriteLine($"Program exited with code {taskRun.ExitCode} at {taskRun.TimeFinished}.");
|
||||
Console.WriteLine($"Program output:");
|
||||
foreach (var line in taskRun.TaskOutput)
|
||||
{
|
||||
Console.WriteLine(line);
|
||||
}
|
||||
```
|
||||
|
||||
```powershell
|
||||
# Start the program
|
||||
$taskRun = $client.RunExecutable("$env:windir\system32\ping.exe", "www.bing.com");
|
||||
|
||||
while (-not $taskRun.TaskRunComplete)
|
||||
{
|
||||
Start-Sleep -seconds 1
|
||||
$taskRun = $client.QueryTaskRun($taskRun.Guid);
|
||||
}
|
||||
|
||||
# Program has completed.
|
||||
Write-Host "Program exited with code $($taskRun.ExitCode) at $($taskRun.TimeFinished)."
|
||||
foreach ($line in $($taskRun.TaskOutput))
|
||||
{
|
||||
Write-Host $line
|
||||
}
|
||||
```
|
||||
|
||||
# Using [ServerPoller](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-ServerPoller-ServerPoller%28System-Nullable-System-Guid-_System-Type_int_bool_int%29/) instances to monitor [TaskList](../CoreLibrary/CoreLibrary\Microsoft-FactoryOrchestrator-Core-TaskList/) & [TaskRun](../CoreLibrary/CoreLibrary\Microsoft-FactoryOrchestrator-Core-TaskRun/) execution asynchronously with C# events
|
||||
The [ServerPoller](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-ServerPoller-ServerPoller%28System-Nullable-System-Guid-_System-Type_int_bool_int%29/) class is used to automatically poll the service for updates, and generates an [OnUpdatedObject](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-ServerPoller-OnUpdatedObject/) event only when the chosen [TaskList](../CoreLibrary/CoreLibrary\Microsoft-FactoryOrchestrator-Core-TaskList/) or [TaskRun](../CoreLibrary/CoreLibrary\Microsoft-FactoryOrchestrator-Core-TaskRun/) object you are polling updates. It can also be used to query all TaskLists for their high-level status. [ServerPoller](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-ServerPoller-ServerPoller%28System-Nullable-System-Guid-_System-Type_int_bool_int%29/) objects are a good choice to asynchronously update your UI or console output.
|
||||
|
||||
This example uses the ServerPoller's [StartPolling](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-ServerPoller-StartPolling%28Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient%29/) method and [OnUpdatedObject](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-ServerPoller-OnUpdatedObject/) event to monitor TaskList and [TaskRun](../CoreLibrary/CoreLibrary\Microsoft-FactoryOrchestrator-Core-TaskRun/) objects.
|
||||
|
||||
```csharp
|
||||
object consoleLock = new object();
|
||||
|
||||
// Pollers should have Dispose() called on them when no longer needed.
|
||||
ServerPoller taskListSummaryPoller = new ServerPoller(null, typeof(TaskList));
|
||||
// Assumes you have an existing TaskList in the service with a GUID of 34d0534b-ed09-46c2-b6bb-73cef9574944.
|
||||
ServerPoller taskListPoller = new ServerPoller(new Guid("34d0534b-ed09-46c2-b6bb-73cef9574944"), typeof(TaskList));
|
||||
// Assumes you have an existing TaskRun in the service with a GUID of e7e316eb-696c-433b-957a-bfcada75c81c
|
||||
ServerPoller taskRunPoller = new ServerPoller(new Guid("e7e316eb-696c-433b-957a-bfcada75c81c"), typeof(TaskRun));
|
||||
int lastOutputIndex = 0;
|
||||
|
||||
async void StartPollers()
|
||||
{
|
||||
var client = new FactoryOrchestratorClient(IPAddress.Parse("192.168.0.100"));
|
||||
await client.Connect();
|
||||
|
||||
// If GUID is null and type is TaskList, ServerPoller returns a List<TaskListSummary> object.
|
||||
taskListSummaryPoller.OnUpdatedObject += OnUpdatedTaskListSummaries;
|
||||
// If GUID is NOT null and type is TaskList, ServerPoller returns a TaskList object.
|
||||
taskListPoller.OnUpdatedObject += OnUpdatedTaskList;
|
||||
// If GUID is NOT null and type is TaskRun, ServerPoller returns a TaskRun object.
|
||||
taskRunPoller.OnUpdatedObject += OnUpdatedTaskRun;
|
||||
|
||||
|
||||
// StartPolling takes the FactoryOrchestratorClient you want to use for polling as an argument
|
||||
taskListSummaryPoller.StartPolling(client);
|
||||
taskListPoller.StartPolling(client);
|
||||
taskRunPoller.StartPolling(client);
|
||||
}
|
||||
|
||||
void OnUpdatedTaskListSummaries(object source, ServerPollerEventArgs e)
|
||||
{
|
||||
// New TaskListSummaries are ready, let's print them out
|
||||
if (e.Result != null)
|
||||
{
|
||||
List<TaskListSummary> updatedSummaries = (List<TaskListSummary>)e.Result;
|
||||
lock (consoleLock)
|
||||
{
|
||||
Console.WriteLine("--- Latest TaskLists Status ---");
|
||||
foreach (var summary in updatedSummaries)
|
||||
{
|
||||
Console.WriteLine(summary); // Uses TaskListSummary.ToString() to print readable output
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnUpdatedTaskList(object source, ServerPollerEventArgs e)
|
||||
{
|
||||
// New TaskList data for 34d0534b-ed09-46c2-b6bb-73cef9574944 is ready, let's print it out
|
||||
if (e.Result != null)
|
||||
{
|
||||
TaskList updatedTaskList = (TaskList)e.Result;
|
||||
lock (consoleLock)
|
||||
{
|
||||
Console.WriteLine("--- Latest Status of TaskList 34d0534b-ed09-46c2-b6bb-73cef9574944 ---");
|
||||
foreach (var task in updatedTaskList.Tasks)
|
||||
{
|
||||
Console.WriteLine($"Task {task.Name} is currently {task.LatestTaskRunStatus}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnUpdatedTaskRun(object source, ServerPollerEventArgs e)
|
||||
{
|
||||
// New TaskRun data for e7e316eb-696c-433b-957a-bfcada75c81c is ready, let's print it out
|
||||
if (e.Result != null)
|
||||
{
|
||||
TaskRun updatedTaskRun = (TaskRun)e.Result;
|
||||
lock (consoleLock)
|
||||
{
|
||||
if (lastOutputIndex < updatedTaskRun.TaskOutput.Count)
|
||||
{
|
||||
// We have new TaskRun output. Write it to console.
|
||||
Console.WriteLine("--- Latest output of TaskRun e7e316eb-696c-433b-957a-bfcada75c81c ---");
|
||||
while (lastOutputIndex < updatedTaskRun.TaskOutput.Count)
|
||||
{
|
||||
Console.WriteLine(updatedTaskRun.TaskOutput[lastOutputIndex++]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (updatedTaskRun.TaskRunComplete)
|
||||
{
|
||||
// Stop polling, run is complete and will never have new data
|
||||
taskRunPoller.StopPolling();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# Install an app, enable local loopback on the installed app, and then launch it (Windows Only & requires Windows Device Portal is running)
|
||||
This example uses [SendAndInstallApp](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-SendAndInstallApp%28string_System-Collections-Generic-List-string-_string%29/), [EnableLocalLoopbackForApp](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-EnableLocalLoopbackForApp%28string%29/), and [RunApp](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-RunApp%28string%29/) to install a UWP app on the device, enable local loopback on the app (enabling it to talk to a localhost Factory Orchestrator service), and launch the app.
|
||||
|
||||
```csharp
|
||||
// Assumes appFolder is a "standard" Visual Studio 2019 published app package with an appx/msix, a .cer certificate, and a dependencies folder.
|
||||
// appFolder is on the client device, NOT on the service. SendAndInstallApp copies it to the service-side device.
|
||||
var files = Directory.EnumerateFiles(appFolder);
|
||||
var app = files.Where(x => x.EndsWith(".appx", StringComparison.InvariantCultureIgnoreCase) || x.EndsWith(".appxbundle", StringComparison.InvariantCultureIgnoreCase) || x.EndsWith(".msixbundle", StringComparison.InvariantCultureIgnoreCase) || x.EndsWith(".msix", StringComparison.InvariantCultureIgnoreCase)).First();
|
||||
var cert = files.Where(x => x.EndsWith(".cer", StringComparison.InvariantCultureIgnoreCase)).First();
|
||||
var interiorDirs = Directory.EnumerateDirectories(appFolder);
|
||||
List<string> depsForApp = null;
|
||||
|
||||
if (interiorDirs.Count() > 0 && interiorDirs.Any(x => x.EndsWith(@"\dependencies", StringComparison.InvariantCultureIgnoreCase)))
|
||||
{
|
||||
// App directory has 'dependencies' folder, see if it contains dependent apps
|
||||
depsForApp = await Directory.EnumerateFiles(Path.Combine(appFolder, "dependencies"), "*", SearchOption.AllDirectories).ToList();
|
||||
if (depsForApp.Count > 0)
|
||||
{
|
||||
depsForApp = depsForApp.Where(x => x.EndsWith(".appx", StringComparison.InvariantCultureIgnoreCase) || x.EndsWith(".appxbundle", StringComparison.InvariantCultureIgnoreCase) || x.EndsWith(".msixbundle", StringComparison.InvariantCultureIgnoreCase) || x.EndsWith(".msix", StringComparison.InvariantCultureIgnoreCase)).ToList();
|
||||
|
||||
if (depsForApp.Count == 0)
|
||||
{
|
||||
depsForApp = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We have found the app, dependencies, and certificate on the client-side PC. SendAndInstallApp will copy the files to the service-side device and install the app using Windows Device Portal.
|
||||
await client.SendAndInstallApp(app, depsForApp, cert);
|
||||
// App installed sucessfully. Enable local loopback & then run it!
|
||||
// Assumes newky installed app AUMID is "Contoso.TestApp_8wekyb3d8bbwe".
|
||||
await client.EnableLocalLoopbackForApp("Contoso.TestApp_8wekyb3d8bbwe");
|
||||
await client.RunApp("Contoso.TestApp_8wekyb3d8bbwe");
|
||||
```
|
||||
|
||||
# System information
|
||||
The following examples show how to get information about the hardware and software of the device the service is running on.
|
||||
## Get OS and Factory Orchestrator build versions
|
||||
This example uses [GetOSVersionString](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-GetOSVersionString%28%29/), [GetOEMVersionString](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-GetOEMVersionString%28%29/), [GetServiceVersionString](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-GetServiceVersionString%28%29/), and [GetClientVersionString](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-GetClientVersionString%28%29/) to get various system & Factory Orchestrator information.
|
||||
|
||||
```csharp
|
||||
// GetOSVersionString() & GetOEMVersionString() are Windows only
|
||||
var osbuild = await client.GetOSVersionString();
|
||||
var oembuild = await client.GetOEMVersionString();
|
||||
var servicebuild = await client.GetServiceVersionString();
|
||||
var clientbuild = await client.GetClientVersionString();
|
||||
```
|
||||
|
||||
## Get network adapter info with [GetIpAddressesAndNicNames](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-GetIpAddressesAndNicNames%28%29/)
|
||||
```csharp
|
||||
var networkinfo = await client.GetIpAddressesAndNicNames();
|
||||
Console.WriteLine($"The following networks are present on {client.IpAddress}:");
|
||||
foreach (var network in networkinfo)
|
||||
{
|
||||
Console.WriteLine($"IP is {network.Item1}. NIC name is {network.Item2}");
|
||||
}
|
||||
```
|
||||
|
||||
## Get installed UWP apps (Windows only) with [GetInstalledApps](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-GetInstalledApps%28%29/)
|
||||
```csharp
|
||||
var appAUMIDs = await client.GetInstalledApps();
|
||||
Console.WriteLine($"The following UWPs are installed on {client.IpAddress}:");
|
||||
foreach (var aumid in appAUMIDs)
|
||||
{
|
||||
Console.WriteLine(aumid);
|
||||
}
|
||||
```
|
||||
|
||||
# System interaction
|
||||
## Reboot device with [RebootDevice](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-RebootDevice%28uint%29/)
|
||||
```csharp
|
||||
await client.RebootDevice();
|
||||
```
|
||||
|
||||
## Shutdown device with [ShutdownDevice](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-ShutdownDevice%28uint%29/)
|
||||
```csharp
|
||||
await client.ShutdownDevice();
|
||||
```
|
||||
|
||||
# File system interactions
|
||||
The following examples show how to perform file system operations on the device the service is running on.
|
||||
## List files & folders on device with EnumerateDirectories and EnumerateFiles
|
||||
```csharp
|
||||
// List all folders under %windir% recursively
|
||||
var dirsRecursive = await client.EnumerateDirectories(@"%windir%", true);
|
||||
// List all all files under %windir% (only, not recursive)
|
||||
var filesNonRecursve = await client.EnumerateFiles(@"%windir%", false);
|
||||
```
|
||||
|
||||
## Copy a file or folder from device to client with [GetFileFromDevice](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-GetFileFromDevice%28string_string_bool%29/) or [GetDirectoryFromDevice](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-GetDirectoryFromDevice%28string_string_bool%29/)
|
||||
```csharp
|
||||
// C:\destination_folder_on_client is created if needed
|
||||
var bytesReceived = await client.GetDirectoryFromDevice(@"C:\source_folder_on_device", @"C:\destination_folder_on_client");
|
||||
bytesReceived += await client.GetFileFromDevice(@"C:\different_folder_on_device\file.txt", @"C:\destination_folder_on_client\file.txt");
|
||||
```
|
||||
|
||||
## Copy a file or folder from client to device with [SendFileToDevice](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-SendFileToDevice%28string_string_bool%29/) or [SendDirectoryToDevice](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-SendDirectoryToDevice%28string_string_bool%29/)
|
||||
```csharp
|
||||
// C:\destination_folder_on_device is created if needed
|
||||
var bytesSent = await client.SendDirectoryToDevice(@"C:\source_folder_on_client", @"C:\destination_folder_on_device");
|
||||
bytesSent += await client.SendFileToDevice(@"C:\different_source_folder_on_client\file.txt", @"C:\destination_folder_on_device\file.txt");
|
||||
```
|
||||
|
||||
## Move a file or folder with [MoveFileOrFolder](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-MoveFileOrFolder%28string_string_bool%29/)
|
||||
```csharp
|
||||
await client.MoveFileOrFolder(@"C:\folder_on_device\file.txt", @"C:\different_folder_on_device\file.txt");
|
||||
await client.MoveFileOrFolder(@"C:\folder_on_device", @"C:\different_folder_on_device");
|
||||
```
|
||||
|
||||
## Delete a file or folder with [DeleteFileOrFolder](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-DeleteFileOrFolder%28string_bool%29/)
|
||||
```csharp
|
||||
await client.DeleteFileOrFolder(@"C:\folder_on_device\file.txt");
|
||||
await client.DeleteFileOrFolder(@"C:\folder_on_device");
|
||||
```
|
|
@ -1,48 +0,0 @@
|
|||
|
||||
# Factory Orchestrator utilities
|
||||
|
||||
In addition to providing a graphical interface to create, manage, and run Tasks and TaskLists. The Factory Orchestrator app also includes some basic utilities intended as a starting point for integration into a manufacturing line, fault analysis workflow or developer inner loop.
|
||||
|
||||
<!-- ## UWP Apps
|
||||
|
||||
This launches a UWP app that's installed on a device under test (DUT). This allows you to launch a UWP directly from the Factory Orchestrator app by clicking on its name in the list of installed UWP apps.
|
||||
|
||||
Your device must be configured to launch into an environment that supports launching UWP apps.
|
||||
|
||||
You can exit a launched UWP with ALT+F4, or from Windows Device Portal. -->
|
||||
|
||||
## Command Prompt
|
||||
|
||||
A basic, non-interactive, command prompt that allows you to troubleshoot without having use other methods like SSH or Windows Device Portal to connect to your DUT.
|
||||
|
||||
While you can run commands and see output when using the built-in command prompt in Factory Orchestrator, it's not an interactive shell. If you run a command that requires additional input, you won't be able to enter the additional input.
|
||||
|
||||
![The Command Prompt screen](./images/fo-cmd.png)
|
||||
|
||||
## (very) basic File Transfer
|
||||
|
||||
A basic file transfer function that enables you to transfer files to and from your device when you're connected from a technician PC. This feature is not visible in the Factory Orchestrator app when run the app and service on the same device.
|
||||
|
||||
### One-time setup (Windows 10 only)
|
||||
|
||||
First, install the Factory Orchestrator app on a Windows 10 system:
|
||||
|
||||
```PowerShell
|
||||
Add-AppxPackage -path "FactoryOrchestrator\Microsoft.FactoryOrchestratorApp_8wekyb3d8bbwe.msixbundle" -DependencyPath "frameworks\Microsoft.NET.CoreFramework.x64.Debug.2.2.appx" -DependencyPath "frameworks\Microsoft.NET.CoreRuntime.x64.2.2.appx" -DependencyPath "frameworks\Microsoft.VCLibs.x64.14.00.appx"
|
||||
```
|
||||
|
||||
Next, you need to give the Factory Orchestrator app full file system access for file transfer to work. Follow the directions on the [Windows 10 file system access and privacy](https://support.microsoft.com/en-us/help/4468237/windows-10-file-system-access-and-privacy-microsoft-privacy) page to give Factory Orchestrator access to the file system. You may need to launch the app at least once before it appears on the Settings app.
|
||||
|
||||
### Send file to a DUT
|
||||
|
||||
- From your Windows 10 device, launch Factory Orchestrator and connect to the IP address of the DUT.
|
||||
- In the "Client File" textbox, enter the full path to a file on your Windows 10 device.
|
||||
- In the "Server File" textbox, enter the full path of where you wish the file to be saved on the DUT. Make sure the location you're saving to is writeable.
|
||||
- Click "Send Client File to Server" to transfer the file from the Windows 10 device to the device.
|
||||
|
||||
### Receive file from your device device
|
||||
|
||||
- From your Windows 10 technician PC, launch Factory Orchestrator and connect to the IP address of the DUT.
|
||||
- In the "Server File" textbox, enter the full path to a file on the DUT.
|
||||
- In the "Client File" textbox, enter the full path to where you wish the file to be saved on the Windows 10 device.
|
||||
- Click "Save Server File to Client" to transfer the file to the DUT.
|
|
@ -1,11 +1,18 @@
|
|||
|
||||
# Get Started with Factory Orchestrator
|
||||
|
||||
## Install the service
|
||||
## Install or Run the service
|
||||
**The service can be downloaded from the [GitHub releases page](https://github.com/microsoft/FactoryOrchestrator/releases).**
|
||||
|
||||
The Factory Orchestrator service (Microsoft.FactoryOrchestrator.Service.exe) runs on your Device under Test and acts as the engine powering Factory Orchestrator. You can connect to the Factory Orchestrator service from a remote technician PC, or from the device itself.
|
||||
The Factory Orchestrator service (Microsoft.FactoryOrchestrator.Service.exe) runs on your Device under Test and acts as the engine powering Factory Orchestrator. To connect to the service, you can use the Factory Orchestrator UWP app, or interact with the service [programmatically using the Factory Orchestrator client APIs](use-the-factory-orchestrator-api.md). Multiple clients can be connected to the same service simultaneously.
|
||||
|
||||
User PowerShell to install the Factory Orchestrator on your device:
|
||||
The service can either be "run" (one time, not started on boot) or "installed" so that it automatically starts every boot.
|
||||
|
||||
### Run the service
|
||||
Download and unzip the service for your target OS and architecture. Then simply run Microsoft.FactoryOrchestrator.Service.exe as administrator/sudo.
|
||||
|
||||
### Install the service
|
||||
Download and unzip the service for your target OS and architecture. Then use an Administrator/Sudo PowerShell to install the Factory Orchestrator service on your device. When installed as a system service (daemon), the service will start every boot until disabled or uninstalled:
|
||||
|
||||
```PowerShell
|
||||
## Optionally set it's start up to automatic with: -StartupType Automatic
|
||||
|
@ -14,35 +21,23 @@ User PowerShell to install the Factory Orchestrator on your device:
|
|||
Start-Service -Name "FactoryOrchestrator"
|
||||
```
|
||||
|
||||
To connect to the service, you can use the Factory Orchestrator UWP app, or interact with the service programattically using the Factory Orchestrator client APIs.
|
||||
### Service configuration
|
||||
See [Service configuration](../service-configuration) for details on how you can configure the Factory Orchestraor service's default behavior.
|
||||
|
||||
## Install the app
|
||||
|
||||
You can install the Factory Orchestrator app on your DUT or on a technician PC.
|
||||
You can install the Factory Orchestrator app on your DUT or on a technician PC running Windows. The app can be downloaded from the [GitHub releases page](https://github.com/microsoft/FactoryOrchestrator/releases).
|
||||
|
||||
To install the app:
|
||||
To install the app, run the .msixbundle to install the app. Alternately, use [Windows Device Portal](https://docs.microsoft.com/en-us/windows/uwp/debug-test-perf/device-portal) to install the app on your DUT. The app on the GitHub releases page is signed by Microsoft and does not require a certificate file to install.
|
||||
|
||||
1. On your technician PC, open an administrative Command prompt.
|
||||
## Run the app
|
||||
|
||||
2. Use Powershell to [install the app and its dependencies](https://docs.microsoft.com/powershell/module/appx/add-appxpackage?view=win10-ps).
|
||||
|
||||
```PowerShell
|
||||
Add-AppxPackage -path "FactoryOrchestrator\Microsoft.FactoryOrchestratorApp_8wekyb3d8bbwe.msixbundle" -DependencyPath "frameworks\Microsoft.NET.CoreFramework.x64.Debug.2.2.appx" -DependencyPath "frameworks\Microsoft.NET.CoreRuntime.x64.2.2.appx" -DependencyPath "frameworks\Microsoft.VCLibs.x64.14.00.appx"
|
||||
```
|
||||
|
||||
## Run Factory Orchestrator
|
||||
|
||||
### Default behavior
|
||||
|
||||
>[!Important]
|
||||
>Need instructions on how to configure a device to run FO automatically
|
||||
|
||||
### If the app isn't configured to run automatically
|
||||
|
||||
To run the Factory Orchestrator app:
|
||||
To run the Factory Orchestrator app, use the Start menu to launch "Factory Orchestrator". Alternately, use [Windows Device Portal](https://docs.microsoft.com/en-us/windows/uwp/debug-test-perf/device-portal) to run the app:
|
||||
|
||||
1. Connect to the device where the app is installed with Device Portal
|
||||
2. From Device Portal's Apps manager tab, choose `Factory Orchestrator (App)` from the Installed Apps list.
|
||||
3. Click Start
|
||||
|
||||
The Factory Orchestrator app will start on the DUT. The Factory Orchestrator service is always running.
|
||||
The Factory Orchestrator app will start on the PC. If the PC has the Factory Orchestrator service running, it will automatically connect to the service. If not, you will be prompted to enter the IPv4 address of the service you wish to connect to.
|
||||
|
||||
See [Run using the application](use-the-factory-orchestrator-app.md) for details on how to use the app.
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 41 KiB |
|
@ -9,13 +9,13 @@ Factory Orchestrator provides a simple and reliable way to run and manage factor
|
|||
|
||||
Factory Orchestrator consists of two components:
|
||||
|
||||
- A system service (Microsoft.FactoryOrchestrator.Service.exe): The service tracks task information, including run unique per-run results and logging; even persisting task state to allow the service to be resilient to data loss due to client failure.
|
||||
- A .NET Core system service (Microsoft.FactoryOrchestrator.Service.exe): The service tracks task information, including run unique per-run results and logging; even persisting task state to allow the service to be resilient to data loss due to client failure. It also provides a robust API surface for clients to monitor & interact with the service via C# .NET, C# UWP, or PowerShell code.
|
||||
|
||||
- A UWP app: Communicates with the service to run executable tasks and commands on a device under test (DUT). This app can communicate with the service running on the same device and/or over a network. The app is optional, the service does not depend on the app.
|
||||
- A UWP app: Communicates with the service to monitor & run executable tasks and commands on a device under test (DUT). This app can communicate with the service running on the same device and/or over a network. The app is optional, the service does not depend on the app.
|
||||
|
||||
Tasks are used to capture actions that the server can executre, and TaskLists are used to organize and manage these Tasks. Learn more about [Tasks and Tasklists](tasks-and-tasklists.md)
|
||||
Tasks are used to capture actions that the server can execute, and TaskLists are used to organize and manage these Tasks. Learn more about [Tasks and Tasklists](tasks-and-tasklists.md).
|
||||
|
||||
[Getting started with Factory Orchestrator](get-started-with-factory-orchestrator.md)
|
||||
See [Getting started with Factory Orchestrator](get-started-with-factory-orchestrator.md) for details on how to install and run the app and/or service.
|
||||
|
||||
## Factory Orchestrator logs
|
||||
|
||||
|
@ -27,4 +27,4 @@ The service log file contains details about the operation of the Factory Orchest
|
|||
|
||||
### Factory Orchestrator Task log files
|
||||
|
||||
The Task log files contain details about the execution of a specific of the Factory Orchestrator Task. There is one log file generated for each run of a Task (TaskRun). The files are saved to `%ProgramData%\FactoryOrchestrator\Logs\` on a device by default, but this location can be changed using the FactoryOrchestratorClient.SetLogFolder() API. Use the FactoryOrchestratorClient.GetLogFolder() API to programmatically retrieve the log folder.
|
||||
The Task log files contain details about the execution of a specific of the Factory Orchestrator Task. There is one log file generated for each run of a Task ([TaskRun](../CoreLibrary/CoreLibrary\Microsoft-FactoryOrchestrator-Core-TaskRun/)). The files are saved to `%ProgramData%\FactoryOrchestrator\Logs\` on a device by default, but this location can be changed using the [FactoryOrchestratorClient](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-FactoryOrchestratorClient%28System-Net-IPAddress_int%29/).[SetLogFolder](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-SetLogFolder%28string_bool%29/)() API. Use the [FactoryOrchestratorClient](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-FactoryOrchestratorClient%28System-Net-IPAddress_int%29/).[GetLogFolder](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-GetLogFolder%28%29/)() API to programmatically retrieve the log folder.
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
|
||||
# Factory Orchestrator Service Configuration
|
||||
## (Optional & for advanced users only) Enable network access
|
||||
By default, the Factory Orchestrator service only allows client connections from the same device the service is running on (i.e. localhost only). However, service can be configured to allow connections from clients anywhere on your local network.
|
||||
|
||||
<b>
|
||||
<p align="center">⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠</p>
|
||||
<p align="center"><i>WARNING: Please read and understand the following before enabling network access!</i></p>
|
||||
<p align="center">⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠</p>
|
||||
</b>
|
||||
|
||||
- ⚠ The service allows any client to connect to it without authentication. Any connected client has full access to the service's computer, including the ability to send or copy files, and/or run any command or program with administrator rights. ⚠
|
||||
- ⚠ If you "install" the service, the service will be configured to run from boot. Depending on the configuration the service may even be running before a user has logged on to the computer. ⚠
|
||||
- ⚠ Once network access is enabled, it will remain enabled until the changes to enable network access are [reverted](#disable-network-access). ⚠
|
||||
- ⚠ The service and client send information over the network in unencrypted JSON using TCP. It is therefore vulnerable to man-in-the-middle attacks. ⚠
|
||||
- ⚠ The service currently has minimal logging about what clients are connected to it and what commands each client has executed. ⚠
|
||||
|
||||
|
||||
If you understand these risks but still require the service to communicate with clients over the local network, set both of the following registry values on the service's computer using regedit.exe or reg.exe:
|
||||
|
||||
Key | Value | [Type](../CoreLibrary/Microsoft-FactoryOrchestrator-Core-TaskBase-Type/) | Data
|
||||
------ | ------ | --- | ---
|
||||
HKLM\SYSTEM\CurrentControlSet\Control\FactoryOrchestrator | EnableNetworkAccess | REG_DWORD | 0x1
|
||||
HKLM\SYSTEM\CurrentControlSet\Control\FactoryOrchestrator | DisableNetworkAccess | REG_DWORD | 0x0
|
||||
|
||||
Once the two registry values are set, restart the service if it is running.
|
||||
|
||||
To check if network access is currently enabled use one of the following:
|
||||
|
||||
- The Factory Orchestrator app's "About" page.
|
||||
- The console output from Microsoft.FactoryOrchestrator.Service.exe
|
||||
- The [service log file](../#factory-orchestrator-service-log-file)
|
||||
- The [IsNetworkAccessEnabled](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-IsNetworkAccessEnabled%28%29/) API.
|
||||
|
||||
## Disable network access
|
||||
If you have enabled network access using the above steps, you can delete the two registry values above to disable network access. Restart the service if it is running.
|
||||
|
||||
To check if network access is currently disabled use one of the following:
|
||||
|
||||
- The Factory Orchestrator app's "About" page.
|
||||
- The console output from Microsoft.FactoryOrchestrator.Service.exe
|
||||
- The [service log file](../index#factory-orchestrator-service-log-file)
|
||||
- The [IsNetworkAccessEnabled](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-IsNetworkAccessEnabled%28%29/) API.
|
|
@ -51,20 +51,20 @@ Factory Orchestrator TaskLists allow adding different types of tasks:
|
|||
|
||||
### Background tasks
|
||||
|
||||
A BackgroundTask is a type of Task which is not expected to return a pass/fail result. Instead, BackgroundTasks are started before any Tasks defined in the TaskList, and are not tracked by the Factory Orchestrator Service, though their output is logged to a file. BackgroundTasks are intended to be used for logging/monitoring tasks that need to be running before any Task in the TaskList executes.
|
||||
A [BackgroundTask](../CoreLibrary/Microsoft-FactoryOrchestrator-Core-TaskRun-BackgroundTask/) is a type of Task which is not expected to return a pass/fail result. Instead, [BackgroundTasks](../CoreLibrary/Microsoft-FactoryOrchestrator-Core-TaskList-BackgroundTasks/) are started before any Tasks defined in the TaskList, and are not tracked by the Factory Orchestrator Service, though their output is logged to a file. [BackgroundTasks](../CoreLibrary/Microsoft-FactoryOrchestrator-Core-TaskList-BackgroundTasks/) are intended to be used for logging/monitoring tasks that need to be running before any Task in the TaskList executes.
|
||||
|
||||
BackgroundTasks are defined the exactly the same as a normal Task with the following exceptions:
|
||||
|
||||
- BackgroundTasks can only be an Executable, PowerShell, or BatchFile Task
|
||||
- BackgroundTasks cannot have Timeout or MaxNumberOfRetries set
|
||||
- [BackgroundTasks](../CoreLibrary/Microsoft-FactoryOrchestrator-Core-TaskList-BackgroundTasks/) can only be an Executable, PowerShell, or BatchFile Task
|
||||
- [BackgroundTasks](../CoreLibrary/Microsoft-FactoryOrchestrator-Core-TaskList-BackgroundTasks/) cannot have Timeout or [MaxNumberOfRetries](../CoreLibrary/Microsoft-FactoryOrchestrator-Core-TaskBase-MaxNumberOfRetries/) set
|
||||
|
||||
When editing a task from the Factory Orchestrator app, you can choose the option of making the task a background task by choosing the "Add as background task?" option.
|
||||
|
||||
Once you've run a task, the Factory Orchestrator service creates a **TaskRun** that is the output and results of the task, as well as other details about the task such as runtime.
|
||||
Once you've run a task, the Factory Orchestrator service creates a **[TaskRun](../CoreLibrary/CoreLibrary\Microsoft-FactoryOrchestrator-Core-TaskRun/)** that is the output and results of the task, as well as other details about the task such as runtime.
|
||||
|
||||
# Author and manage Factory Orchestrator TaskLists
|
||||
|
||||
You can define a collection of tasks in a **TaskList**. Tasks in a TaskList are run in a defined order, and can be a mixture that includes any type of tasks that's supported by Factory Orchestrator. TaskList data persists through reboots. TaskList data is stored and maintained by the Factory Orchestrator service, and doesn't depend on the app being open or running.
|
||||
You can define a collection of tasks in a **[TaskList](../CoreLibrary/CoreLibrary\Microsoft-FactoryOrchestrator-Core-TaskList/)**. Tasks in a TaskList are run in a defined order, and can be a mixture that includes any type of tasks that's supported by Factory Orchestrator. TaskList data persists through reboots. TaskList data is stored and maintained by the Factory Orchestrator service, and doesn't depend on the app being open or running.
|
||||
|
||||
Factory Orchestrator uses XML files to define TaskLists and their associated Tasks. An XML file can contain one or more TaskLists, each with any number of Tasks.
|
||||
|
||||
|
@ -96,11 +96,11 @@ The 'Manage TaskLists' tab in the Factory Orchestrator app allows you to create,
|
|||
|
||||
- **Choose individual files to add to a TaskList**
|
||||
|
||||
Use `Create new TaskList` to create a new TaskList where you can individual tasks one-at-a-time to your TaskList. When you add tasks this way, you choose the type of task that you're adding and can configure arguments, timeout settings, etc as you add tasks.
|
||||
Use `Create new TaskList` to create a new [TaskList](../CoreLibrary/CoreLibrary\Microsoft-FactoryOrchestrator-Core-TaskList/) where you can individual tasks one-at-a-time to your TaskList. When you add tasks this way, you choose the type of task that you're adding and can configure arguments, timeout settings, etc as you add tasks.
|
||||
|
||||
![Create new TaskList button](./images/create-new-tasklist.png)
|
||||
|
||||
- **Import a previously generated TaskLists XML file**
|
||||
- **Import a previously generated FactoryOrchestratorXML file**
|
||||
|
||||
This enables you to generate and export a TaskList on one device, and import it into your device. Once loaded, imported TaskList XML files can be modified like any other Task List.
|
||||
|
||||
|
@ -197,7 +197,7 @@ When Factory Orchestrator is running these tasks, you'll see a warning in the Fa
|
|||
|
||||
When hand-authoring FactoryOrchestratorXML files, you'll need to follow the FactoryOrchestratorXML schema. At the end of this topic, we've also provided a [sample FactoryOrchestratorXML file](#sample-factory-orchestrator-xml-file):
|
||||
|
||||
```XML
|
||||
```XML
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xs:schema id="FactoryOrchestratorXML"
|
||||
elementFormDefault="qualified"
|
||||
|
@ -266,7 +266,7 @@ When hand-authoring FactoryOrchestratorXML files, you'll need to follow the Fact
|
|||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
```
|
||||
```
|
||||
|
||||
### TaskList attributes
|
||||
|
||||
|
@ -278,7 +278,7 @@ A TaskList element defines a Factory Orchestrator TaskList. The following define
|
|||
| Guid | String | N | The GUID used to identify the TaskList. If not set, it will be assigned by the Factory Orchestrator Service automatically when the FactoryOrchestratorXML is loaded. |
|
||||
| RunInParallel | Bool | Y | If "true", the Tasks in this TaskList are executed in parallel. If "false", the Tasks in this TaskList are executed in order, one at a time. |
|
||||
| AllowOtherTaskListsToRun | Bool | Y | If "false", while this TaskList is running all other TaskLists are blocked from executing. If "true", other TaskLists may execute while this TaskList is running. |
|
||||
| TerminateBackgroundTasksOnCompletion | Bool | N | If "true", any BackgroundTasks defined in this TaskList are forcibly terminated when the TaskList's Tasks complete. If "false", any BackgroundTasks defined in this TaskList continue executing. Defaults to "true". |
|
||||
| TerminateBackgroundTasksOnCompletion | Bool | N | If "true", any [BackgroundTasks](../CoreLibrary/Microsoft-FactoryOrchestrator-Core-TaskList-BackgroundTasks/) defined in this TaskList are forcibly terminated when the TaskList's Tasks complete. If "false", any [BackgroundTasks](../CoreLibrary/Microsoft-FactoryOrchestrator-Core-TaskList-BackgroundTasks/) defined in this TaskList continue executing. Defaults to "true". |
|
||||
|
||||
#### Sample TaskList element
|
||||
|
||||
|
@ -293,16 +293,16 @@ A Task element defines a Factory Orchestrator Task. Tasks are pass/fail executab
|
|||
<!--Delete this table-->
|
||||
| Attribute Name | Type | Required? | Details |
|
||||
|------------------------|--------------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| xsi:type | See details | Y | The type of the Task. Allowed values are: ExecutableTask, PowerShellTask, BatchFileTask, TAEFTest, UWPTask, and ExternalTask. |
|
||||
| xsi:type | See details | Y | The type of the Task. Allowed values are: [ExecutableTask](../CoreLibrary/Microsoft-FactoryOrchestrator-Core-ExecutableTask/), [PowerShellTask](../CoreLibrary/Microsoft-FactoryOrchestrator-Core-PowerShellTask/), BatchFileTask, TAEFTest, [UWPTask](../CoreLibrary/Microsoft-FactoryOrchestrator-Core-UWPTask/), and [ExternalTask](../CoreLibrary/Microsoft-FactoryOrchestrator-Core-ExternalTask/). |
|
||||
| Name | String | N | The "friendly name" of the Task. If not set, it will be assigned by the Factory Orchestrator Service automatically when the FactoryOrchestratorXML is loaded, based on the Task type and other attributes. |
|
||||
| Guid | String | N | The GUID used to identify the Task. If not set, it will be assigned by the Factory Orchestrator Service automatically when the FactoryOrchestratorXML is loaded. |
|
||||
| Path | String | Depends | See the [Path table below](#path-definitions) to see which Tasks require you to include a Path element. | |
|
||||
| Arguments | String | N | For Executable, PowerShell, BatchFile, and TAEF Tasks: this is the list of arguments to provide to the executable you specified in the "Path".<br><br> For UWP Tasks: this can be used to provide details about the Task to the client. It is NOT passed to the UWP app.<br><br>For External Tasks: this can be used to provide details about the Task to the client. |
|
||||
| Timeout | Int | N | In seconds, the amount of time to wait for the Task to be completed. Defaults to "-1" (infinite).<br><br> If "-1", the Task will never timeout.<br><br>If the timeout is reached, the Task status is set to "Timeout", a failed state. The Task's executable is also forcibly terminated (if it has one). |
|
||||
| MaxNumberOfRetries | Int | N | The number of times the Task should automatically be re-run if it completes in a failed state (Aborted/Failed/Timeout). Defaults to "0" (do not retry).<br><br>For example, if this is set to "2", the Task could be run up to 3 times automatically. |
|
||||
| AbortTaskListOnFailed | Bool | N | If "true", if the Task is run during a TaskList and the Task fails (Aborted/Failed/Timeout), the TaskList is aborted in its current state. Any other pending or running Tasks will be aborted.<br><br>This action takes place after any re-runs specified by MaxNumberOfRetries.<br><br>While allowed, it is not recommended to use this for "RunInParallel" TaskLists, as the execution order of such a TaskList is not guaranteed, and Tasks may be aborted mid-execution. |
|
||||
| TerminateOnCompleted | Bool | N | By default, an app is terminated when the UWPTask completes. Set to false to not terminate after a UWPTask completes. TerminateOnCompleted is ignored if AutoPassedIfLaunched=`true` |
|
||||
| AutoPassedIfLaunched | Bool | N | By default, a UWPTask waits for its TaskRun to be completed by a Factory Orchestrator Client. Setting this to true marks the UWP task completed when the app is launched. |
|
||||
| AbortTaskListOnFailed | Bool | N | If "true", if the Task is run during a TaskList and the Task fails (Aborted/Failed/Timeout), the TaskList is aborted in its current state. Any other pending or running Tasks will be aborted.<br><br>This action takes place after any re-runs specified by [MaxNumberOfRetries](../CoreLibrary/Microsoft-FactoryOrchestrator-Core-TaskBase-MaxNumberOfRetries/).<br><br>While allowed, it is not recommended to use this for "RunInParallel" TaskLists, as the execution order of such a TaskList is not guaranteed, and Tasks may be aborted mid-execution. |
|
||||
| TerminateOnCompleted | Bool | N | By default, an app is terminated when the [UWPTask](../CoreLibrary/Microsoft-FactoryOrchestrator-Core-UWPTask/) completes. Set to false to not terminate after a [UWPTask](../CoreLibrary/Microsoft-FactoryOrchestrator-Core-UWPTask/) completes. TerminateOnCompleted is ignored if AutoPassedIfLaunched=`true` |
|
||||
| AutoPassedIfLaunched | Bool | N | By default, a [UWPTask](../CoreLibrary/Microsoft-FactoryOrchestrator-Core-UWPTask/) waits for its [TaskRun](../CoreLibrary/CoreLibrary\Microsoft-FactoryOrchestrator-Core-TaskRun/) to be completed by a Factory Orchestrator Client. Setting this to true marks the UWP task completed when the app is launched. |
|
||||
|
||||
#### Path definitions
|
||||
|
||||
|
@ -323,12 +323,12 @@ A Task element defines a Factory Orchestrator Task. Tasks are pass/fail executab
|
|||
|
||||
#### Validate Factory Orchestrator XML
|
||||
|
||||
You can validate FactoryOrchestratorXML using the Factory Orchestrator app on a technician PC.
|
||||
You can validate FactoryOrchestratorXML using the Factory Orchestrator app on a Windows PC, even without having to connect to a Factory Orchestrator service.
|
||||
|
||||
1. Install the Factory Orchestrator app on a technician PC and launch it.
|
||||
2. Click "Validate FactoryOrchestratorXML" in the bottom left of the app.
|
||||
1. [Install the Factory Orchestrator app](../get-started-with-factory-orchestrator/#install-the-app) on a Windows PC and launch it.
|
||||
2. Click "Validate FactoryOrchestratorXML" in the bottom left of the app's connect page.
|
||||
3. Browse to the path of your FactoryOrchestratorXML file and click open.
|
||||
4. The FactoryOrchestratorXML file will be validated against the schema. Because this validation happens on the technician PC, it will only catch XML syntax errors not Factory Orchestrator Service errors such as duplicate GUIDs or invalid file paths.
|
||||
4. The FactoryOrchestratorXML file will be validated against the schema. Because this validation happens on the Windows PC, it will only catch XML syntax errors. It will not catch runtime errors such as duplicate GUIDs or invalid file paths.
|
||||
|
||||
- If the FactoryOrchestratorXML is valid you will see a success message saying that "FactoryOrchestratorXML was successfully validated."
|
||||
|
||||
|
@ -345,9 +345,9 @@ The `TerminateBackgroundTasksOnCompletion` attribute on the owning TaskList dete
|
|||
Background Tasks are defined the exactly the same as a normal Task with the following exceptions:
|
||||
|
||||
- Any Executable, PowerShell, or Batch File Task can be made a Background Task.
|
||||
- Background Tasks cannot have Timeout or MaxNumberOfRetries set
|
||||
- Background Tasks cannot have Timeout or [MaxNumberOfRetries](../CoreLibrary/Microsoft-FactoryOrchestrator-Core-TaskBase-MaxNumberOfRetries/) set
|
||||
|
||||
#### Sample BackgroundTasks element
|
||||
#### Sample [BackgroundTasks](../CoreLibrary/Microsoft-FactoryOrchestrator-Core-TaskList-BackgroundTasks/) element
|
||||
|
||||
```xml
|
||||
<BackgroundTasks>
|
||||
|
@ -357,7 +357,7 @@ Background Tasks are defined the exactly the same as a normal Task with the foll
|
|||
|
||||
## Sample Factory Orchestrator XML file
|
||||
|
||||
The following sample FactoryOrchestratorXML file shows two TaskLists containing various types of tests, as well as a BackgroundTask that is part of the first TaskList.
|
||||
The following sample FactoryOrchestratorXML file shows two TaskLists containing various types of tests, as well as a [BackgroundTask](../CoreLibrary/Microsoft-FactoryOrchestrator-Core-TaskRun-BackgroundTask/) that is part of the first TaskList.
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
|
|
@ -1,34 +1,40 @@
|
|||
# Using the Factory Orchestrator client API
|
||||
# Factory Orchestrator Client API Overview
|
||||
The Factory Orchestrator service, Microsoft.FactoryOrchestrator.Service.exe, provides a [robust API surface](../ClientLibrary/Microsoft-FactoryOrchestrator-Client) for clients to interact with test devices via C# .NET, C# UWP, or PowerShell code. You can use these APIs to author advanced task orchestration code to programmatically interact with the service outside of what the app provides. Like the app, you can connect to a service running either on the same device or a service running on a remote device available over the network.
|
||||
|
||||
All FactoryOrchestratorClient and FactoryOrchestratorUWPClient C# (.NET and UWP) API calls are [asynchronous](https://docs.microsoft.com/dotnet/csharp/async).
|
||||
All [FactoryOrchestratorClient](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-FactoryOrchestratorClient%28System-Net-IPAddress_int%29/) and FactoryOrchestratorUWPClient C# (.NET and UWP) API calls are [asynchronous](https://docs.microsoft.com/dotnet/csharp/async).
|
||||
|
||||
You can see [the full API reference for the Microsoft.FactoryOrchestrator.Client here](../ClientLibrary/Microsoft-FactoryOrchestrator-Client). You can also see [the Microsoft.FactoryOrchestrator.Core reference here](../CoreLibrary/Microsoft-FactoryOrchestrator-Core). The CoreLibrary contains class definitions for objects some client APIs return, such as TaskRun instances.
|
||||
You can see [the full API reference for the Microsoft.FactoryOrchestrator.Client here](../ClientLibrary/Microsoft-FactoryOrchestrator-Client). You can also see [the Microsoft.FactoryOrchestrator.Core reference here](../CoreLibrary/Microsoft-FactoryOrchestrator-Core). The CoreLibrary contains class definitions for objects some client APIs return, such as [TaskRun](../CoreLibrary/CoreLibrary\Microsoft-FactoryOrchestrator-Core-TaskRun/) instances.
|
||||
|
||||
Before executing other APIs, the Connect() or TryConnect() API must be called. Once the Connect() or TryConnect() API succeeds, you can use all other APIs.
|
||||
**See [Factory Orchestrator API usage samples](../factory-orchestrator-client-usage-samples) for code snippets that show how to perform various activities using the Factory Orchestrator client APIs.**
|
||||
|
||||
## Using the Factory Orchestrator client API in C# .NET
|
||||
The recommended method to use the Factory Orchestrator C# client library in your .NET code is by adding a reference to the [Microsoft.FactoryOrchestrator.Client NuGet package](https://www.nuget.org/packages/Microsoft.FactoryOrchestrator.Client/) in your .NET project.
|
||||
|
||||
Before executing other APIs, the[Connect](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-Connect%28bool%29/)() or [TryConnect](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-TryConnect%28bool%29/)() API must be called. Once the[Connect](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-Connect%28bool%29/)() or [TryConnect](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-TryConnect%28bool%29/)() API succeeds, you can use all other APIs. All calls are asynchronous.
|
||||
|
||||
```csharp
|
||||
// Create client instance targeting service at desired IP Address
|
||||
var client = new FactoryOrchestratorClient(new IPAddress("192.168.0.50"));
|
||||
|
||||
// Establish connection
|
||||
await Client.Connect();
|
||||
// Establish connection.
|
||||
await client.Connect();
|
||||
|
||||
// Do things!
|
||||
await Client.RunExecutable(@"%windir%\system32\ping.exe");
|
||||
await client.RunExecutable(@"%windir%\system32\ping.exe");
|
||||
```
|
||||
|
||||
## Using FactoryOrchestratorClient in PowerShell
|
||||
The FactoryOrchestratorClient PowerShell module is available in Microsoft.FactoryOrchestrator.Client.psd1.
|
||||
## Using [FactoryOrchestratorClient](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-FactoryOrchestratorClient%28System-Net-IPAddress_int%29/) in PowerShell
|
||||
The [FactoryOrchestratorClient](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-FactoryOrchestratorClient%28System-Net-IPAddress_int%29/) PowerShell module is available on [PowerShell Gallery as Microsoft.FactoryOrchestrator.Client](https://www.powershellgallery.com/packages/Microsoft.FactoryOrchestrator.Client/). Currently, the module is only supported on PowerShell 6+.
|
||||
|
||||
To use the PowerShell module, import Microsoft.FactoryOrchestrator.Client.psd1 and then use the New-FactoryOrchestratorClient cmdlet to create a FactoryOrchestratorClient instance. The PowerShell FactoryOrchestratorClient instance exposes the exact same APIs as the C# FactoryOrchestratorClient class. However, unlike FactoryOrchestratorClient and FactoryOrchestratorUWPClient C# classes, all calls are synchronous.
|
||||
To use the PowerShell module, install Microsoft.FactoryOrchestrator.Client and then use the New-FactoryOrchestratorClient cmdlet to create a [FactoryOrchestratorClient](.\ClientLibrary\Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient.md) instance. The PowerShell [FactoryOrchestratorClient](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-FactoryOrchestratorClient%28System-Net-IPAddress_int%29/) instance returned by New-FactoryOrchestratorClient has the exact same methods as the C# [FactoryOrchestratorClient](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-FactoryOrchestratorClient%28System-Net-IPAddress_int%29/) class. **However, unlike [FactoryOrchestratorClient](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-FactoryOrchestratorClient%28System-Net-IPAddress_int%29/) and FactoryOrchestratorUWPClient C# classes, all calls are synchronous.**
|
||||
|
||||
Other supported cmdlets are: New-FactoryOrchestratorTask, New-FactoryOrchestratorTaskList, and New-FactoryOrchestratorServerPoller. They return new TaskBase, TaskList, and ServerPoller objects respectively.
|
||||
Other supported cmdlets are: New-FactoryOrchestratorTask, New-FactoryOrchestratorTaskList, and New-FactoryOrchestratorServerPoller. They return new [Task](../CoreLibrary/Microsoft-FactoryOrchestrator-Core-TaskBase), [TaskList](../CoreLibrary/Microsoft-FactoryOrchestrator-Core-TaskList), and [ServerPoller](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-ServerPoller) objects respectively.
|
||||
|
||||
Below is a sample PowerShell script showing how you can use these cmdlets:
|
||||
```powershell
|
||||
# Import client module
|
||||
Import-Module Microsoft.FactoryOrchestrator.Client.psd1
|
||||
|
||||
# Install client module
|
||||
Install-Module -Name Microsoft.FactoryOrchestrator.Client
|
||||
|
||||
# Create client instance targeting service at desired IP Address (127.0.0.1 == loopback)
|
||||
$client = New-FactoryOrchestratorClient -IpAddress "127.0.0.1"
|
||||
|
@ -36,73 +42,17 @@ $client = New-FactoryOrchestratorClient -IpAddress "127.0.0.1"
|
|||
# Establish connection. Unlike C# FactoryOrchestratorClient, this is synchronous
|
||||
$client.Connect();
|
||||
|
||||
# Do things! For example...
|
||||
# Create a TaskList. Create as global for event handling to work.
|
||||
$global:tasklist = New-FactoryOrchestratorTaskList "My TaskList"
|
||||
|
||||
# Create Tasks
|
||||
$task = New-FactoryOrchestratorTask -Type Executable -Path "C:\TestContent\PathToMyExe.exe"
|
||||
$task2 = New-FactoryOrchestratorTask -Type External -Name "External Task"
|
||||
|
||||
# Add the Tasks to the TaskList
|
||||
$global:tasklist.Tasks.Add($task);
|
||||
$global:tasklist.Tasks.Add($task2);
|
||||
|
||||
# Add the TaskList to the service
|
||||
$global:tasklist = $client.CreateTaskListFromTaskList($global:tasklist)
|
||||
|
||||
# Create and start a poller for the TaskList
|
||||
$poller = New-FactoryOrchestratorServerPoller -GuidToPoll $global:tasklist.Guid -GuidType TaskList
|
||||
# Register for OnUpdatedObject event
|
||||
$pollEvent = Register-ObjectEvent -InputObject $poller -EventName OnUpdatedObject -Action { $global:tasklist = $Event.SourceEventArgs.Result }
|
||||
# PowerShell only: you must pass the AsyncClient to the ServerPoller!
|
||||
$poller.StartPolling($client.AsyncClient)
|
||||
|
||||
# Run the TaskList
|
||||
$client.RunTaskList($global:tasklist.Guid)
|
||||
|
||||
# Wait for ExternalTask to be waiting on result
|
||||
$externalTaskrunGuid = $null
|
||||
while ($externalTaskrunGuid -eq $null)
|
||||
{
|
||||
$externalTaskrunGuid = ($global:tasklist.Tasks | Where-Object {$_.LatestTaskRunStatus -eq [Microsoft.FactoryOrchestrator.Core.TaskStatus]::WaitingForExternalResult}).LatestTaskRunGuid
|
||||
Start-Sleep -seconds 1
|
||||
}
|
||||
|
||||
# Get the TaskRun
|
||||
$externalRun = $client.QueryTaskRun($externalTaskrunGuid)
|
||||
|
||||
# Complete the ExternalTask TaskRun
|
||||
$externalRun.TaskOutput.Add("Completed via PowerShell!")
|
||||
$externalRun.TaskStatus = [Microsoft.FactoryOrchestrator.Core.TaskStatus]::Passed
|
||||
$externalRun.ExitCode = 0
|
||||
$client.UpdateTaskRun($externalRun)
|
||||
|
||||
# Wait for the TaskList to fully complete
|
||||
while ($global:tasklist.IsRunningOrPending -eq $true)
|
||||
{
|
||||
Start-Sleep -seconds 1
|
||||
}
|
||||
|
||||
# Stop polling
|
||||
$poller.StopPolling()
|
||||
Get-EventSubscriber | Unregister-Event
|
||||
|
||||
# Write out results
|
||||
foreach ($t in $global:tasklist.Tasks)
|
||||
{
|
||||
Write-Host "$($t.Name) finished in $($t.LatestTaskRunRunTime) with result $($t.LatestTaskRunStatus)"
|
||||
Write-Host "Output:"
|
||||
$output = ($client.QueryTaskRun($t.LatestTaskRunGuid)).TaskOutput
|
||||
Write-Host $output
|
||||
}
|
||||
# Do things!
|
||||
$client.RunExecutable("$env:windir\system32\ping.exe");
|
||||
```
|
||||
|
||||
## Using FactoryOrchestratorUWPClient in a UWP
|
||||
If you are writing a UWP app that uses the Factory Orchestrator Client API, you must use the FactoryOrchestratorUWPClient class instead of FactoryOrchestratorClient. The FactoryOrchestratorUWPClient APIs are identical to the FactoryOrchestratorClient APIs. The FactoryOrchestratorUWPClient class is available in FactoryOrchestratorUWPClientLibrary.dll. Like the FactoryOrchestratorClient C# class, all FactoryOrchestratorUWPClient API calls are [asynchronous](https://docs.microsoft.com/dotnet/csharp/async).
|
||||
The recommended method to use the Factory Orchestrator C# UWP client library in your .NET code is by adding a reference to the [Microsoft.FactoryOrchestrator.UWPClient NuGet package](https://www.nuget.org/packages/Microsoft.FactoryOrchestrator.UWPClient/) in your UWP project.
|
||||
|
||||
If you are writing a UWP app that uses the Factory Orchestrator Client API, you must use the FactoryOrchestratorUWPClient class instead of [FactoryOrchestratorClient](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-FactoryOrchestratorClient%28System-Net-IPAddress_int%29/). The FactoryOrchestratorUWPClient APIs are identical to the [FactoryOrchestratorClient](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-FactoryOrchestratorClient%28System-Net-IPAddress_int%29/) APIs. Like the [FactoryOrchestratorClient](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-FactoryOrchestratorClient%28System-Net-IPAddress_int%29/) C# class, all FactoryOrchestratorUWPClient API calls are [asynchronous](https://docs.microsoft.com/dotnet/csharp/async).
|
||||
|
||||
## Factory Orchestrator Versioning
|
||||
Factory Orchestator uses [semver](https://semver.org/) versioning. If there is a major version mismatch between the client and service your program may not work as expected and either the client program or target service should be updated so the major versions match. Major versions are checked when the client connects to the service. You can also manually check the version of the client API by:
|
||||
Factory Orchestator uses [semver](https://semver.org/) versioning. If there is a major version mismatch between the client and service your program may not work as expected and either the client program or target service should be updated so the major versions match. Major versions are checked when the client connects to the service via the[Connect](../ClientLibrary/Microsoft-FactoryOrchestrator-Client-FactoryOrchestratorClient-Connect%28bool%29/)() API. You can also manually check the version of the client API by:
|
||||
|
||||
- Manually inspecting the properties of the Microsoft.FactoryOrchestrator.Client.dll file used by your program
|
||||
|
||||
|
@ -116,19 +66,3 @@ FactoryOrchestratorClient.GetClientVersionString();
|
|||
```powershell
|
||||
Get-Module FactoryOrchestratorClient
|
||||
```
|
||||
|
||||
## Factory Orchestrator client sample
|
||||
|
||||
A sample .NET Core program that communicates with the Factory Orchestrator service is available in the Factory Orchestrator GitHub repo at: https://github.com/microsoft/FactoryOrchestrator/tree/main/src/ClientSample. Copy the entire directory to your technician PC, then open ClientSample.csproj in Visual Studio 2019 or build it with the dotnet CLI SDK.
|
||||
|
||||
The sample shows you how to connect to a remote (or local) device running Factory Orchestrator service, copy files to that device, execute test content, and retrieve the test results from the device both using an API and by retrieving the service's log files.
|
||||
|
||||
### Factory Orchestrator client sample usage
|
||||
|
||||
Once the sample is built, create a folder on your PC with test content and a FactoryOrchestratorXML file that references the test content in the location it will execute from on the test device. Then, run the sample by calling:
|
||||
|
||||
```cmd
|
||||
dotnet ClientSample.dll <IP Address of DUT> <Folder on technician PC with test content AND FactoryOrchestratorXML files> <Destination folder on DUT> <Destination folder on this PC to save logs>
|
||||
```
|
||||
|
||||
The sample will then connect to the test device, copy files to that device, execute test content, and retrieve the test results from the device both using an API and by retreiving the log files. You will be able to monitor the progress of the sample in the ClientSample console window, on the DUT (if it is running the Factory Orchestrator app), and on the Factory Orchestrator app on the PC (if it is connected to the test device).
|
|
@ -27,6 +27,53 @@ A 'Re-run' button will also appear next to a Task if the TaskList is done execut
|
|||
|
||||
![Results of an aborted running TaskList](./images/re-run-task.png)
|
||||
|
||||
If you click on a Task, the results page will load and show you the status of the latest "run" (TaskRun) of that Task, including the any output of the Task. The results page also allows you to see the log file path for that run. You can also use the buttons at the top of the page to view older or newer runs of the Task, provided it has been run multiple times.
|
||||
If you click on a Task, the results page will load and show you the status of the latest "run" ([TaskRun](../CoreLibrary/CoreLibrary\Microsoft-FactoryOrchestrator-Core-TaskRun/)) of that Task, including the any output of the Task. The results page also allows you to see the log file path for that run. You can also use the buttons at the top of the page to view older or newer runs of the Task, provided it has been run multiple times.
|
||||
|
||||
![Clicking on a Task that has run](./images/test-results.png)
|
||||
|
||||
# Factory Orchestrator utilities
|
||||
|
||||
The Factory Orchestrator app also includes some basic utilities intended as a starting point for integration into a manufacturing line, fault analysis workflow or developer inner loop.
|
||||
|
||||
<!-- ## UWP Apps
|
||||
|
||||
This launches a UWP app that's installed on a device under test (DUT). This allows you to launch a UWP directly from the Factory Orchestrator app by clicking on its name in the list of installed UWP apps.
|
||||
|
||||
Your device must be configured to launch into an environment that supports launching UWP apps.
|
||||
|
||||
You can exit a launched UWP with ALT+F4, or from Windows Device Portal. -->
|
||||
|
||||
## Command Prompt
|
||||
|
||||
A basic and non-interactive command prompt that allows you to troubleshoot without having to use other methods like SSH or Windows Device Portal to connect to your DUT.
|
||||
|
||||
While you can run commands and see output when using the built-in command prompt in Factory Orchestrator, it's not an interactive shell. If you run a command that requires additional input, you won't be able to enter the additional input.
|
||||
|
||||
![The Command Prompt screen](./images/fo-cmd.png)
|
||||
|
||||
## File Transfer
|
||||
![The Transfer Files screen](./images/fo-transfer-files.png)
|
||||
|
||||
A very basic file transfer function that enables you to transfer files & folders to and from your device when you're connected from a Windows PC. This feature is not visible in the Factory Orchestrator app when running the app and service on the same device (the "Transfer Files" tab will be hidden).
|
||||
|
||||
### One-time setup
|
||||
|
||||
First, [install the Factory Orchestrator app](get-started-with-factory-orchestrator.md#install-the-app) on a Windows system that is __not running the Factory Orchestrator service__.
|
||||
|
||||
Next, you need to give the Factory Orchestrator app full file system access for file transfer to work. Follow the directions on the [Windows 10 file system access and privacy](https://support.microsoft.com/en-us/help/4468237/windows-10-file-system-access-and-privacy-microsoft-privacy) page to give the Factory Orchestrator app access to your local file system. You may need to launch the app at least once before it appears on the Settings app.
|
||||
|
||||
### Send a file or folder to a DUT
|
||||
|
||||
- From your local Windows PC, launch the Factory Orchestrator app and connect to the IP address of the remote DUT.
|
||||
- Navigate to "Transfer Files". This tab is only visible if you are connected to a remote DUT.
|
||||
- In the "Local File/Folder" textbox, enter the full path to a file or folder on your local Windows PC.
|
||||
- In the "Remote File/Fikder" textbox, enter the full path of where you wish the file or folder to be saved on the DUT. Make sure the location you're saving to is writeable.
|
||||
- Click "Send Local File/Folder" to transfer the file or folder from the Windows PC to the DUT.
|
||||
|
||||
### Receive a file or folder from your DUT
|
||||
|
||||
- From your local Windows PC, launch the Factory Orchestrator app and connect to the IP address of the remote DUT.
|
||||
- Navigate to "Transfer Files". This tab is only visible if you are connected to a remote DUT.
|
||||
- In the "Remote File/Folder" textbox, enter the full path of to a file or folder you wish to copy from the DUT.
|
||||
- In the "Local File/Folder" textbox, enter the full path of where you wish the file or folder to be saved on your local Windows PC. Make sure the location you're saving to is writeable.
|
||||
- Click "Get Remote File/Folder" to transfer the file or folder from the DUT to your local Windows 10 PC.
|
||||
|
|
|
@ -18,9 +18,10 @@ nav:
|
|||
- Overview: 'index.md'
|
||||
- Get Started: 'get-started-with-factory-orchestrator.md'
|
||||
- Tasks & TaskLists : 'tasks-and-tasklists.md'
|
||||
- Service Configuration : 'service-configuration.md'
|
||||
- Run using the application: 'use-the-factory-orchestrator-app.md'
|
||||
- Run using the client api: 'use-the-factory-orchestrator-api.md'
|
||||
- Built-In Utilities: 'factory-orchestrator-utilities.md'
|
||||
- Run using the client API: 'use-the-factory-orchestrator-api.md'
|
||||
- Client API samples: 'factory-orchestrator-client-usage-samples.md'
|
||||
- Client Library Class Reference: 'ClientLibrary\Microsoft-FactoryOrchestrator-Client.md'
|
||||
- Core Library Class Reference: 'CoreLibrary\Microsoft-FactoryOrchestrator-Core.md'
|
||||
|
|
@ -370,7 +370,7 @@ namespace Microsoft.FactoryOrchestrator.Core
|
|||
void InstallApp(string appPackagePath, List<string> dependentPackages = null, string certificateFile = null);
|
||||
|
||||
/// <summary>
|
||||
/// Enables local loopback on the given UWP app.
|
||||
/// Enables local loopback on the given UWP app. Local loopback is enabled permanently for this app, persisting through reboots.
|
||||
/// </summary>
|
||||
/// <param name="aumid">The Application User Model ID (AUMID) of the app to enable local loopback on.</param>
|
||||
void EnableLocalLoopbackForApp(string aumid);
|
||||
|
|
Загрузка…
Ссылка в новой задаче