Eseguire e debuggare un'​ applicazione ASP.NET Core in Visual Studio utilizzando WSL (windows subsystem for linux)
Tags: aspnet, windows, linux, visualstudio
Published: 2021-01-30 11:19:55

[Stefano Marchisio - sviluppatore freelance: angular | asp.net core mvc c#](https://www.stefanomarchisio.it/)

##Introduzione
Il “sottosistema Windows per Linux” (o wsl) consente agli sviluppatori di eseguire un ambiente Linux all’interno di Windows, questo ambiente include la maggior parte delle applicazioni e degli strumenti da riga di comando presenti in Linux, il tutto senza il sovraccarico di una macchina virtuale tradizionale o di una configurazione di doppio avvio.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/vc9ykc8j9w9mz446k7dw.png)

Ciò risulterà utile (non in produzione) nel momento in cui vogliamo effettuare il debug di un applicazione ASP.NET Core in ambiente Linux. Seppur con ASP.NET Core sia possibile creare applicazioni multipiattaforma (Windows, Linux, Mec), se un’applicazione è stata sviluppata in ambiente Windows quando viene pubblicata in ambiente Linux possono sorgere dei problemi (per esempio a causa di come sono scritti i percorsi dei file). In questo modo sarà possibile lanciare l’applicazione ed effettuare il debug all’interno di Visual Studio (nelle cartelle di progetto in Windows), utilizzando un runtime di una macchina Linux a tutti gli effetti, per riscontrare e correggere eventuali problemi.

Esistono 2 versioni di WSL (windows subsystem for linux), più precisamente WSL1 e WSL2. In WSL1 non è presente un kernel linux, l’applicazione viene eseguita tramite una traslazione tra la “distribuzione linux” ed il “kernel windows”. Con l’avvento di WSL2 Microsoft abbandona l'emulazione delle API e integra una copia dell'interno kernel Linux all’interno di Windows. Il kernel è stato prelevato dal sito ufficiale (kernel.org), ottimizzato allo scopo e ricompilato; viene poi eseguito all'interno di una macchina virtuale light invisibile all'utente.

*Windows subsystem for linux è presente di default in Windows 10 (anche se non attivato), in quest’articolo vedremo come attivarlo e come scaricare una distribuzione Linux dallo store di Windows 10. Una volta che avremo poi un sottosistema Linux funzionante, vedremo come fare il deploy di un applicazione ASP.NET Core e come fare l’ ”attach” del “debugger” per poterla debuggare.*

##Attivazione del Windows subsystem for linux 

Per prima cosa dobbiamo andare attraverso il pannello di controllo in istallazione programmi e cliccare su “Turn windows features on or off”. A questo punto verrà visualizzato un popup con le varie features che possono essere attivate, se non sono già state selezionate dobbiamo selezionare: “Virtual Machine Platform” e “Windows Subsystem for Linux”. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/no6d6ga3a5qmitxrlr2k.png)

Dopo aver riavviato il pc Windows avrà installato ciò che ci serve, o meglio avrà predisposto la macchina installando il Kernel Linux anche se non sarà ancora presente una distribuzione Linux reale. Per installare una distribuzione Linux reale dobbiamo invece andare sul Windows Store e scegliere la distribuzione che desideriamo installare tra quelle disponibili.

##Installazione di una distribuzione Linux

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/tf0y7guiz88ttq9ivdl9.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/49eeug23ino3q0qds8u6.png)

Dopo che Windows ha finito di scaricare la distribuzione selezionata dobbiamo lanciarla come si farebbe con qualsiasi altra applicazione. La prima volta si aprirà una finestra console e verrà chiesto di attendere uno o due minuti affinché i file vengano decompressi e archiviati sul pc (i lanci futuri dovrebbero richiedere meno di un secondo), verrà inoltre chiesto di inserire uno “username” ed una “password”.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/e4uklp9aczomd8i2n14z.png)

