Vai al contenuto

Struttura e Codice Base (C#)

Nel nuovo SDK Framework di SAP Business One, l'intero ciclo di vita dell'applicazione è gestito dalla classe SAPbouiCOM.Framework.Application.

Vediamo il codice completo e pulito per il punto d'ingresso (Program.cs).


1. Il File Principale: Program.cs

Sostituisci il contenuto del tuo file Program.cs con il seguente codice:

using System;
using System.Windows.Forms;
using SAPbouiCOM.Framework;

namespace MySAPAddon
{
    internal static class Program
    {
        /// <summary>
        /// Punto di ingresso principale per l'applicazione add-on.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            try
            {
                Application app = null;

                // Connessione intelligente:
                // - Se non ci sono argomenti (avvio in debug), cerca il client SAP B1 già aperto.
                // - Altrimenti, è SAP che passa la stringa di connessione negli argomenti.
                if (args.Length < 1)
                {
                    app = new Application();
                }
                else
                {
                    app = new Application(args[0]);
                }

                // Inizializzazione del menu dell'add-on
                AddOnMenu menu = new AddOnMenu();
                menu.AddMenuItems();

                // Registrazione degli eventi
                app.RegisterMenuEventHandler(menu.SBO_Application_MenuEvent);
                Application.SBO_Application.AppEvent += SBO_Application_AppEvent;

                // Mostra un messaggio di benvenuto sulla status bar di SAP B1
                Application.SBO_Application.StatusBar.SetText(
                    "Add-on avviato con successo!",
                    SAPbouiCOM.BoMessageTime.bmt_Short,
                    SAPbouiCOM.BoStatusBarMessageType.smt_Success
                );

                // Avvia il message loop del Framework
                app.Run();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Errore durante l'avvio dell'Add-on: " + ex.Message,
                                "Errore Add-on",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// Gestione degli eventi di sistema di SAP B1 (chiusura, cambio azienda, ecc.)
        /// </summary>
        private static void SBO_Application_AppEvent(SAPbouiCOM.BoAppEventTypes EventType)
        {
            switch (EventType)
            {
                case SAPbouiCOM.BoAppEventTypes.aet_ShutDown:
                case SAPbouiCOM.BoAppEventTypes.aet_CompanyChanged:
                case SAPbouiCOM.BoAppEventTypes.aet_LanguageChanged:
                case SAPbouiCOM.BoAppEventTypes.aet_ServerTerminition:
                    // Rilascia le risorse e termina pulitamente il processo
                    System.Windows.Forms.Application.Exit();
                    break;
            }
        }
    }
}

2. Anatomia del Codice

A. [STAThread] — Perché è Obbligatorio

L'attributo [STAThread] indica al runtime .NET di inizializzare il thread principale come Single Thread Apartment (STA).

Per capire perché è necessario, bisogna sapere come funziona COM (Component Object Model), la tecnologia su cui si basa tutta l'API di SAP Business One.

COM supporta due modelli di threading:

Modello Significato
STA (Single Thread Apartment) Un solo thread alla volta può accedere all'oggetto COM. Le chiamate da altri thread vengono automaticamente serializzate (messe in coda).
MTA (Multi Thread Apartment) Più thread possono accedere contemporaneamente allo stesso oggetto COM.

SAP Business One (come la maggior parte delle applicazioni con interfaccia grafica basate su COM) richiede STA, perché:

  1. Gli oggetti UI di SAP (form, menu, item) non sono thread-safe: possono essere manipolati solo dal thread che li ha creati.
  2. Senza [STAThread], il runtime .NET usa MTA di default. In MTA, le chiamate COM alle API di SAP possono arrivare da thread diversi, causando crash, blocchi o comportamenti imprevedibili.
  3. [STAThread] garantisce che tutte le chiamate COM vengano eseguite sequenzialmente sul thread principale, nello stesso ordine in cui le fai.

Cosa succede senza [STAThread]?

L'add-on potrebbe avviarsi ma crashare in modo casuale, soprattutto quando interagisci con form, menu o eventi. Il debug è difficilissimo perché gli errori sono non deterministici.

B. Connessione trasparente (new Application())

A differenza del vecchio modello (SboGuiApi.Connect(...)), il nuovo framework offre un costruttore senza parametri:

  • new Application(): si connette automaticamente all'istanza attiva di SAP Business One 64-bit presente sulla macchina di sviluppo. Non occorre copiare la stringa di connessione manualmente nei parametri di debug!
  • new Application(args[0]): gestisce la modalità di produzione quando l'add-on viene lanciato direttamente dal Gestore Add-on del client SAP Business One.

C. Application.SBO_Application

È la proprietà statica globale attraverso cui puoi accedere in qualsiasi punto del tuo codice a tutti i metodi della UI API standard (es. Forms, StatusBar, Menus, MessageBox).

D. Registrazione degli eventi

Per registrare un handler su un evento COM in C#, basta usare l'operatore += passando direttamente il metodo:

Application.SBO_Application.AppEvent += SBO_Application_AppEvent;

Non è necessario creare esplicitamente un'istanza del delegate — il compilatore C# lo fa automaticamente.

Evento AppEvent

L'evento AppEvent viene scatenato da SAP quando avvengono eventi di sistema come la chiusura del client, il cambio azienda o il cambio lingua. È fondamentale gestirlo per terminare pulitamente l'add-on.

E. app.Run()

Sostituisce il vecchio System.Windows.Forms.Application.Run(). Ascolta gli eventi COM di SAP in modo nativo e mantiene il processo in esecuzione finché non viene terminato.


3. Prossimi Passi