diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index a490a0513f7971003a4ee75e81f58fa89b9b528d..eb0aca62c39a7d37817de0334918f59152e46723 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,7 +1,7 @@
 image: golang
 
 build:
-  script: tools/build-and-pack.sh
+  script: tools/build-and-pack.sh common-arch-only
   artifacts:
     paths:
       - "*.tar.gz"
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index e539a9a4e328218d9cc19c15d0bf66fabcf350a4..899605e3a00b7785dc8804bd910fb6cbe2729027 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -13,7 +13,7 @@ steps:
   inputs:
     targetType: inline
     script: >
-      tools/build-and-pack.sh
+      tools/build-and-pack.sh common-arch-only
 
       for fname in ./*.tar.gz; do
         curl -X PUT -u "recolic-manifact:$RECOLIC_MANIFACT_ACC_TOKEN" "https://drive.recolic.net/remote.php/dav/files/recolic-manifact/openxt-release/$fname" --data-binary @"$fname"
diff --git a/envImpl.go b/envImpl.go
index e4c320da2b22cd7c580a288978a8121b666495b4..b1fb3e4c6ff2bd88421521f4aa88a34064f3a2f8 100644
--- a/envImpl.go
+++ b/envImpl.go
@@ -3,7 +3,7 @@ package main
 import "fmt"
 
 // generateEnvvar generates key-value pairs, and this function converts key-value pairs into good env string.
-// supports: bash, fish, powershell
+// supports: bash, fish, powershell, cmd
 // panic on error, because it seems to be unrecoverable.
 func SerializeEnvvar(shellName string, asUniversalVar bool, kvPairs map[string]string) string {
 	result, fmtStr := "", ""
@@ -26,8 +26,15 @@ func SerializeEnvvar(shellName string, asUniversalVar bool, kvPairs map[string]s
 		if asUniversalVar {
 			panic("serializeEnvvar.NotSupportedError: doesn't support powershell universal variable. ")
 		}
+		break
+	case "cmd":
+		fmtStr = "set \"%v=%v\""
+		if asUniversalVar {
+			panic("serializeEnvvar.NotSupportedError: doesn't support cmd universal variable. ")
+		}
+		break
 	default:
-		panic("serializeEnvvar.InvalidArgument: shellName should be bash,fish,powershell, instead of " + shellName)
+		panic("serializeEnvvar.InvalidArgument: shellName should be bash,fish,powershell,cmd, instead of " + shellName)
 	}
 
 	for k, v := range kvPairs {
diff --git a/main.go b/main.go
index 6e1ed03c8ed57916074f26d61895bf8b332a7e04..2810cc86a51276a1485a855a90e0b45f36f64e39 100644
--- a/main.go
+++ b/main.go
@@ -10,7 +10,7 @@ import (
 // Some options here. Would be improved in beta release.
 const DEDUCT_PKGNAME_FROM_VARNAME = true
 const USE_PROJECT_NETVER_INSTEAD_OF_HINTPATH_NETVER = false
-const OPENXT_VERSION = "1.4.1-2"
+const OPENXT_VERSION = "1.4.1-3"
 
 func print_help_and_exit() {
 	println("Usage: openxt <subcommand> [options...]")
@@ -33,7 +33,7 @@ func main() {
 	nugetConfigPath := flag.String("nuget-config", "", "Path to nuget.config. It's ~/.nuget/NuGet/NuGet.Config by default. ")
 	localRepoDir := flag.String("local-repo-dir", "", "Path to local nuget repo. (known as CxCache in CoreXT)")
 	binDir := flag.String("bin-dir", "", "Path for output build. (TODO: remove in the future)")
-	shell := flag.String("shell", "bash", "Shell for the output env variables, supports bash/fish/powershell")
+	shell := flag.String("shell", "bash", "Shell for the output env variables, supports bash/fish/powershell/cmd")
 	if(len(os.Args) < 2) {
 		print_help_and_exit()
 	}
diff --git a/tools/build-and-pack.sh b/tools/build-and-pack.sh
index b84731705a05a83a9590853e912f4ba80c617f67..a764a0c11bf57bd78b6aec534012275d9bfa1e03 100755
--- a/tools/build-and-pack.sh
+++ b/tools/build-and-pack.sh
@@ -31,13 +31,14 @@ build linux amd64
 build linux 386
 build linux arm
 build linux arm64
-build freebsd amd64
-build openbsd amd64
 build darwin amd64
 build windows amd64
 build windows arm
 build windows 386
+[[ "$1" = "common-arch-only" ]] && exit 0
 
+build freebsd amd64
+build openbsd amd64
 build linux mips
 build linux mips64
 build linux mipsle