A questo punto la distribuzione Linux da noi scelta è stata installata sul pc. Infatti se apriamo il menu start di Windows la vedremo insieme agli altri programmi, analogamente se clicchiamo si aprirà una finestra console con un terminale Linux. Importante, potrebbe comparire la scritta “Access is denied”, per ovviare a questo problema dobbiamo lanciare la console come amministratore.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/g1xe5xk7z1a4bi1y1frm.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/o7f5kj1dc1i2w072j26u.png)

Come si può vedere dall’immagine sovrastante una volta entrati nel sottosistema Linux ci troviamo nella directory di lavoro assegnata al nostro utente, sarà quindi possibile eseguire qualsiasi comando Linux.

##Conosciamo il commando WSL.EXE

Nel momento in cui è stato attivato/installato “windows subsystem for linux” è stato aggiunto al prompt dei comandi un nuovo comando: wsl.exe. Questo comando ci permette di gestire le varie distribuzioni Linux presenti sulla nostra macchina ed in particolar modo di: 1) visualizzare le distribuzioni linux installate (può essere presente anche più di una distribuzione). 2) Lanciare una distribuzione. 3) Impostare wsl1 o wsl2 come formato predefinito quando si installa una nuova distribuzione 4) Convertire una distribuzione da un formato all’altro: wsl1 => wsl2 o wsl2 => wsl1 5) Molto altro ancora 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/udk15bbkjgqhtmcihbxq.png)

Come si può vedere dall’immagine sovrastante sul sistema era già presente la distribuzione 20.04 di Ubuntu, nell’esempio abbiamo voluto installare anche la distribuzione 18.04 di Ubuntu. Come si può vedere la distribuzione appena installata utilizza il formato wsl1, pertanto dobbiamo convertirla al formato wsl2. Questo può essere fatto attraverso il comando “wsl –set-default Ubuntu-18.04 2”.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/u44eau1xwu9h31ldj900.png)

Adesso entrambe le distribuzioni utilizzano il formato wsl2. E’ possibile lanciare una distribuzione oltre che dal menu start di Windows anche attraverso il comando wsl, infatti i se digitiamo il comando “wsl -d Ubuntu-18.04” verrà aperta un finestra di terminale con la distribuzione desiderata. Per verificare che la versione sia quella corretta possiamo digitare il comando “lsb_release -a”. Maggiari informazioni sul comando wsl le potete trovare nella guida in linea di wsl.

##Interoperabilità tra il file system di Windows e quello di Linux

Giunti a questo punto ci ritroviamo più sistemi operativi affiancati, in particolar modo abbiamo Windows che funge da host e una o più distribuzioni Linux che girano su macchine virtuali light. Per rendere più agevole il lavoro dello sviluppatore, da ognuno dei sistemi operativi è possibile accedere agevolmente al file system degli altri sistemi operativi.

1) Dall’interno di Windows è possibile accedere al file system delle varie distribuzioni Linux attraverso la risorsa di rete \\wsl$.

2) Analogamente ogni distribuzione Linux monta il file system della macchina Windows sul seguente percorso “/mnt/<drive-letter>”.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/cb1jyp26x75dvp1dzwd8.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/vmbfam1d868vb2ounexo.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/l2lj0rq88wmhjqnxhbta.png)

*In questo modo, in seguito sarà facilmente possibile posizionarsi nella directory di lavoro di un progetto Visual Studio (in Windows) dall’interno di un ambiente Linux, per poter poi lanciare la soluzione o avviare il debug in ambiente Linux.*

Come mostra l’immagine sovrastante, dall’interno di un ambiante Linux ci siamo posizionati in un progetto Visual Studio (in Windows) contenuto nel drive “Z”.

Dall’interno di un ambiente Linux è anche possibile digitando il comando “explorer.exe .” aprire esplora risorse in Windows, mostrando il contenuto di una directory dell’ambiente Linux. Infatti l’interprete dei comandi Linux, prova a lanciare in Windows ogni file che ha come suffisso “.exe”

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/60qi1ml7hchc5sxfebu3.png)

**Perché usare Sottosistema Windows per Linux anziché Linux in una macchina virtuale?**

