SapGuiBridge 0.1.1

dotnet add package SapGuiBridge --version 0.1.1
                    
NuGet\Install-Package SapGuiBridge -Version 0.1.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SapGuiBridge" Version="0.1.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SapGuiBridge" Version="0.1.1" />
                    
Directory.Packages.props
<PackageReference Include="SapGuiBridge" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SapGuiBridge --version 0.1.1
                    
#r "nuget: SapGuiBridge, 0.1.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SapGuiBridge@0.1.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SapGuiBridge&version=0.1.1
                    
Install as a Cake Addin
#tool nuget:?package=SapGuiBridge&version=0.1.1
                    
Install as a Cake Tool

SapGuiBridge

Executa scripts C# sobre uma sessão do SAP GUI já autenticada, via SAP GUI Scripting (COM), serializados numa fila FIFO em thread STA única.

Windows apenas, e o projeto que consome precisa alvejar net10.0-windows. Não é limitação nova — COM, afinidade STA e leitura do registro já exigiam Windows. Mas o NuGet só resolve lib/net10.0-windows7.0 para projetos com o mesmo sufixo: um backend em net10.0 puro não consegue referenciar este pacote, e a mensagem de restauro não deixa isso óbvio.

A biblioteca não autentica ninguém. O logon é feito pelo usuário no próprio SAP GUI; o que ela faz é adotar uma sessão já autenticada e garantir que continue sendo a mesma — se o sistema, o mandante ou o usuário mudarem no meio, ela aborta em vez de seguir rodando no lugar errado.

Instalação

dotnet add package SapGuiBridge

Uso

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSapGui(builder.Configuration.GetSection(SapGuiOptions.SectionName));

var app = builder.Build();

app.MapPost("/sap/estoque", async (ConsultaRequest pedido, ISapScriptRunner runner, CancellationToken ct) =>
{
    var args = ScriptArgs.From([new("material", pedido.Material)], "consultar-estoque");
    return Results.Ok(await runner.RunAsync<EstoqueDto>("consultar-estoque.cs", args, cancellationToken: ct));
});

app.Run();

public sealed record EstoqueDto(string Material, string Deposito, string Mensagem);

O script (scripts/consultar-estoque.cs) — note que não leva nenhum using, eles já vêm prontos:

public sealed record Resultado(string Material, string Deposito, string Mensagem);

public sealed class ConsultarEstoque(SapContext sap) : SapScript<Resultado>(sap)
{
    public override Resultado Execute(ScriptArgs args)
    {
        Transaction("MMBE");
        Set("wnd[0]/usr/ctxtRM03B-MATNR", args.Required("material"));
        SendVKey(8);
        ThrowIfStatusError();
        return new Resultado(args.Required("material"), "0001", StatusBar());
    }
}

EstoqueDto e Resultado nunca compartilham assembly — o script é um arquivo de texto compilado em tempo de execução. O resultado é serializado em JSON ainda dentro da fila, com o assembly do script vivo, e o acoplamento passa a ser por nome de campo. Confira o contrato com ISapScriptRunner.Describe.

Configuração

{
  "SapGui": {
    "System": "PRD",
    "StartMode": "Background",
    "LoginTimeout": "00:10:00",
    "MaxQueueDepth": 50,
    "ScriptDirectory": "scripts",
    "ScriptHotReload": false
  }
}

StartMode: "Background" é o recomendado. Aguardar uma sessão autenticada bloqueia por até LoginTimeout esperando uma pessoa digitar uma senha; fazer isso na subida do host significa que o Kestrel não abre o socket nesse tempo, o readiness probe falha e o orquestrador mata o processo antes de alguém conseguir logar.

O que esperar

  • Uma tela do SAP por vez. A fila é FIFO e serial, por definição: a tela do SAP GUI é estado global. Use MaxQueueDepth para contrapressão e GetQueueStatus() para observar.
  • Cancelamento é cooperativo. Um CancellationToken cancela item enfileirado e é honrado nos ThrowIfCancelled(), mas uma chamada COM em andamento não pode ser abortada.
  • Scripts devolvem resumos, não conjuntos de dados. A serialização roda na thread STA. Para volume, grave um arquivo e devolva o caminho.

Observabilidade

SapGuiDiagnostics.Collect() devolve o retrato do ambiente e da instalação do SAP GUI — versões de sapfront.dll, presença da pasta Scripting, política UserScripting no registro. É a primeira coisa a pedir quando funciona na sua máquina e não na do cliente.

Filtre o log por categoria (SapGuiBridge.Execution.SapExecutor, SapScript.<nome-do-script>) ou por evento, via SapEventIds.

Documentação completa

O guia de uso — docs/biblioteca.md no repositório — traz a referência de todos os objetos e suas propriedades, as duas formas de instanciar (com e sem container), como registrar e executar scripts, receitas para ASP.NET Core e Worker Service, e os limites que valem conhecer antes de ir para produção.

Product Compatible and additional computed target framework versions.
.NET net10.0-windows7.0 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.1 130 7/31/2026
0.1.0 112 7/30/2026

0.1.1 — só metadados; nenhuma mudança de comportamento em relação à 0.1.0.
     Acrescenta os links de projeto e repositório, que faltavam na primeira publicação, e o
     arquivo de licença. A 0.1.0 continua funcional e pode ser usada sem prejuízo.