Se stai mantenendo un progetto WinForms (VB.NET) che comunica via seriale usando il vecchio controllo MSComm (AxMSCommLib.AxMSComm), potresti imbatterti in un problema fastidioso: l’app compila, il controllo si inizializza… ma quando provi ad aprire la porta seriale compare un’eccezione COM e la comunicazione non parte.

Nel mio caso l’errore avveniva quando la porta era COM17.


Il problema: l’app va in errore quando apro la porta

Il sintomo tipico è questo:

  • il form si apre normalmente
  • clicchi “Connetti” / “Apri porta”
  • e appare una finestra con un errore simile a:
System.Runtime.InteropServices.COMException (0x800A1F4C)
in MSCommLib.IMSComm.set_PortOpen(Boolean pfPortOpen)
...

In pratica l’errore scatta sulla riga dove fai:

com.PortOpen = True

Perché succede? (Spoiler: COM17 è il punto)

MSComm è un componente “storico” (deriva dal mondo VB6/ActiveX). Con porte seriali moderne (soprattutto adattatori USB-Serial), Windows può assegnare numeri di porta alti, tipo COM17, COM18, COM25…

Con MSComm, in molti scenari, porte oltre COM16 possono causare problemi: l’apertura fallisce e viene sollevata un’eccezione COM.

Quindi il progetto non è “rotto”: è il componente legacy che non digerisce il numero alto della COM.


Diagnosi rapida: verifica quale COM stai usando davvero

  1. Apri Gestione dispositivi
  2. Vai su Porte (COM e LPT)
  3. Individua il tuo dispositivo (es. “USB-SERIAL CH340”, “FTDI”, ecc.)
  4. Leggi il numero: ad esempio COM17

Se il tuo codice imposta:

com.CommPort = 17

hai trovato il problema.


La soluzione: cambia numero porta a una COM più bassa (COM1–COM16)

Passo-passo

  1. Gestione dispositivi → Porte (COM e LPT)
  2. Tasto destro sulla porta (es. “USB Serial Device (COM17)”) → Proprietà
  3. Scheda Impostazioni porta
  4. Clic su Avanzate…
  5. Cambia Numero porta COM scegliendo una porta libera, ad esempio COM6
  6. Conferma con OK e chiudi

A questo punto Windows userà un numero più basso e MSComm tornerà ad aprire la porta senza eccezioni.


Miglioria consigliata: blocca COM > 16 direttamente nel codice

Così eviti la finestra JIT e mostri un messaggio chiaro all’utente:

Private Sub BTcom_Click(sender As Object, e As EventArgs) Handles BTcom.Click
    Try
        ' Esempio: numero porta letto da UI (ComboBox, TextBox, ecc.)
        Dim n As Integer = Integer.Parse(txtCom.Text) ' oppure ricavato da "COM17"

        If n > 16 Then
            MessageBox.Show("MSComm non apre porte oltre COM16. " &
                            "Cambia il numero porta da Gestione dispositivi (Avanzate).",
                            "Porta non supportata", MessageBoxButtons.OK, MessageBoxIcon.Warning)
            Exit Sub
        End If

        If com.PortOpen Then com.PortOpen = False
        com.CommPort = CShort(n)
        com.Settings = "9600,N,8,1"

        com.PortOpen = True

    Catch ex As Exception
        MessageBox.Show("Errore apertura porta: " & ex.Message)
    End Try
End Sub

Nota importante: chiudi sempre la porta quando esci

Per evitare che resti “occupata” dopo crash o chiusura forzata:

Private Sub frmMain_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
    Try
        If com IsNot Nothing AndAlso com.PortOpen Then com.PortOpen = False
    Catch
    End Try
End Sub

Consiglio “definitivo”: valuta di sostituire MSComm

Se stai aggiornando il progetto e vuoi eliminare questi problemi una volta per tutte, considera System.IO.Ports.SerialPort (nativo .NET). Non richiede OCX, non richiede registrazioni e gestisce senza storie anche COM alte.


Conclusione

Se MSComm ti lancia un’eccezione all’apertura e la tua porta è COM17, la soluzione più rapida e concreta è:

riassegnare la porta a COM1–COM16 da Gestione dispositivi
✅ aggiungere un controllo in codice per prevenire l’errore e dare un messaggio chiaro

Da qui in poi l’app torna a comunicare normalmente.

Se vuoi, posso anche prepararti una versione “più SEO” per WordPress (excerpt, meta description, slug e tag) oppure una variante più breve da pubblicare come post tecnico.