mirror of
https://github.com/bin456789/reinstall.git
synced 2026-10-03 22:17:46 +08:00
windows: 优化 iso 查找
This commit is contained in:
+212
-104
@@ -874,7 +874,9 @@ is_have_arm_version() {
|
||||
'enterprise ltsc 2021' | 'iot enterprise ltsc 2021') return ;;
|
||||
esac
|
||||
;;
|
||||
11) return ;;
|
||||
11)
|
||||
return
|
||||
;;
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
@@ -893,9 +895,13 @@ find_windows_iso() {
|
||||
full_lang=$(english)
|
||||
|
||||
case "$basearch" in
|
||||
x86) # 备用,查找功能目前不支持 32 位
|
||||
arch_win=x86
|
||||
arch_win_vlsc='32-?bit'
|
||||
;;
|
||||
x86_64)
|
||||
arch_win=x64
|
||||
arch_win_vlsc=64bit
|
||||
arch_win_vlsc='64-?bit'
|
||||
;;
|
||||
aarch64)
|
||||
arch_win=arm64
|
||||
@@ -908,82 +914,125 @@ find_windows_iso() {
|
||||
|
||||
get_windows_iso_link() {
|
||||
get_label_msdn() {
|
||||
if [ -n "$server" ]; then
|
||||
case "$version" in
|
||||
2019 | 2022 | 2025)
|
||||
case "$edition" in
|
||||
serverstandard | serverstandardcore) echo _ ;;
|
||||
serverdatacenter | serverdatacentercore) echo _ ;;
|
||||
esac
|
||||
case "$version" in
|
||||
8 | 8.1)
|
||||
case "$edition" in
|
||||
'') # windows 8.x core
|
||||
echo _
|
||||
;;
|
||||
pro | enterprise)
|
||||
echo "$edition"
|
||||
;;
|
||||
esac
|
||||
else
|
||||
case "$version" in
|
||||
10)
|
||||
case "$edition" in
|
||||
home | 'home single language') echo consumer ;;
|
||||
pro | enterprise) echo business ;;
|
||||
education | 'pro education' | 'pro for workstations')
|
||||
case "$arch_win" in
|
||||
arm64) echo consumer ;;
|
||||
x64) echo business ;; # iso 更小
|
||||
esac
|
||||
;;
|
||||
# iot
|
||||
'iot enterprise') echo 'iot enterprise' ;;
|
||||
# iot ltsc
|
||||
'iot enterprise ltsc 2021') echo "$edition" ;;
|
||||
# ltsc
|
||||
'enterprise ltsc 2021')
|
||||
# arm64 的 enterprise ltsc 2021 要下载 iot enterprise ltsc 2021 iso
|
||||
case "$arch_win" in
|
||||
arm64) echo 'iot enterprise ltsc 2021' ;;
|
||||
x86 | x64) echo 'enterprise ltsc 2021' ;;
|
||||
esac
|
||||
;;
|
||||
;;
|
||||
10)
|
||||
case "$edition" in
|
||||
home | 'home single language')
|
||||
echo 'consumer editions'
|
||||
;;
|
||||
pro | enterprise)
|
||||
echo 'business editions'
|
||||
;;
|
||||
education | 'pro education' | 'pro for workstations')
|
||||
case "$arch_win" in
|
||||
arm64) echo 'consumer editions' ;; # 只能从 consumer 获取
|
||||
x86 | x64) echo 'business editions' ;; # iso 更小
|
||||
esac
|
||||
;;
|
||||
11)
|
||||
# iot
|
||||
'iot enterprise')
|
||||
echo 'iot enterprise'
|
||||
;;
|
||||
# ltsc
|
||||
'enterprise 2015 ltsb' | 'enterprise 2016 ltsb' | 'enterprise ltsc 2019' | 'enterprise ltsc 2021')
|
||||
case "$arch_win" in
|
||||
arm64) echo "iot $edition" ;; # 只能从 iot ltsc iso 获取
|
||||
x86 | x64) echo "$edition" ;;
|
||||
esac
|
||||
;;
|
||||
# iot ltsc
|
||||
'iot enterprise 2015 ltsb' | 'iot enterprise 2016 ltsb' | 'iot enterprise ltsc 2019' | 'iot enterprise ltsc 2021')
|
||||
echo "$edition"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
11)
|
||||
case "$edition" in
|
||||
home | 'home single language')
|
||||
echo 'consumer editions'
|
||||
;;
|
||||
pro | enterprise)
|
||||
echo 'business editions'
|
||||
;;
|
||||
education | 'pro education' | 'pro for workstations')
|
||||
# arm business iso 都没有 education, pro education, pro for workstations
|
||||
# 即使它的名字包含 EDU
|
||||
# SW_DVD9_Win_Pro_10_22H2.31_Arm64_English_Pro_Ent_EDU_N_MLF_X24-05074.ISO
|
||||
# en-us_windows_11_business_editions_version_25h2_arm64_dvd_8afc9b39.iso
|
||||
case "$edition" in
|
||||
home | 'home single language') echo consumer ;;
|
||||
pro | enterprise) echo business ;;
|
||||
education | 'pro education' | 'pro for workstations')
|
||||
case "$arch_win" in
|
||||
arm64) echo consumer ;;
|
||||
x64) echo business ;; # iso 更小
|
||||
esac
|
||||
;;
|
||||
# iot
|
||||
'iot enterprise' | 'iot enterprise subscription') echo 'iot enterprise' ;;
|
||||
# iot ltsc
|
||||
'iot enterprise ltsc 2024' | 'iot enterprise subscription ltsc 2024') echo 'iot enterprise ltsc 2024' ;;
|
||||
# ltsc
|
||||
'enterprise ltsc 2024')
|
||||
# arm64 的 enterprise ltsc 2024 要下载 iot enterprise ltsc 2024 iso
|
||||
case "$arch_win" in
|
||||
arm64) echo 'iot enterprise ltsc 2024' ;;
|
||||
x64) echo 'enterprise ltsc 2024' ;;
|
||||
esac
|
||||
;;
|
||||
case "$arch_win" in
|
||||
arm64) echo 'consumer editions' ;; # 只能从 consumer 获取
|
||||
x64) echo 'business editions' ;; # iso 更小
|
||||
esac
|
||||
;;
|
||||
# iot
|
||||
'iot enterprise' | 'iot enterprise subscription')
|
||||
echo 'iot enterprise'
|
||||
;;
|
||||
# ltsc
|
||||
'enterprise ltsc 2024')
|
||||
case "$arch_win" in
|
||||
arm64) echo "iot $edition" ;; # 只能从 iot ltsc iso 获取
|
||||
x64) echo "$edition" ;;
|
||||
esac
|
||||
;;
|
||||
# iot ltsc
|
||||
'iot enterprise ltsc 2024' | 'iot enterprise subscription ltsc 2024')
|
||||
echo 'iot enterprise ltsc 2024'
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
2019 | 2022 | 2025)
|
||||
case "$edition" in
|
||||
serverstandard | serverstandardcore | serverdatacenter | serverdatacentercore)
|
||||
echo _
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
get_label_vlsc() {
|
||||
case "$version" in
|
||||
10 | 11)
|
||||
# SW_DVD9_Win_Pro_11_25H2_Arm64_Arabic_Pro_Ent_EDU_N_MLF_X24-13113.iso
|
||||
|
||||
# SW_DVD5_WIN_ENT_LTSB_10_2015_64BIT_Arabic_MLF_X20-26578.ISO
|
||||
# SW_DVD5_WIN_ENT_LTSB_2016_64BIT_Arabic_MLF_X21-07425.ISO
|
||||
# SW_DVD5_WIN_ENT_LTSC_2019_64-bit_Arabic_MLF_X21-96407.ISO
|
||||
# SW_DVD9_WIN_ENT_LTSC_2021_64BIT_ChnSimp_MLF_X22-84402.ISO
|
||||
# SW_DVD9_WIN_ENT_LTSC_2024_64-bit_Arabic_MLF_X23-70037.ISO
|
||||
|
||||
# SW_DVD5_Win_10_IOT_Enterprise_2015_LTSB_64Bit_EMB_English_OEM_X20-20063.IMG
|
||||
# SW_DVD5_Win10_IoT_Enterprise_LTSB_1607_64-bit_EMB_English_OEM_X21-05293.IMG
|
||||
# SW_DVD9_Win_11_IoT_Enterprise_LTSC_24H2_64-Bit_English_X23-70076.ISO
|
||||
10)
|
||||
case "$edition" in
|
||||
pro | education | enterprise | 'pro education' | 'pro for workstations') echo pro ;;
|
||||
'enterprise 2015 ltsb') echo 'ent ltsb 10 2015' ;;
|
||||
'enterprise 2016 ltsb') echo 'ent ltsb 2016' ;;
|
||||
'enterprise ltsc 2019') echo 'ent ltsc 2019' ;;
|
||||
'enterprise ltsc 2021') echo 'ent ltsc 2021' ;;
|
||||
'iot enterprise 2015 ltsb') echo 'iot enterprise 2015 ltsb' ;; # √
|
||||
'iot enterprise 2016 ltsb') echo 'iot enterprise ltsb 1607' ;; # √
|
||||
'iot enterprise ltsc 2019') echo 'iot enterprise ltsc 2019' ;; # 没找到
|
||||
'iot enterprise ltsc 2021') echo 'iot enterprise ltsc 2021' ;; # 没找到
|
||||
esac
|
||||
;;
|
||||
2025)
|
||||
echo SrvSTDCORE
|
||||
11)
|
||||
case "$edition" in
|
||||
pro | education | enterprise | 'pro education' | 'pro for workstations') echo pro ;;
|
||||
'enterprise ltsc 2024') echo 'ent ltsc 2024' ;;
|
||||
'iot enterprise ltsc 2024' | 'iot enterprise subscription ltsc 2024') echo 'iot enterprise ltsc 24h2' ;; # √
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
@@ -997,20 +1046,26 @@ get_windows_iso_link() {
|
||||
:
|
||||
}
|
||||
|
||||
get_page() {
|
||||
if [ "$arch_win" = arm64 ]; then
|
||||
echo arm
|
||||
elif is_ltsc; then
|
||||
echo ltsc
|
||||
get_page_url() {
|
||||
local page=
|
||||
|
||||
if is_ltsc; then
|
||||
page=ntriver/ltsc
|
||||
elif [ "$server" = 'server' ]; then
|
||||
echo server
|
||||
page=massgrave/server
|
||||
else
|
||||
case "$version" in
|
||||
10 | 11)
|
||||
echo "$version"
|
||||
8 | 8.1 | 10 | 11)
|
||||
page=ntriver/$version
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
case "$page" in
|
||||
massgrave/server) echo https://massgrave.dev/windows-server-links ;;
|
||||
massgrave/*) echo https://massgrave.dev/windows_${page#*/}_links ;;
|
||||
ntriver/*) echo https://ntriver.org/download-windows-${page#*/} ;;
|
||||
esac
|
||||
}
|
||||
|
||||
is_ltsc() {
|
||||
@@ -1021,13 +1076,7 @@ get_windows_iso_link() {
|
||||
label_msdn=$(get_label_msdn)
|
||||
label_msdl=$(get_label_msdl)
|
||||
label_vlsc=$(get_label_vlsc)
|
||||
page=$(get_page)
|
||||
|
||||
if [ "$page" = server ]; then
|
||||
page_url=https://massgrave.dev/windows-server-links
|
||||
else
|
||||
page_url=https://massgrave.dev/windows_${page}_links
|
||||
fi
|
||||
page_url=$(get_page_url)
|
||||
|
||||
info "Find windows iso"
|
||||
echo "Version: $version"
|
||||
@@ -1035,7 +1084,7 @@ get_windows_iso_link() {
|
||||
echo "Label msdn: $label_msdn"
|
||||
echo "Label msdl: $label_msdl"
|
||||
echo "Label vlsc: $label_vlsc"
|
||||
echo "List: $page_url"
|
||||
echo "Page: $page_url"
|
||||
echo
|
||||
|
||||
# 先判断是否能自动查找该版本
|
||||
@@ -1043,7 +1092,7 @@ get_windows_iso_link() {
|
||||
# 这样可以在输入错误 Edition 时例如 windows 11 enterprise ltsc 2021
|
||||
# 显示名称错误,而不是显示该版本不支持 arm
|
||||
|
||||
if [ -z "$page" ] || { [ -z "$label_msdn" ] && [ -z "$label_msdl" ] && [ -z "$label_vlsc" ]; }; then
|
||||
if [ -z "$page_url" ] || { [ -z "$label_msdn" ] && [ -z "$label_msdl" ] && [ -z "$label_vlsc" ]; }; then
|
||||
error_and_exit "Not support find this iso. Check if --image-name is wrong. Or set --iso manually."
|
||||
fi
|
||||
|
||||
@@ -1056,26 +1105,32 @@ get_windows_iso_link() {
|
||||
else
|
||||
http_to_host=$(get_scheme_and_host_by_url "$page_url")
|
||||
http_to_current_dir=$(dirname "$page_url")
|
||||
curl -L "$page_url" |
|
||||
tr -d '\n' | sed -e 's,<a ,\n<a ,g' -e 's,</a>,</a>\n,g' | # 使每个 <a></a> 占一行
|
||||
grep -Ei '\.(iso|img)</a>$' | # 找出是 iso 或 img 的行
|
||||
# 提取文件名和链接
|
||||
|
||||
curl -L "$page_url" | tr -d '\n' | # 合成一行
|
||||
if [[ "$page_url" =~ massgrave.dev ]]; then
|
||||
sed -e 's,<a ,\n<a ,g' -e 's,</a>,</a>\n,g' | # 使每个 <a></a> 占一行
|
||||
grep -Ei '\.(iso|img)</a>$' | # 找出是 iso 或 img 的行
|
||||
sed -E 's,<a href="?([^" ]+)"?.+>(.+)</a>,\2 \1,' # 提取文件名和链接
|
||||
else
|
||||
sed -e 's,<td><strong>,\n<td><strong>,g' -e 's,</a>,</a>\n,g' | # 使每个镜像占一行
|
||||
grep -Ei '\.(iso|img)</strong>' | # 找出是 iso 或 img 的行
|
||||
sed -E 's,<td><strong>([^<]+).+<a href="?([^" ]+)"?.+,\1 \2,' # 提取文件名和链接
|
||||
fi |
|
||||
|
||||
# 如果链接是 / 开头,则补全域名
|
||||
# 如果链接非 https:// 开头,则补全域名和目录
|
||||
sed -E -e 's,<a href="?([^" ]+)"?.+>(.+)</a>,\2 \1,' \
|
||||
-e "s, (/), $http_to_host\1," |
|
||||
awk '{if ($2 !~ /^https?:\/\//) $2 = "'$http_to_current_dir/'" $2; print}' >$tmp/win.list
|
||||
sed -E "s, (/), $http_to_host\1," |
|
||||
awk '{if ($2 !~ /^https?:\/\//) $2 = "'$http_to_current_dir/'" $2; print}' |
|
||||
|
||||
# 如果不是 ltsc ,应该先去除 ltsc 链接,否则最终链接有 ltsc 的
|
||||
# 例如查找 windows 10 iot enterprise,会得到
|
||||
# en-us_windows_10_iot_enterprise_ltsc_2021_arm64_dvd_e8d4fc46.iso
|
||||
# en-us_windows_10_iot_enterprise_version_22h2_arm64_dvd_39566b6b.iso
|
||||
# sed -Ei 和 sed -iE 是不同的
|
||||
if is_ltsc; then
|
||||
sed -Ei '/ltsc|ltsb/!d' $tmp/win.list
|
||||
else
|
||||
sed -Ei '/ltsc|ltsb/d' $tmp/win.list
|
||||
fi
|
||||
# 如果不是 ltsc ,应该先去除 ltsc 链接,否则最终链接有 ltsc 的
|
||||
# 例如查找 windows 10 iot enterprise,会得到
|
||||
# en-us_windows_10_iot_enterprise_ltsc_2021_arm64_dvd_e8d4fc46.iso
|
||||
# en-us_windows_10_iot_enterprise_version_22h2_arm64_dvd_39566b6b.iso
|
||||
if is_ltsc; then
|
||||
grep -Ei '_lts[bc]_'
|
||||
else
|
||||
grep -Ei -v '_lts[bc]_'
|
||||
fi >$tmp/win.list
|
||||
|
||||
get_windows_iso_link_inner
|
||||
fi
|
||||
@@ -1090,6 +1145,29 @@ get_shortest_line_by_field() {
|
||||
awk "(NR == 1 || length(\$$field) < length(field)) { line = \$0; field = \$$field } END { print line }"
|
||||
}
|
||||
|
||||
get_best_windows_iso_line() {
|
||||
local lines
|
||||
lines=$(cat)
|
||||
|
||||
# 在所有符合的 iso 中
|
||||
# 先选择 win10/11 大版本更新的 (version 26h1) 或者有 sp 版本的 (sp1, windows_8.1_with_update_)
|
||||
# 再选择有日期更新的 (updated_july_2026)
|
||||
# 再选择 vl
|
||||
# 再按版本号排序选择最新版
|
||||
|
||||
# 但是也有例外
|
||||
# zh-cn_windows_server_2019_x64_dvd_19d65722.iso 2022-11-15
|
||||
# cn_windows_server_2019_updated_april_2021_x64_dvd_a6dae187.iso 2021-04-20
|
||||
|
||||
for key in '(version|sp[0-9]|update)' 'updated' 'vl'; do
|
||||
if grep_lines=$(grep -E "_${key}_" <<<"$lines"); then
|
||||
lines=$grep_lines
|
||||
fi
|
||||
done
|
||||
|
||||
echo "$lines" | sort -Vr | head -1
|
||||
}
|
||||
|
||||
get_windows_iso_link_inner() {
|
||||
regexs=()
|
||||
|
||||
@@ -1099,14 +1177,29 @@ get_windows_iso_link_inner() {
|
||||
label_msdn=
|
||||
fi
|
||||
for lang in $langs; do
|
||||
regex=
|
||||
# en_windows_vista_sp2_x64_dvd_342267.iso
|
||||
# cn_windows_vista_with_sp2_x64_dvd_x15-36322.iso
|
||||
# en_windows_8_x64_dvd_915440.iso
|
||||
# en_windows_8.1_pro_vl_with_update_x64_dvd_6050880.iso
|
||||
# en_windows_8.1_with_update_x64_dvd_6051480.iso
|
||||
# en_windows_8.1_n_with_update_x64_dvd_6051677.iso
|
||||
# en-us_windows_10_iot_enterprise_version_22h2_arm64_dvd_39566b6b.iso
|
||||
# en-us_windows_11_consumer_editions_version_26h1_updated_july_2026_x64_dvd_f69a9a1e.iso
|
||||
# en-us_windows_server_2025_updated_july_2026_x64_dvd_4e6f5a42.iso
|
||||
local prefix=
|
||||
for i in ${lang} windows ${server} ${version} ${label_msdn}; do
|
||||
if [ -n "$i" ]; then
|
||||
regex+="${i}_"
|
||||
prefix+="${i}_"
|
||||
fi
|
||||
done
|
||||
regex+=".*${arch_win}.*.(iso|img)"
|
||||
regexs+=("$regex")
|
||||
|
||||
# 用于准确匹配,例如防止 2012 匹配到 2012 r2
|
||||
# 首先匹配 label 后面紧接着这些关键字的
|
||||
# 然后匹配 label 后面紧接着 x64/arm64 的
|
||||
# 最后模糊匹配
|
||||
regexs+=("${prefix}(version|vl|with|updated|sp[0-9])_.*${arch_win}.*\.(iso|img)")
|
||||
regexs+=("${prefix}${arch_win}.*\.(iso|img)")
|
||||
regexs+=("${prefix}.*${arch_win}.*\.(iso|img)")
|
||||
done
|
||||
fi
|
||||
|
||||
@@ -1118,8 +1211,14 @@ get_windows_iso_link_inner() {
|
||||
# 先判断 full_lang 是否为空
|
||||
# 因为假如用户输入的 lang 不正确,full_lang 就为空,正则表达式就无法只匹配当前语言
|
||||
if [ -n "$label_vlsc" ] && [ -n "$full_lang" ]; then
|
||||
regex="sw_?dvd[59]_win_?${label_vlsc}_?${version}.*${arch_win_vlsc}_${full_lang}.*.(iso|img)"
|
||||
regexs+=("$regex")
|
||||
regexs+=("sw_?dvd[59]_win_?${label_vlsc}_?${version}_.*${arch_win_vlsc}.*_${full_lang}.*.(iso|img)")
|
||||
regexs+=("sw_?dvd[59]_win_?${version}_${label_vlsc}_?.*${arch_win_vlsc}.*_${full_lang}.*.(iso|img)")
|
||||
# LTSC 没有 windows 主版本号
|
||||
# SW_DVD5_WIN_ENT_LTSB_10_2015_64BIT_Arabic_MLF_X20-26578.ISO # 将 ENT_LTSB_10_2015 视为 label
|
||||
# SW_DVD5_WIN_ENT_LTSB_2016_64BIT_Arabic_MLF_X21-07425.ISO # 将 ENT_LTSB_2016 视为 label
|
||||
if is_ltsc; then
|
||||
regexs+=("sw_?dvd[59]_win_?${label_vlsc}_?.*${arch_win_vlsc}.*_${full_lang}.*.(iso|img)")
|
||||
fi
|
||||
fi
|
||||
|
||||
# 查找
|
||||
@@ -1127,10 +1226,16 @@ get_windows_iso_link_inner() {
|
||||
regex=${regex// /_}
|
||||
|
||||
echo "looking for: $regex" >&2
|
||||
if line=$(grep -Ei "^$regex " "$tmp/win.list" | get_shortest_line_by_field 1 | grep .) &&
|
||||
iso=$(awk '{print $2}' <<<"$line" | grep .); then
|
||||
echo "Selected: $line" >&2
|
||||
return
|
||||
local matched_lines
|
||||
if matched_lines=$(grep -Ei "^$regex " "$tmp/win.list"); then
|
||||
info "ISO Matched"
|
||||
cat -n <<<"$matched_lines" >&2
|
||||
if line=$(echo "$matched_lines" | get_best_windows_iso_line | grep .) &&
|
||||
iso=$(awk '{print $2}' <<<"$line" | grep .); then
|
||||
info "ISO Selected"
|
||||
echo " $line" >&2
|
||||
return
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -1531,7 +1636,8 @@ Continue?
|
||||
else
|
||||
iso_is_tested=false
|
||||
if $auto_find_iso; then
|
||||
if test_url_grace "$iso" iso 2>/dev/null; then
|
||||
# 目前自动获取 iso 肯定不是直连,因此先关闭直连测试
|
||||
if false && test_url_grace "$iso" iso 2>/dev/null; then
|
||||
iso_is_tested=true
|
||||
else
|
||||
# 需要用户输入 massgrave.dev 直链
|
||||
@@ -1548,6 +1654,8 @@ Continue?
|
||||
IFS= read -r -p "Direct Link: " iso
|
||||
if [ -z "$iso" ]; then
|
||||
error_and_exit "ISO Link is empty."
|
||||
elif ! grep -Eiq '^https?://' <<<"$iso"; then
|
||||
error_and_exit "ISO Link is invalid."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user