From 27dd00c0784bc39fbc91f6fd6cfec500a4903bd4 Mon Sep 17 00:00:00 2001 From: bin456789 Date: Tue, 4 Aug 2026 21:10:05 +0800 Subject: [PATCH] =?UTF-8?q?windows:=20=E4=BC=98=E5=8C=96=20iso=20=E6=9F=A5?= =?UTF-8?q?=E6=89=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.en.md | 7 +- README.md | 7 +- reinstall.sh | 316 ++++++++++++++++++++++++++++++++++----------------- 3 files changed, 220 insertions(+), 110 deletions(-) diff --git a/README.en.md b/README.en.md index 185d755..3e8ca0a 100644 --- a/README.en.md +++ b/README.en.md @@ -356,8 +356,8 @@ bash reinstall.sh netboot.xyz #### Method 1: Let the Script Automatically Search for ISO -- The script will search for ISOs from , a site that collects official ISOs. -- Only supports ISOs searching for Windows 10, 11, Server 2019, 2022, 2025. +- The script will search for ISOs from and , sites that collect official ISOs. +- Only supports ISOs searching for Windows 8.x, 10, 11, Server 2019, 2022, 2025. ```bash bash reinstall.sh windows \ @@ -436,7 +436,8 @@ bash reinstall.sh windows \ - General - - - + - (Recommended, ISOs are up to date) + - (Recommended, ISOs are up to date) - - - (Need to open it with a non-Windows User-Agent) diff --git a/README.md b/README.md index c343c4f..56e4774 100644 --- a/README.md +++ b/README.md @@ -356,8 +356,8 @@ bash reinstall.sh netboot.xyz #### 方法 1: 让脚本自动查找 ISO -- 脚本会从 查找 ISO,该网站专门提供官方 ISO 下载 -- 只支持查找 Windows 10, 11, Server 2019, 2022, 2025 的 ISO +- 脚本会从 和 查找 ISO,网站专门提供官方 ISO 下载 +- 只支持查找 Windows 8.x, 10, 11, Server 2019, 2022, 2025 的 ISO ```bash bash reinstall.sh windows \ @@ -436,7 +436,8 @@ bash reinstall.sh windows \ - 正式版 - - - + - (推荐,ISO 是最新版) + - (推荐,ISO 是最新版) - - - (需用非 Windows User-Agent 打开) diff --git a/reinstall.sh b/reinstall.sh index 1ce22cd..d4c05d4 100644 --- a/reinstall.sh +++ b/reinstall.sh @@ -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,,\n,g' | # 使每个 占一行 - grep -Ei '\.(iso|img)$' | # 找出是 iso 或 img 的行 - # 提取文件名和链接 + + curl -L "$page_url" | tr -d '\n' | # 合成一行 + if [[ "$page_url" =~ massgrave.dev ]]; then + sed -e 's,,\n,g' | # 使每个 占一行 + grep -Ei '\.(iso|img)$' | # 找出是 iso 或 img 的行 + sed -E 's,(.+),\2 \1,' # 提取文件名和链接 + else + sed -e 's,,\n,g' -e 's,,\n,g' | # 使每个镜像占一行 + grep -Ei '\.(iso|img)' | # 找出是 iso 或 img 的行 + sed -E 's,([^<]+).+(.+),\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