*Sottosistema Windows per Linux richiede un minor numero di risorse (CPU, memoria e file system) rispetto a una macchina virtuale completa. Consente di eseguire applicazioni e strumenti da riga di comando di Linux insieme alle applicazioni desktop Windows e di accedere ai rispettivi file system.*

NOTA IMPORTANTE: una delle principali limitazioni di Sottosistema Windows per Linux è la mancanza di supporto per la modifica diretta di file nel file system delle distribuzioni Linux tramite applicazioni o strumenti di Windows. Vedi: [Do not change Linux files using Windows apps and tools](https://devblogs.microsoft.com/commandline/do-not-change-linux-files-using-windows-apps-and-tools/) (non modificare i file linux usando app e strumenti di windows).

##Spostiamo la distribuzione appena installata in un'altra cartella

Di default le varie distribuzioni linux installate vengono messe all’interno di “C:”, questo può essere un problema se abbiamo un SSD con poco spazio, per questo motivo dobbiamo trovare un modo per poterle spostare in altra unita. 

Questo può essere fatto tramite utility “LxRunOffline” che viene lanciata all’interno della power shell di Windows. Per installare “LxRunOffline” dobbiamo aver prima installato il package manager “Chocolate”.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/foac7q0ai4dyc1yd29ol.png)

Come si può vedere dall’immagine sovrastante la distribuzione verrà spostata nella cartella: “Z:\zzz-linux\Ubuntu-18.04”.

##Installiamo l’SDK o il RUNTIME di ASP.NET Core nella distribuzione Linux

Prima di continuare di continuare dobbiamo però installare l’SDK o il RUNTIME di ASP.NET Core nella distribuzione Linux. Per far ciò si utilizzano i package manager presenti in Linux.

L'installazione con APT può essere fatta con pochi comandi, però prima di installare dotnet si devono eseguire i seguenti comandi per aggiungere la chiave di firma del pacchetto Microsoft all'elenco di chiavi attendibili e aggiungere il repository del pacchetto. Aprire quindi un terminale Linux e digitare.

*wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb*

*sudo dpkg -i packages-microsoft-prod.deb*

A questo punto è possibile installare dotnet scegliendo se installare anche SDK o solo il RUNTIME, nel caso si decide di installare l’SDK non è più necessario installare il RUNTIME.

sudo apt-get update; \ 

sudo apt-get install -y apt-transport-https && \ 

sudo apt-get update && \ 

sudo apt-get install -y dotnet-sdk-5.0 

oppure

sudo apt-get update; \ 

sudo apt-get install -y apt-transport-https && \ 

sudo apt-get update && \ 

sudo apt-get install -y aspnetcore-runtime-5.0

Maggiori informazioni è possibile trovarle [qui](https://docs.microsoft.com/it-it/dotnet/core/install/linux-ubuntu) 

Una volta che abbiamo installato SDK o il RUNTIME possiamo provare ad eseguire la nostra applicazione all’interno dell’ambiente Linux, ma per far ciò dobbiamo prima fare il deploy all’interno di un folder di prova. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/za9oe6q6lzrj1lhjo9yt.png)

La directory dove è stata pubblicata l’applicazione è la seguente.

*Z:\zzz-linux\Projects\WebApplication1\WebApplication1\bin\Debug\net5.0\publish*

Apriamo ora un terminale Linux e tramite il comando “cd” ed entriamo nella directory dove è stata pubblicata l’applicazione.

*cd /mnt/z/zzz-linux/Projects/WebApplication1/WebApplication1/bin/Debug/net5.0/publish*

A questo punto possiamo lanciare l’applicazione tramite il commando “dotnet”.

*dotnet WebApplication1.dll*

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/jmhbux8v92g6pkqbb9mw.png)

Come si può vedere dall’immagine sovrastante il server “Kestrel” è partito e ci segnala che l’applicazione è ora visibile ai seguenti indirizzi: “http://localhost:5000” e “https://localhost:5001” (da tener presente che la console è in ambiente Linux). Se ora apriamo il browser all’interno di Windows ed inseriamo uno dei 2 indirizzi, vedremo la nostra applicazione. 

