diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml
index a5d10909..98726cce 100644
--- a/.github/workflows/deployment.yml
+++ b/.github/workflows/deployment.yml
@@ -267,6 +267,8 @@ jobs:
         if: matrix.triple.target == 'x86_64-pc-windows-msvc'
         run: |
           python "./deployment/packager.py" ${{ env.RELEASE_VERSION }} "./deployment/windows/winget/winget.yaml.template" "Clement.bottom.yaml" "SHA256" "./bottom_x86_64_installer.msi"
+          $Code = powershell ./deployment/windows/winget/get_product_code.ps1 ./bottom_x86_64_installer.msi
+          python "./deployment/windows/winget/product_code.py" Clement.bottom.yaml $Code
 
       - name: Upload winget file (Windows x86-64 MSVC)
         if: matrix.triple.target == 'x86_64-pc-windows-msvc'
diff --git a/deployment/windows/winget/get_product_code.ps1 b/deployment/windows/winget/get_product_code.ps1
new file mode 100644
index 00000000..e12e2582
--- /dev/null
+++ b/deployment/windows/winget/get_product_code.ps1
@@ -0,0 +1,11 @@
+$path = $args[0]
+
+$comObjWI = New-Object -ComObject WindowsInstaller.Installer
+$MSIDatabase = $comObjWI.GetType().InvokeMember("OpenDatabase","InvokeMethod",$Null,$comObjWI,@($Path,0))
+$Query = "SELECT Value FROM Property WHERE Property = 'ProductCode'"
+$View = $MSIDatabase.GetType().InvokeMember("OpenView","InvokeMethod",$null,$MSIDatabase,($Query))
+$View.GetType().InvokeMember("Execute", "InvokeMethod", $null, $View, $null)
+$Record = $View.GetType().InvokeMember("Fetch","InvokeMethod",$null,$View,$null)
+$Value = $Record.GetType().InvokeMember("StringData","GetProperty",$null,$Record,1)
+
+echo $Value
\ No newline at end of file
diff --git a/deployment/windows/winget/product_code.py b/deployment/windows/winget/product_code.py
new file mode 100644
index 00000000..b56f5825
--- /dev/null
+++ b/deployment/windows/winget/product_code.py
@@ -0,0 +1,20 @@
+import sys
+from string import Template
+
+args = sys.argv
+template_file_path = args[1]
+product_code = args[2]
+
+with open(template_file_path, "r") as template_file:
+    template = Template(template_file.read())
+
+    substitutes = dict()
+    substitutes["product_code"] = "'{}'".format(product_code)
+    substitute = template.safe_substitute(substitutes)
+
+    print("\n================== Generated package file ==================\n")
+    print(substitute)
+    print("\n============================================================\n")
+
+with open(template_file_path, "w") as template_file:
+    template_file.write(substitute)
diff --git a/deployment/windows/winget/winget.yaml.template b/deployment/windows/winget/winget.yaml.template
index d577505a..fb85d671 100644
--- a/deployment/windows/winget/winget.yaml.template
+++ b/deployment/windows/winget/winget.yaml.template
@@ -11,11 +11,15 @@ Tags:
 - terminal
 ShortDescription: Yet another cross-platform graphical process/system monitor.
 PackageUrl: https://github.com/ClementTsang/bottom
+Commands:
+- btm
 Installers:
 - Architecture: x64
   InstallerUrl: https://github.com/ClementTsang/bottom/releases/download/$version/bottom_x86_64_installer.msi
   InstallerSha256: $hash1
+  ProductCode: $product_code
   InstallerType: msi
+  Scope: machine
 PackageLocale: en-US
 ManifestType: singleton
-ManifestVersion: 1.0.0
\ No newline at end of file
+ManifestVersion: 1.0.0