使用 .NET 移除工具(Uninstall Tool)刪除系統上用不到的 .NET SDK 和 Runtime
使用 .NET Core 來開發各種應用時,久了都會在系統留下一些過時或用不到的 SDK,放著不理它雖然沒啥大礙,但老實說其實還蠻佔空間的,因此一直想找個機會把他們移除掉。最近剛好看到有人介紹了官方的移除工具,就藉此機會來清理一下硬碟吧^^。
**Step 1\.** 先到[這裡](https://github.com/dotnet/cli-lab/releases)下載安裝檔(Windows:msi 檔、MacOS:tar.gz 檔)
**Step 2\.** 將下載回來的檔案直接安裝或是解壓縮,此篇文章會以 MacOS 來當作範例
```bash
# 將檔案解壓縮至目標目錄
$ tar -zxf dotnet-core-uninstall.tar.gz -C ~/your_directory
# 切換至該目錄
$ cd ~/your_directory
# 查看一下指令手冊
$ ./dotnet-core-uninstall -h
```
**Step 3\.** 查看手冊後會發現提供的功能很單純,如下圖所示
![Image](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhR16Ugj2TrNaErxVDGJrtTt_ItEYXEPYgTenfPsDzA3YS4mPnWpJkv4p-ZEMAJn7fW1dTd-lBPXCs0LPRo4uofBBIRxF1jnuI7FkctH4kZmMTtbl3z7XFaZzSS5Es9ksPrQHCFatVKaw7n/s0/dotnet-uninstall-tool.png)
從說明裡可發現,透過 Visual Studio 安裝的 SDK 版本,是無法使用該工具進行移除的,只能從控制台裡的***新增/移除程式(Add or Remove Programs)***選單中移除它們
**Step 4\.** 先列出系統上可移除的 SDK 和 Runtime(不會包含 Visual Studio 安裝的 SDK 版本)
```bash
$ ./dotnet-core-uninstall list
```
執行後會出現類似下圖的列表資訊,**之後步驟的指令執行結果會以該列表為基準**
![Image](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0Tc2RGf3wL7h3WHL17d0B6AIvgbx-QgYYlVlwp5j42GB2muroK4Z8K7c1NT-rH1TymlTKNO7ERD1yJosB14ys1SqpchyphenhyphenUnPwsnuR97eB0uJfAwSmQf87Y8rZWongUMWcCsCzH5zeGdcva/s2152/dotnet-uninstall-tool-list.png)
**Step 5\.** 在實際執行移除命令前,可以先用`dry-run`或`whatif`來模擬移除的結果,用法如下
使用 `dry-run` 方式
```bash
# 移除特定版本
$ ./dotnet-core-uninstall dry-run --sdk 3.1.300
$ ./dotnet-core-uninstall dry-run --runtime 3.1.4
# 移除所有 SDK 或 Runtime,若不加上選項 --force,則版本有註記 Visual Studio for Mac 的 SDK 或 Runtime 不會被包含進來
$ ./dotnet-core-uninstall dry-run --sdk --all --force
$ ./dotnet-core-uninstall dry-run --runtime --all --force
# 移除 3.1.402 以下的所有 SDK 版本(不包含 3.1.402)
$ ./dotnet-core-uninstall dry-run --sdk --all-below 3.1.402 --force
# 移除所有 SDK,但不包含版本 2.2.402 及 3.1.402
$ ./dotnet-core-uninstall dry-run --sdk --all-but 2.2.402 3.1.402 --force
# 只保留最新版本 5.0.301,其它 SDK 皆會移除
$ ./dotnet-core-uninstall dry-run --sdk --all-but-latest --force
# 只留下每個主要版本的最新補丁版(patches),例如以下命令只會移除版本為 3.1.300 的 SDK
$ ./dotnet-core-uninstall dry-run --sdk --all-lower-patches --force
# 移除符合 3.1.* 的所有 SDK 版本,例如以下命令會移除版本為 3.1.300 、3.1.301、3.1.402 的 SDK
$ ./dotnet-core-uninstall dry-run --sdk --major-minor 3.1 --force
```
使用 `whatif` 方式
```bash
# 移除特定版本
$ ./dotnet-core-uninstall whatif --sdk --major-minor 3.1.300
$ ./dotnet-core-uninstall whatif --runtime --major-minor 3.1.4
# 移除所有 SDK 或 Runtime,若不加上選項 --force,則版本有註記 Visual Studio for Mac 的 SDK 或 Runtime 不會被包含進來
$ ./dotnet-core-uninstall whatif --sdk --all --force
$ ./dotnet-core-uninstall whatif --runtime --all --force
# 移除 3.1.8 以下的所有 Runtime 版本(不包含 3.1.8)
$ ./dotnet-core-uninstall whatif --runtime --all-below 3.1.8 --force
# 移除所有 Runtime,但不包含版本 5.0.7 及 2.2.7
$ ./dotnet-core-uninstall whatif --runtime --all-but 5.0.7 2.2.7 --force
# 只保留最新版本 5.0.7,其它 Runtime 皆會移除
$ ./dotnet-core-uninstall whatif --runtime --all-but-latest --force
# 只留下每個主要版本的最新補丁版(patches),例如以下命令會移除版本為 3.1.4、3.1.5、5.0.3 的 Runtime
$ ./dotnet-core-uninstall whatif --runtime --all-lower-patches --force
# 移除符合 3.1.* 的所有 Runtime 版本,例如以下命令會移除版本為 3.1.4 、3.1.5、3.1.8 的 Runtime
$ ./dotnet-core-uninstall whatif --runtime --major-minor 3.1 --force
```
輸入以上任一種指令都可先在畫面上看到移除結果,類似下圖這樣
![Image](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQRff8ao8c8zUHOP1Fj8-1rGBoAhSK5qpkV2bfN01bhjCcNAHMhI1GJDsqMVG6WiiLrm3I_z_IBLJlDtEDJztAsSJ5J8VSFbpBKSkqQGbi8jP4eegBfNIs2WL4nZBhOePm7Dirf_yifZAX/s0/dotnet-uninstall-tool-dryrun.png)
這邊我打算移除掉版本為 3.1.300 的 SDK 和版本為 3.1.4 的 Runtime,因為本身沒在使用 Visual Studio for Mac,所以出現相關的警告訊息我都先忽略掉
**Step 6\.** 將`dry-run`或`whatif`置換成**`remove`**,並加上 ***sudo*** (執行此命令需較高權限)
```bash
$ sudo ./dotnet-core-uninstall remove --sdk 3.1.300
```
執行過程如下
![Image](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEid77YJQvyjdEvrnNp7gA45NAOKyABrK7J954e-lYhqB5SMDckzm2yJ9r_xobJPVDWWO-ikOhlpkIRd9K8dbORM2lbAPNJkhSKib-55YK1BOP1q2AHoKhM3Zt685YSuk79w4COjIFplUQAe/s0/dotnet-uninstall-tool-remove-sdk.png)
若不想出現確認詢問畫面,可加上選項`-y`或`--yes`如下
```bash
$ sudo ./dotnet-core-uninstall remove --runtime 3.1.4 -y
```
執行後不會再出現確認詢問畫面並直接移除 Runtime,如下圖
![Image](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcZEGWNbdOLvbKgOpabU_FcQMnhgEBoIZSiHw_3HPahKKcGps3FIRUzVAr1kd7eTgeBzp1RktRj0WA58eo4vKPdGf_kxyeL_QOydV2-7NEVlALrnYyGplhe67HbW80AFLClCNymWBi-FTq/s0/dotnet-uninstall-tool-remove-runtime.png)
**Step 7\.** 驗收移除成果
這邊先使用該移除工具的`list`指令來列出系統上剩下的 SDK 和 Runtime 列表
```bash
$ ./dotnet-core-uninstall list
```
列表裡已經看不到版本為 3.1.300 的 SDK 和版本為 3.1.4 的 Runtime 了
![Image](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihDYzTmhd2DgAqhDALcraT3QG8GU4QdMwiC8yxn0YA9UvX41FOTDioI5j_DP_9EaXAS-RTXmieaCTe8Kmwv_dJIUaRhDYf4gTpfP6JbfkntrU5-pno7c09JRjoRavajMZ9Tmpi58e2V65z/s0/dotnet-uninstall-tool-list2.png)
接著換用 `dotnet --info` 指令再確認一次是否真的移除了
```bash
$ dotnet --info
```
輸入執行後,從下圖結果可再次驗證確實真的移除了,硬碟君表示欣慰(= ̄ω ̄=)
![Image](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8ZBwDXgyF5dR-U8Sl2uv2ZPpENK1aGp_9hZbln8oOohOMfaPwsdIh6aOw7eTnkrj-bM3II8EtIyy-d7llPfKeAFR59D_3fPCa0QKoMT7npZaLi5XRYTRy5m_sZ2fhPOeeCuH6DnPWn-IM/s0/dotnet-info.png)
##總結 (Summary)
自己在經過以上一連串的操作後,真心希望未來微軟可以將此工具整合到 .NET CLI (command-line interface) 裡,然後實際要執行移除前,建議都先嘗試用模擬移除指令跑過一次,確認結果是自己想要的再真的去執行移除指令,避免悲劇發生(不過其實也還好,重新下載回來重裝即可)
補充: 原則上,該工具在執行時需要擁有較高的權限,因此官方有建議先將此工具安裝至具有寫入保護的路徑下,如`/usr/local/bin`。我自己認為這樣的好處是在使用該工具時,可以像系統一般指令那樣直接操作,但至於要不要這麼做,就見仁見智了,下面為設置方式
```bash
# 先切換到你放 .NET 移除工具的目錄
$ cd ~/dotnet_core_uninstall_directory
# 複製
$ sudo cp dotnet-core-uninstall /usr/local/bin/dotnet-uninstall
# 將擁有者改成你自己的帳號(例如我帳號為 CoCo)
$ sudo chown CoCo dotnet-uninstall
# 切回你的根目錄
$ cd ~
# 測試是否能正常執行
$ dotnet-uninstall list
```
##參考資料
[\[Microsoft\] .NET Uninstall Tool](https://docs.microsoft.com/en-us/dotnet/core/additional-tools/uninstall-tool?tabs=macos)
[\[Marcus Turewicz\] Remove old .NET versions with the new uninstall tool](https://www.marcusturewicz.com/blog/remove-old-dotnet-versions-with-the-new-uninstall-tool/)