##Abilitiamo il protocollo SSH ed installiamo il debugger remoto di dotnet

Fino ad ora ci siamo limitati a lanciare un applicazione in ambiente Linux da un browser in Windows. Ma prima di poter effettuare il debug dobbiamo fare ancora un paio di cose.

Essendo Visual Studio e l’ambiente Linux che esegue l’applicazione su 2 sistemi operativi diversi, siamo obbligati a lanciare una sessione di debug remoto. Per questo motivo dobbiamo abilitare protocollo SSH e poi installare il debugger remoto di dotnet all’interno di Linux. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/1u8c7mx1oa17dxshnps6.png)

I default è presente un server SSH all’interno della distribuzione Linux, ma a volte capita che nel momento in cui viene lanciato solleva un errore. Per questo motivo è bene disinstallarlo per poi installarlo nuovamente.

*sudo apt-get remove openssh-server*

*sudo apt-get install openssh-server*

Una volta reinstallato il server SSH dobbiamo andare a impostare i parametri di configurazione “PasswordAuthentication yes” e “AllowUsers <nomeutente>” contenuti nel file “/etc/ssh/sshd_config”. Infatti di default la password authentication è disabilitata e non sono presenti utenti nella lista degli utenti abilitati. Per editare il file “/etc/ssh/sshd_config” possiamo se non ancora presente installare “nano”, un semplice e funzionale editor di testo.

*sudo apt-get install nano*

*sudo nano /etc/ssh/sshd_config*

*PasswordAuthentication yes*

*AllowUsers <nomeutente>*

Una volta terminata la configurazione del servizio SSH riavviamo il server.

*sudo service ssh --full-restart*

Installiamo ora l’ unzip e il debug di dotnet.

*sudo apt-get install unzip*

*curl -sSL https://aka.ms/getvsdbgsh | bash /dev/stdin -v latest -l ~/vsdbg*

Tramite “curl” scarichiamo lo script “getvsdbgsh” che una volta lanciato provvederà a completare l’istallazione e la configurazione del debugger.

Se tutto à andato per il verso giusto, siamo ora in grado di lanciare da Visual Studio una sessione di debug di un applicazione che viene eseguita in ambiente Linux. Prima di lanciare la sessione di debug recuperiamo però l’indirizzo ip dell’ambiente Linux.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/o9fbduqzfci6klotg1q8.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/8ibzn7mbi4niyll8en0s.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/sre1352zjza5aaake5n0.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/iwyj8auw759jj0wmnbwt.png)

Nel momento in cui clicchiamo su “OK” partirà il debug di Visual Studio, se inseriamo un break-point sul metodo “Index” nel momento in cui effettuiamo il refresh della pagina il debug si arresterà al punto selezionato.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/lyjl9lgksjfqt2dro4up.png)

##Conclusioni

Giunti a questo punto abbiamo visto come è possibile lanciare una sessione di debug da Visual Studio di un applicazione eseguita in un ambiente Linux.

##Links

[Windows Subsystem for Linux Installation Guide for Windows 10](https://docs.microsoft.com/en-us/windows/wsl/install-win10)

[Install .NET on Linux](https://docs.microsoft.com/en-us/dotnet/core/install/linux)

[Install the .NET SDK or the .NET Runtime on Ubuntu](https://docs.microsoft.com/en-us/dotnet/core/install/linux-ubuntu)

[Debugging .NET Core on Unix over SSH](https://devblogs.microsoft.com/devops/debugging-net-core-on-unix-over-ssh/)

[Move/Install WSl distro from C drive to another drive](https://dev.to/kapilgorve/move-install-wsl-distro-from-c-drive-to-another-drive-19g9)

Se volete contattarmi il mio profilo Linkedin è il seguente:
[Stefano Marchisio - sviluppatore freelance: angular | asp.net core mvc c#](https://www.linkedin.com/in/stefano-marchisio-sviluppatore-web-angular-javascript-aspnet-fullstack/)