- Notas relacionadas
- Información general
- Primeros pasos
- Proveedores de Marketplace
- Clientes de Marketplace
- Pautas de publicación
- Directrices de publicación para automatizaciones listas para usar
- Directrices de publicación para aceleradores de soluciones
- Directrices de publicación para conectores de Integration Service
- Seguridad y protección de IP
- Otros listados de UiPath
- Node-RED
- Configuración
- Equipos
- Ámbito de Microsoft Teams
- Crear equipo
- Crear equipo a partir de un grupo
- Obtener equipo
- Obtener Teams
- Canales
- Crear canal
- Eliminar canal
- Obtener canal
- Obtener canales
- Actualizar canal
- Charlas
- Obtener chat
- Obtener chats
- Obtener miembros del chat
- Mensajes
- Obtener mensaje
- Obtener mensajes
- Obtener respuestas de mensajes
- Responder al mensaje
- Enviar mensaje
- Events
- Crear Evento
- Eliminar Evento
- Obtener evento
- Obtener eventos
- Usuarios
- Obtener presencia del usuario
- Cómo funciona
- Referencias técnicas
- Comience ya
- Acerca de
- Configuración
- Referencias técnicas
- Ámbito del reconocedor de formularios de Azure
- Actividades
- Analizar formulario
- Analizar formulario asíncrono
- Obtener analizar el resultado del formulario
- Analizar recibo
- Analizar recibo asíncrono
- Obtener analizar resultado de recibo
- Analizar diseño
- Analizar diseño asíncrono
- Obtener analizar el resultado del diseño
- Modelo de entrenamiento
- Obtener modelos
- Obtener claves de modelo
- Obtener información del modelo
- Eliminar modelo
- Conectores
- Cómo crear actividades
- Cree su integración
Implementación de licencias
Esta sección de documentación te guía a través del proceso de insertar la biblioteca del SDK de licencias en tu paquete de actividades.
Siga los siguientes pasos dependiendo de si su paquete se desarrolló con o sin el Creador de actividades de UiPath:
La responsabilidad de la implementación de licencias para .NET 6 o actividades personalizadas compatibles con Windows recae en el proveedor. Marketplace no proporciona una biblioteca de licencias compatible con .NET6. Proporciona una biblioteca de licencias compatible con Windows-Legacy.
-
En el método ExecuteAsync de cada una de tus actividades, agrega la comprobación de validación a menos que tengas un escenario de actividad de ámbito.
Si tiene un escenario de actividad de ámbito, puede agregar la comprobación de validación solo a esa actividad si todas sus actividades están sujetas a licencia.
protected override async Task<Action<AsyncCodeActivityContext>> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken) { // Inputs var firstNumber = FirstNumber.Get(context); var secondNumber = SecondNumber.Get(context); // License validation #if !DEBUG //if your package is MyCompany.MyPackageName.Activities.1.0.0.nupkg await Validator.ValidateAsync(context, "MyCompany.MyPackageName.Activities"); #endif /////////////////////////// // Add execution logic HERE /////////////////////////// // Outputs return (ctx) => { }; }
protected override async Task<Action<AsyncCodeActivityContext>> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken) { // Inputs var firstNumber = FirstNumber.Get(context); var secondNumber = SecondNumber.Get(context); // License validation #if !DEBUG //if your package is MyCompany.MyPackageName.Activities.1.0.0.nupkg await Validator.ValidateAsync(context, "MyCompany.MyPackageName.Activities"); #endif /////////////////////////// // Add execution logic HERE /////////////////////////// // Outputs return (ctx) => { }; }Nota:- El objeto de contexto solo se puede pasar una vez y usarse solo en el método al que se pasó. Por ejemplo, después de la llamada Validator.ValidateAsync , ya no se puede utilizar en el método ExecuteAsync .
- Teniendo en cuenta el requisito anterior, esto también significa que las variables de entrada deben leerse antes de pasar el contexto al método de licencia o biblioteca.
-
Haga referencia a la biblioteca Licensing.dll en su proyecto .Activities y agregue la declaración " usando ":
using UiPath.Marketplace.License.Validations;
- La configuración ha finalizado: cree su paquete y asegúrese de que la biblioteca Licensing.dll esté presente dentro del contenido del paquete (dentro de la carpeta lib ). Después, podrá enviarlo a Marketplace.
Si su actividad inicial se ve así:
using System;
using System.Activities;
using System.ComponentModel;
namespace ClassMathCustomActivity
{
public class SimpleFormula : CodeActivity
{
[Category("Input")]
[RequiredArgument]
public InArgument<double> FirstNumber { get; set; }
[Category("Input")]
public InArgument<double> SecondNumber { get; set; }
[Category("Output")]
public OutArgument<double> ResultNumber { get; set; }
protected override void Execute(CodeActivityContext context)
{
var firstNumber = FirstNumber.Get(context);
var secondNumber = SecondNumber.Get(context);
var result = System.Math.Pow(firstNumber + secondNumber, 2);
ResultNumber.Set(context, result);
}
}
}
using System;
using System.Activities;
using System.ComponentModel;
namespace ClassMathCustomActivity
{
public class SimpleFormula : CodeActivity
{
[Category("Input")]
[RequiredArgument]
public InArgument<double> FirstNumber { get; set; }
[Category("Input")]
public InArgument<double> SecondNumber { get; set; }
[Category("Output")]
public OutArgument<double> ResultNumber { get; set; }
protected override void Execute(CodeActivityContext context)
{
var firstNumber = FirstNumber.Get(context);
var secondNumber = SecondNumber.Get(context);
var result = System.Math.Pow(firstNumber + secondNumber, 2);
ResultNumber.Set(context, result);
}
}
}
El cambio más importante que debe realizar es en el método de ejecución, que debe ser un ExecuteAsync.
La solución propuesta es crear la clase AsyncTaskCodeActivity.cs que debería tener este aspecto:
using System;
using System.Activities;
using System.Runtime.ExceptionServices;
using System.Threading;
using System.Threading.Tasks;
namespace ClassMathCustomActivity
{
internal struct AsyncTaskCodeActivityImplementation : IDisposable
{
private CancellationTokenSource _cancellationTokenSource;
private bool _tokenDisposed;
public void Cancel()
{
if (!_tokenDisposed)
{
_cancellationTokenSource?.Cancel();
_cancellationTokenSource?.Dispose();
_tokenDisposed = true;
}
}
public IAsyncResult BeginExecute(AsyncCodeActivityContext context
, Func<AsyncCodeActivityContext, CancellationToken, Task<Action<AsyncCodeActivityContext>>> onExecute
, AsyncCallback callback, object state)
{
if (!_tokenDisposed)
{
_cancellationTokenSource?.Dispose();
}
_cancellationTokenSource = new CancellationTokenSource();
_tokenDisposed = false;
TaskCompletionSource<Action<AsyncCodeActivityContext>> taskCompletionSource = new TaskCompletionSource<Action<AsyncCodeActivityContext>>(state);
Task<Action<AsyncCodeActivityContext>> task = onExecute(context, _cancellationTokenSource.Token);
var cancellationTokenSource = _cancellationTokenSource;
task.ContinueWith(t =>
{
if (t.IsFaulted)
{
taskCompletionSource.TrySetException(t.Exception.InnerException);
}
else if (t.IsCanceled || cancellationTokenSource.IsCancellationRequested)
{
taskCompletionSource.TrySetCanceled();
}
else
{
taskCompletionSource.TrySetResult(t.Result);
}
callback?.Invoke(taskCompletionSource.Task);
});
return taskCompletionSource.Task;
}
public void EndExecute(AsyncCodeActivityContext context, IAsyncResult result)
{
Task<Action<AsyncCodeActivityContext>> task = (Task<Action<AsyncCodeActivityContext>>)result;
if (task.IsFaulted)
{
ExceptionDispatchInfo.Capture(task.Exception.InnerException).Throw();
}
if (task.IsCanceled)
{
context.MarkCanceled();
}
task.Result?.Invoke(context);
if (!_tokenDisposed)
{
_cancellationTokenSource?.Dispose();
_tokenDisposed = true;
}
}
private bool _disposed; // To detect redundant calls
public void Dispose()
{
if (!_disposed)
{
if (!_tokenDisposed)
{
if (_cancellationTokenSource != null)
_cancellationTokenSource.Dispose();
_tokenDisposed = true;
}
_disposed = true;
}
}
}
public abstract class AsyncTaskCodeActivity : AsyncCodeActivity, IDisposable
{
private AsyncTaskCodeActivityImplementation _impl = new AsyncTaskCodeActivityImplementation();
protected override void Cancel(AsyncCodeActivityContext context)
{
_impl.Cancel();
base.Cancel(context);
}
protected override IAsyncResult BeginExecute(AsyncCodeActivityContext context, AsyncCallback callback, object state)
{
return _impl.BeginExecute(context, ExecuteAsync, callback, state);
}
protected override void EndExecute(AsyncCodeActivityContext context, IAsyncResult result)
{
_impl.EndExecute(context, result);
}
protected abstract Task<Action<AsyncCodeActivityContext>> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken);
#region IDisposable Support
private bool _disposed = false; // To detect redundant calls
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
}
_impl.Dispose(); //structs are not garbage collected so they fit in the unmanaged bucket
_disposed = true;
}
}
public void Dispose()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
public abstract class AsyncTaskCodeActivity<T> : AsyncCodeActivity<T>, IDisposable
{
private AsyncTaskCodeActivityImplementation _impl = new AsyncTaskCodeActivityImplementation();
protected override void Cancel(AsyncCodeActivityContext context)
{
_impl.Cancel();
base.Cancel(context);
}
protected override IAsyncResult BeginExecute(AsyncCodeActivityContext context, AsyncCallback callback, object state)
{
return _impl.BeginExecute(context, ExecuteAsync, callback, state);
}
protected override T EndExecute(AsyncCodeActivityContext context, IAsyncResult result)
{
_impl.EndExecute(context, result);
return Result.Get(context);
}
protected abstract Task<Action<AsyncCodeActivityContext>> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken);
#region IDisposable Support
private bool _disposed = false; // To detect redundant calls
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
}
_impl.Dispose(); //structs are not garbage collected so they fit in the unmanaged bucket
_disposed = true;
}
}
public void Dispose()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
}
using System;
using System.Activities;
using System.Runtime.ExceptionServices;
using System.Threading;
using System.Threading.Tasks;
namespace ClassMathCustomActivity
{
internal struct AsyncTaskCodeActivityImplementation : IDisposable
{
private CancellationTokenSource _cancellationTokenSource;
private bool _tokenDisposed;
public void Cancel()
{
if (!_tokenDisposed)
{
_cancellationTokenSource?.Cancel();
_cancellationTokenSource?.Dispose();
_tokenDisposed = true;
}
}
public IAsyncResult BeginExecute(AsyncCodeActivityContext context
, Func<AsyncCodeActivityContext, CancellationToken, Task<Action<AsyncCodeActivityContext>>> onExecute
, AsyncCallback callback, object state)
{
if (!_tokenDisposed)
{
_cancellationTokenSource?.Dispose();
}
_cancellationTokenSource = new CancellationTokenSource();
_tokenDisposed = false;
TaskCompletionSource<Action<AsyncCodeActivityContext>> taskCompletionSource = new TaskCompletionSource<Action<AsyncCodeActivityContext>>(state);
Task<Action<AsyncCodeActivityContext>> task = onExecute(context, _cancellationTokenSource.Token);
var cancellationTokenSource = _cancellationTokenSource;
task.ContinueWith(t =>
{
if (t.IsFaulted)
{
taskCompletionSource.TrySetException(t.Exception.InnerException);
}
else if (t.IsCanceled || cancellationTokenSource.IsCancellationRequested)
{
taskCompletionSource.TrySetCanceled();
}
else
{
taskCompletionSource.TrySetResult(t.Result);
}
callback?.Invoke(taskCompletionSource.Task);
});
return taskCompletionSource.Task;
}
public void EndExecute(AsyncCodeActivityContext context, IAsyncResult result)
{
Task<Action<AsyncCodeActivityContext>> task = (Task<Action<AsyncCodeActivityContext>>)result;
if (task.IsFaulted)
{
ExceptionDispatchInfo.Capture(task.Exception.InnerException).Throw();
}
if (task.IsCanceled)
{
context.MarkCanceled();
}
task.Result?.Invoke(context);
if (!_tokenDisposed)
{
_cancellationTokenSource?.Dispose();
_tokenDisposed = true;
}
}
private bool _disposed; // To detect redundant calls
public void Dispose()
{
if (!_disposed)
{
if (!_tokenDisposed)
{
if (_cancellationTokenSource != null)
_cancellationTokenSource.Dispose();
_tokenDisposed = true;
}
_disposed = true;
}
}
}
public abstract class AsyncTaskCodeActivity : AsyncCodeActivity, IDisposable
{
private AsyncTaskCodeActivityImplementation _impl = new AsyncTaskCodeActivityImplementation();
protected override void Cancel(AsyncCodeActivityContext context)
{
_impl.Cancel();
base.Cancel(context);
}
protected override IAsyncResult BeginExecute(AsyncCodeActivityContext context, AsyncCallback callback, object state)
{
return _impl.BeginExecute(context, ExecuteAsync, callback, state);
}
protected override void EndExecute(AsyncCodeActivityContext context, IAsyncResult result)
{
_impl.EndExecute(context, result);
}
protected abstract Task<Action<AsyncCodeActivityContext>> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken);
#region IDisposable Support
private bool _disposed = false; // To detect redundant calls
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
}
_impl.Dispose(); //structs are not garbage collected so they fit in the unmanaged bucket
_disposed = true;
}
}
public void Dispose()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
public abstract class AsyncTaskCodeActivity<T> : AsyncCodeActivity<T>, IDisposable
{
private AsyncTaskCodeActivityImplementation _impl = new AsyncTaskCodeActivityImplementation();
protected override void Cancel(AsyncCodeActivityContext context)
{
_impl.Cancel();
base.Cancel(context);
}
protected override IAsyncResult BeginExecute(AsyncCodeActivityContext context, AsyncCallback callback, object state)
{
return _impl.BeginExecute(context, ExecuteAsync, callback, state);
}
protected override T EndExecute(AsyncCodeActivityContext context, IAsyncResult result)
{
_impl.EndExecute(context, result);
return Result.Get(context);
}
protected abstract Task<Action<AsyncCodeActivityContext>> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken);
#region IDisposable Support
private bool _disposed = false; // To detect redundant calls
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
}
_impl.Dispose(); //structs are not garbage collected so they fit in the unmanaged bucket
_disposed = true;
}
}
public void Dispose()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
}
La actividad modificada debería tener este aspecto:
using System;
using System.Threading.Tasks;
using UiPath.Marketplace.License.Validations;
using System.ComponentModel;
using System.Activities;
using System.Threading;
namespace ClassMathCustomActivity
{
public class SimpleFormula : AsyncTaskCodeActivity
{
[Category("Input")]
[RequiredArgument]
public InArgument<double> FirstNumber { get; set; }
[Category("Input")]
public InArgument<double> SecondNumber { get; set; }
[Category("Output")]
public OutArgument<double> ResultNumber { get; set; }
protected override async Task<Action<AsyncCodeActivityContext>> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken)
{
var firstNumber = FirstNumber.Get(context);
var secondNumber = SecondNumber.Get(context);
// check for license after reading input arguments
#if !DEBUG
//if your package is MyCompany.MyPackageName.Activities.1.0.0.nupkg
await Validator.ValidateAsync(context, "MyCompany.MyPackageName.Activities");
#endif
return (ctx) =>
{
var result = System.Math.Pow(firstNumber + secondNumber, 2);
ResultNumber.Set(ctx, result);
};
}
}
}
using System;
using System.Threading.Tasks;
using UiPath.Marketplace.License.Validations;
using System.ComponentModel;
using System.Activities;
using System.Threading;
namespace ClassMathCustomActivity
{
public class SimpleFormula : AsyncTaskCodeActivity
{
[Category("Input")]
[RequiredArgument]
public InArgument<double> FirstNumber { get; set; }
[Category("Input")]
public InArgument<double> SecondNumber { get; set; }
[Category("Output")]
public OutArgument<double> ResultNumber { get; set; }
protected override async Task<Action<AsyncCodeActivityContext>> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken)
{
var firstNumber = FirstNumber.Get(context);
var secondNumber = SecondNumber.Get(context);
// check for license after reading input arguments
#if !DEBUG
//if your package is MyCompany.MyPackageName.Activities.1.0.0.nupkg
await Validator.ValidateAsync(context, "MyCompany.MyPackageName.Activities");
#endif
return (ctx) =>
{
var result = System.Math.Pow(firstNumber + secondNumber, 2);
ResultNumber.Set(ctx, result);
};
}
}
}
Es importante que la línea 24 se ejecute justo después de leer todos los argumentos de entrada. En el ejemplo anterior, las líneas 20 y 21 se usan para leer los argumentos de entrada, y las líneas 26 a 30 se usan para configurar el argumento de salida.
Una última cosa: al crear su .nupkg , asegúrese de que la biblioteca Licensing.dll esté presente dentro del contenido del paquete (dentro de la carpeta lib ).
¿Qué sucede después de implementar estos cambios?
Después de implementar los cambios y crear el .nupkg, debe enviarlo a Marketplace para su publicación.
¿Puedo obtener el archivo de licencia para fines de prueba?
#if !DEBUG
)
¿Cómo obtendrán los clientes el archivo de licencia?
Después de que alguien realizó una compra, un archivo de licencia .lic se generará y estará disponible para ellos en Marketplace. Podrán descargar el archivo y luego seguir los pasos necesarios para usar las actividades.