From a12718e49c23ff7a21dfffa368fd811c671ce054 Mon Sep 17 00:00:00 2001 From: bin456789 Date: Sun, 2 Mar 2025 21:57:06 +0800 Subject: [PATCH] =?UTF-8?q?windows:=20=E4=BB=8E=20inf=20=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E9=A9=B1=E5=8A=A8=E6=96=87=E4=BB=B6=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.en.md | 27 ++-- README.md | 26 ++-- reinstall.sh | 88 +++++++++---- trans.sh | 69 ++++++---- windows-driver-utils.sh | 278 ++++++++++++++++++++++++++++++++++++++++ windows-setup.bat | 17 ++- 6 files changed, 435 insertions(+), 70 deletions(-) create mode 100644 windows-driver-utils.sh diff --git a/README.en.md b/README.en.md index e0d308c..fe22375 100644 --- a/README.en.md +++ b/README.en.md @@ -11,19 +11,18 @@ One-Click Script to Reinstall System [中文](README.md) -![Sponsors](https://raw.githubusercontent.com/bin456789/sponsors/refs/heads/master/sponsors.svg) +[![Sponsors](https://raw.githubusercontent.com/bin456789/sponsors/refs/heads/master/sponsors.svg)](https://github.com/sponsors/bin456789) ## Highlights - One-click Linux installation: Supports 19 common distributions. - One-click Windows installation: Uses the official ISO for installation instead of custom images. The script can automatically ~~retrieves the ISO link~~ and installs common drivers like `Virtio`. - Supports installation in any direction, i.e., `Linux to Linux`, `Linux to Windows`, `Windows to Windows`, `Windows to Linux` -- No need to input IP parameters; automatically recognizes dynamic and static IPs, supports `/32`, `/128`, `gateway outside subnet`, `IPv6 only`, `dual NIC` and other special network configurations +- No need to input IP parameters; automatically recognizes dynamic and static IPs, supports `/32`, `/128`, `gateway outside subnet`, `IPv6 only`, `dual NIC` - Specially optimized for low-spec servers, requires less memory than the official netboot - Uses partition table ID to identify hard drives throughout the process, ensuring no wrong disk is written - Supports BIOS and EFI boot, and ARM Server - No homemades image included, all resources are obtained in real-time from mirror sites -- Includes many comments. ## System Requirements @@ -32,7 +31,7 @@ The original system can be any system listed in the table. The system requirements for the target system are as follows: | System | Version | Memory | Disk | -| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | --------- | -----------------| +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | --------- | ---------------- | | Alpine | 3.18, 3.19, 3.20, 3.21 | 256 MB | 1 GB | | Debian | 9, 10, 11, 12 | 256 MB | 1 ~ 1.5 GB ^ | | Kali | Rolling | 256 MB | 1 ~ 1.5 GB ^ | @@ -144,6 +143,7 @@ bash reinstall.sh anolis 7|8|23 kali arch gentoo + aosc fnos ``` @@ -329,6 +329,14 @@ bash reinstall.sh windows \ --iso "https://go.microsoft.com/fwlink/?linkid=2289029" ``` +or Magnet Link + +```bash +bash reinstall.sh windows \ + --image-name "Windows 11 Enterprise LTSC 2024" \ + --iso "magnet:?xt=urn:btih:7352bd2db48c3381dffa783763dc75aa4a6f1cff" +``` +
The following website provides ISO links. @@ -336,6 +344,8 @@ bash reinstall.sh windows \ - General - - + - + - - (Need to open it with a non-Windows User-Agent) - - @@ -349,8 +359,8 @@ bash reinstall.sh windows \ - - - Insider Preview - - - - + - + -
@@ -361,10 +371,9 @@ bash reinstall.sh windows \ - `--rdp-port PORT` Change RDP port - `--ssh-port PORT` Change SSH port (for log observation during installation) - `--web-port PORT` Change Web port (for log observation during installation) -- `--add-driver-dir DIR` Adds additional driver, specifying the folder where the .inf file is located. +- `--add-driver INF_OR_DIR` Add additional driver, specifying .inf path, or the folder contains .inf file. - The driver must be downloaded locally first. - - This parameter can be set multiple times to add different driver folders. - - The script will copy the entire folder, so no other files should be placed inside the folder. + - This parameter can be set multiple times to add different driver. - `--hold 2` Allow SSH connections for modifying the disk content before rebooting into the official Windows installation program, with the disk mounted at `/os`. #### The following drivers will automatic download and install as needed, without the need for manual addition diff --git a/README.md b/README.md index d360238..8541556 100644 --- a/README.md +++ b/README.md @@ -11,19 +11,18 @@ 一键重装脚本 [English](README.en.md) -![捐赠者](https://raw.githubusercontent.com/bin456789/sponsors/refs/heads/master/sponsors.svg) +[![Sponsors](https://raw.githubusercontent.com/bin456789/sponsors/refs/heads/master/sponsors.svg)](https://github.com/sponsors/bin456789) ## 亮点 - 一键安装 Linux,支持 19 种常见发行版 - 一键安装 Windows,使用官方 ISO 安装而非自制镜像,~~脚本会自动获取 ISO 链接~~、自动安装 Virtio 等常见驱动 - 支持任意方向重装,即 `Linux to Linux`、`Linux to Windows`、`Windows to Windows`、`Windows to Linux` -- 无需填写 IP 参数,自动识别动静态,支持 `/32`、`/128`、`网关不在子网范围内`、`纯 IPv6`、`双网卡` 等特殊网络 +- 无需填写 IP 参数,自动识别动静态,支持 `/32`、`/128`、`网关不在子网范围内`、`纯 IPv6`、`双网卡` - 专门适配低配小鸡,比官方 netboot 需要更少的内存 - 全程用分区表 ID 识别硬盘,确保不会写错硬盘 - 支持 BIOS、EFI 引导,支持 ARM 服务器 - 不含自制包,所有资源均实时从镜像源获得 -- 有很多注释 ## 系统要求 @@ -47,7 +46,7 @@ | NixOS | 24.11 | 512 MB | 5 GB | | Arch | 滚动 | 512 MB | 5 GB | | Gentoo | 滚动 | 512 MB | 5 GB | -| 安同 OS | 滚动 | 512 MB | 5 GB | +| 安同 OS | 滚动 | 512 MB | 5 GB | | 飞牛 fnOS | 公测 | 512 MB | 12 GB | | Windows (DD) | 任何 | 512 MB | 取决于镜像 | | Windows (ISO) | Vista, 7, 8.x (Server 2008 - 2012 R2) | 512 MB | 25 GB | @@ -330,6 +329,14 @@ bash reinstall.sh windows \ --iso "https://go.microsoft.com/fwlink/?linkid=2289029" ``` +或者磁力链接 + +```bash +bash reinstall.sh windows \ + --image-name "Windows 11 Enterprise LTSC 2024" \ + --iso "magnet:?xt=urn:btih:7352bd2db48c3381dffa783763dc75aa4a6f1cff" +``` +
以下网站可找到 ISO 链接 @@ -337,6 +344,8 @@ bash reinstall.sh windows \ - 正式版 - - + - + - - (需用非 Windows User-Agent 打开) - - @@ -350,8 +359,8 @@ bash reinstall.sh windows \ - - - Insider 预览版 - - - - + - + -
@@ -362,10 +371,9 @@ bash reinstall.sh windows \ - `--rdp-port PORT` 更改 RDP 端口 - `--ssh-port PORT` 修改 SSH 端口(安装期间观察日志用) - `--web-port PORT` 修改 Web 端口(安装期间观察日志用) -- `--add-driver-dir DIR` 添加额外驱动,填写 .inf 所在的文件夹 +- `--add-driver INF_OR_DIR` 添加额外驱动,填写 .inf 路径,或者 .inf 所在的文件夹 - 需先下载驱动到本地 - - 可多次设置该参数以添加不同的驱动文件夹 - - 脚本将复制整个文件夹,因此文件夹内不要放置其他文件 + - 可多次设置该参数以添加不同的驱动 - `--hold 2` 在进入 Windows 官方安装程序之前,可以 SSH 登录修改硬盘内容,硬盘挂载在 `/os` #### 以下驱动会自动按需下载安装,无需手动添加 diff --git a/reinstall.sh b/reinstall.sh index 9abe261..0a488a7 100644 --- a/reinstall.sh +++ b/reinstall.sh @@ -81,8 +81,15 @@ EOF } info() { - upper=$(to_upper <<<"$@") - echo_color_text '\e[32m' "***** $upper *****" >&2 + local msg + if [ "$1" = false ]; then + shift + msg=$* + else + msg=$(to_upper <<<"$@") + fi + + echo_color_text '\e[32m' "***** $msg *****" >&2 } warn() { @@ -91,7 +98,7 @@ warn() { error() { echo_color_text '\e[31m' "***** ERROR *****" >&2 - echo_color_text '\e[31m' "Error: $*" >&2 + echo_color_text '\e[31m' "$*" >&2 } echo_color_text() { @@ -609,6 +616,12 @@ is_virt() { $_is_virt } +is_absolute_path() { + # 检查路径是否以/开头 + # 注意语法和 ash 不同 + [[ "$1" = /* ]] +} + assert_cpu_supports_x86_64_v3() { # 用 ld.so/cpuid/coreinfo.exe 更准确 # centos 7 /usr/lib64/ld-linux-x86-64.so.2 没有 --help @@ -2150,7 +2163,13 @@ del_empty_lines() { sed '/^[[:space:]]*$/d' } +trim() { + # sed -E -e 's/^[[:space:]]+//' -e 's/[[:space:]]+$//' + sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' +} + prompt_password() { + info "prompt password" while true; do IFS= read -r -p "Password [$DEFAULT_PASSWORD]: " password IFS= read -r -p "Retype password [$DEFAULT_PASSWORD]: " password_confirm @@ -3459,16 +3478,12 @@ This script is outdated, please download reinstall.sh again. fi # 添加自定义 windows 驱动 - if [ "$distro" = windows ]; then - mkdir -p $initrd_dir/custom_drivers - i=0 - while IFS= read -r dir; do - if [ -d "$dir" ]; then - ((i += 1)) - info "add custom driver: $dir" - cp -r "$dir" "$initrd_dir/custom_drivers/$i" - fi - done < <(echo "$custom_driver_dirs") + if [ "$distro" = windows ] && [ -n "$custom_infs" ]; then + # shellcheck disable=SC1090 + . <(curl -L $confhome/windows-driver-utils.sh) + echo "$custom_infs" | while read -r inf; do + parse_inf_and_cp_driever "$inf" "$initrd_dir/custom_drivers" "$basearch_alt" true + done fi # alpine live 不精简 initrd @@ -3594,7 +3609,7 @@ fi long_opts= for o in ci installer debug minimal allow-ping force-cn \ - add-driver-dir: \ + add-driver: \ hold: sleep: \ iso: \ image-name: \ @@ -3687,26 +3702,45 @@ while true; do web_port=$2 shift 2 ;; - --add-driver-dir) - # 指定 dir 而不是指定 inf - # 防止用户将 inf 放在 / 而复制整个 / - + --add-driver) # 路径转换 if is_in_windows; then # 输入的路径是 / 开头也没问题 - dir="$(cygpath -u "$2")" + inf_or_dir="$(cygpath -u "$2")" else - dir=$2 + inf_or_dir=$2 fi - # 防止重复添加 - if ! grep -Fqx "$dir" <<<"$custom_driver_dirs"; then - # shellcheck disable=SC2010 - { [ -d "$dir" ] && ls "$dir" | grep -Eiq '\.inf$'; } || error_and_exit "Invalid Driver Directory: $2" - # 一行一个驱动文件夹 - custom_driver_dirs+="$dir -" + # alpine busybox 不支持 readlink -m + # readlink -m /asfsafasfsaf/fasf + # 因此需要先判断路径是否存在 + + if ! [ -d "$inf_or_dir" ] && + ! { [ -f "$inf_or_dir" ] && [[ "$inf_or_dir" =~ \.[iI][nN][fF]$ ]]; }; then + error_and_exit "Not a inf or dir: $2" fi + + # 转为绝对路径 + inf_or_dir=$(readlink -f "$inf_or_dir") + + info "finding inf in $inf_or_dir" + # find /tmp -type f -iname '*.inf' 只要 /tmp 存在就会返回 0 + if infs=$(find "$inf_or_dir" -type f -iname '*.inf' | grep .); then + while IFS= read -r inf; do + # 防止重复添加 + if ! grep -Fqx "$inf" <<<"$custom_infs"; then + echo "inf found: $inf" + # 一行一个 inf + if [ -n "$custom_infs" ]; then + custom_infs+=$'\n' + fi + custom_infs+=$inf + fi + done <<<"$infs" + else + error_and_exit "Can't find inf files in $2" + fi + shift 2 ;; --force-old-windows-setup) diff --git a/trans.sh b/trans.sh index af526c2..aba565d 100644 --- a/trans.sh +++ b/trans.sh @@ -20,13 +20,28 @@ error() { color='\e[31m' plain='\e[0m' echo -e "${color}***** ERROR *****${plain}" >&2 - echo -e "${color}Error: $*${plain}" >&2 + echo -e "${color}$*${plain}" >&2 } info() { color='\e[32m' plain='\e[0m' - echo -e "${color}***** $(echo "$*" | to_upper) *****${plain}" >&2 + local msg + + if [ "$1" = false ]; then + shift + msg=$* + else + msg=$(echo "$*" | to_upper) + fi + + echo -e "${color}***** $msg *****${plain}" >&2 +} + +warn() { + color='\e[33m' + plain='\e[0m' + echo -e "${color}Warning: $*${plain}" >&2 } error_and_exit() { @@ -754,6 +769,10 @@ to_lower() { tr '[:upper:]' '[:lower:]' } +del_cr() { + sed 's/\r//g' +} + del_empty_lines() { sed '/^[[:space:]]*$/d' } @@ -4982,6 +5001,12 @@ get_filesize_mb() { du -m "$1" | awk '{print $1}' } +is_absolute_path() { + # 检查路径是否以/开头 + # 注意语法和 bash 不同 + [[ "$1" = "/*" ]] +} + install_windows() { get_wim_prop() { wim=$1 @@ -5188,11 +5213,11 @@ install_windows() { fi # 变量名 使用场景 - # arch_uname arch命令 / uname -m x86_64 aarch64 - # arch_wim wiminfo x86 x86_64 ARM64 - # arch virtio iso / unattend.xml x86 amd64 arm64 - # arch_xdd virtio msi / xen驱动 x86 x64 - # arch_dd 华为云驱动 32 64 + # arch_uname arch命令 / uname -m x86_64 aarch64 + # arch_wim wiminfo x86 x86_64 ARM64 + # arch virtio iso / unattend.xml / .inf x86 amd64 arm64 + # arch_xdd virtio msi / xen驱动 x86 x64 + # arch_dd 华为云驱动 32 64 # 将 wim 的 arch 转为驱动和应答文件的 arch case "$arch_wim" in @@ -5219,6 +5244,10 @@ install_windows() { drv=/os/drivers mkdir -p "$drv" # 驱动下载临时文件夹 + # 下载脚本 + # shellcheck disable=SC1090 + . <(wget -O- $confhome/windows-driver-utils.sh) + # 这里有坑 # $(get_cloud_vendor) 调用了 cache_dmi_and_virt # 但是 $(get_cloud_vendor) 运行在 subshell 里面 @@ -5647,13 +5676,10 @@ install_windows() { # 因此只能交给用户自己添加驱动 add_driver_custom() { - for dir in /custom_drivers/*; do - if [ -d "$dir" ]; then - info "Add custom drivers: $dir" - cp_drivers custom "$dir" - # 复制后不删除,因为脚本可能再次运行 - fi - done + if [ -d /custom_drivers/ ]; then + cp_drivers custom /custom_drivers/ + # 复制后不删除,因为脚本可能再次运行 + fi } # 修改应答文件 @@ -5718,21 +5744,20 @@ install_windows() { cp_drivers() { if [ "$1" = custom ]; then shift - dst="/wim/custom_drivers/$(basename "$1")" + dst="/wim/custom_drivers" else dst=/wim/drivers fi - mkdir -p "$dst" src=$1 shift - find $src \ - -type f \ - -not -iname "*.pdb" \ - -not -iname "dpinst.exe" \ - "$@" \ - -exec cp -rfv {} "$dst" \; + # -not -iname "*.pdb" \ + # -not -iname "dpinst.exe" \ + + find $src -type f -iname "*.inf" "$@" | while read -r inf; do + parse_inf_and_cp_driever "$inf" "$dst" "$arch" false + done } # 添加驱动 diff --git a/windows-driver-utils.sh b/windows-driver-utils.sh new file mode 100644 index 0000000..7d8501b --- /dev/null +++ b/windows-driver-utils.sh @@ -0,0 +1,278 @@ +#!/bin/ash +# shellcheck shell=dash +# shellcheck disable=SC3001,SC3010 +# reinstall.sh / trans.sh 共用此文件 + +del_inf_comment() { + sed 's/;.*//' +} + +simply_inf() { + del_cr | del_inf_comment | trim | del_empty_lines +} + +simply_inf_word() { + # 1 删除引号 " + # 2 删除两边空格 + # 3 \ 和 .\ 换成 / + # 4 连续的 / 替换成单个 / + # 5 删除最前面的 / + sed -E \ + -e 's,",,g' \ + -e 's/^[[:space:]]+//' -e 's/[[:space:]]+$//' \ + -e 's,\.?\\,/,g' \ + -e 's,/+,/,g' \ + -e 's,^/,,' +} + +# reinstall.sh 下无法判断 iso 是 32 位还是 64 位,此时 mix_x86_x86_64 为 true +# trans.sh 下可以判断 iso 是 32 位还是 64 位,此时 mix_x86_x86_64 为 false +list_files_from_inf() { + local inf=$1 + local arch=$2 # x86 amd64 arm64 + local mix_x86_x86_64=$3 + + # 所有字段不区分大小写 + inf_txts=$(simply_inf <"$inf" | to_lower) + + is_match_section() { + local section=$1 + + [ "$line" = "[$section]" ] || [ "$line" = "[$section.$arch]" ] || + { $mix_x86_x86_64 && [ "$arch" = x86 ] && [ "$line" = "[$section.amd64]" ]; } || + { $mix_x86_x86_64 && [ "$arch" = amd64 ] && [ "$line" = "[$section.x86]" ]; } + } + + is_match_catalogfile() { + local left + left=$(echo "$line" | awk -F= '{print $1}' | simply_inf_word) + + # catalogfile.nt 是指所有 nt ? + [ "$left" = "catalogfile" ] || + [ "$left" = "catalogfile.nt" ] || + [ "$left" = "catalogfile.nt$arch" ] || + { $mix_x86_x86_64 && [ "$arch" = x86 ] && [ "$left" = "catalogfile.ntamd64" ]; } || + { $mix_x86_x86_64 && [ "$arch" = amd64 ] && [ "$left" = "catalogfile.ntx86" ]; } + } + + is_match_manufacturer_arch() { + # x86 可写 NT / NTx86, 其它必须明确架构 + # https://learn.microsoft.com/en-us/windows-hardware/drivers/install/inf-manufacturer-section + case "$arch" in + x86) $mix_x86_x86_64 && regex='NT|NTx86|NTamd64' || regex='NT|NTx86' ;; + amd64) $mix_x86_x86_64 && regex='NT|NTx86|NTamd64' || regex='NTamd64' ;; + arm64) regex='NTarm64' ;; + esac + + # 注意 cut awk 结果不同 + # 虽然在这里不会造成影响 + # echo 1 | cut -d, -f2- + # 1 + # echo 1 | awk -F, '{print $2}' + # 空白 + + echo "$line" | awk -F, '{for(i=2;i<=NF;i++) print $i}' | grep -Eiwq "$regex" + } + + # 还需要从 [Strings] 读取字符串? + + # 0. 检测 inf 是否适合当前架构 + # 目前没有对比版本号 + + # 例子1 + # [Manufacturer] + # %Amazon% = AWSNVME, NTamd64, NTARM64 + + # 例子2 + # [Manufacturer] + # %MyName% = MyName,NTx86.6.0,NTx86.5.1, + # . + # [MyName.NTx86.6.0] ; Empty section, so this INF does not support + # . ; NT 6.0 and later. + # . + # [MyName.NTx86.5.1] ; Used for NT 5.1 and later + # . ; (but not NT 6.0 and later due to the NTx86.6.0 entry) + # %MyDev% = InstallB,hwid + # . + # [MyName] ; Empty section, so this INF does not support + # . ; Win2000 + # . + + # 例子3 + # 系统自带的驱动,没有 [Manufacturer] + + # 例子4 + # C:\Windows\INF\wfcvsc.inf + # %StdMfg%=Standard,NTamd64...0x0000001,NTamd64...0x0000002,NTamd64...0x0000003 + + in_section=false + arch_matched=false + has_manufacturer=false + # 未添加 IFS= 时,read 会删除行首行尾的空白字符 + while read -r line; do + if [[ "$line" = "["* ]]; then + is_match_section manufacturer && has_manufacturer=true && in_section=true || in_section=false + continue + fi + + if $in_section; then + if is_match_manufacturer_arch; then + arch_matched=true + break + fi + fi + done < <(echo "$inf_txts") + + if $has_manufacturer && ! $arch_matched; then + return 10 + fi + + # 1. 输出 .inf 文件名 + basename "$inf" + + # 2. 输出 .cat 相对路径 + # 例子 + # [version] + # CatalogFile = "xxxxx.cat" + # CatalogFile.NTAMD64=Balloon.cat + in_section=false + # 未添加 IFS= 时,read 会删除行首行尾的空白字符 + while read -r line; do + if [[ "$line" = "["* ]]; then + is_match_section version && in_section=true || in_section=false + continue + fi + + if $in_section && is_match_catalogfile; then + echo "$line" | awk -F= '{print $2}' | simply_inf_word + fi + done < <(echo "$inf_txts") + + # 3. 获取 SourceDisksNames + # 例子 + # [SourceDisksNames] + # 1 = "Windows NT CD-ROM",file.tag,, "\common" + SourceDisksNames= + in_section=false + # 未添加 IFS= 时,read 会删除行首行尾的空白字符 + while read -r line; do + if [[ "$line" = "["* ]]; then + is_match_section sourcedisksnames && in_section=true || in_section=false + continue + fi + # 注意可能有空格和引号 + + if $in_section; then + num=$(echo "$line" | awk -F= '{print $1}' | simply_inf_word) + dir=$(echo "$line" | awk -F, '{print $4}' | simply_inf_word) + # 每行一条记录 + if [ -n "$SourceDisksNames" ]; then + SourceDisksNames="$SourceDisksNames +" + fi + SourceDisksNames="$SourceDisksNames$num:$dir" + fi + done < <(echo "$inf_txts") + + # 4. 打印 SourceDisksFiles 的绝对路径 + # 例子 + # [SourceDisksFiles] + # aha154x.sys = 1 , "\x86" ,, + in_section=false + # 未添加 IFS= 时,read 会删除行首行尾的空白字符 + while read -r line; do + if [[ "$line" = "["* ]]; then + is_match_section sourcedisksfiles && in_section=true || in_section=false + continue + fi + + if $in_section; then + file=$(echo "$line" | awk -F= '{print $1}' | simply_inf_word) + num=$(echo "$line" | awk -F'=|,' '{print $2}' | simply_inf_word) + sub_dir=$(echo "$line" | awk -F, '{print $2}' | simply_inf_word) + # 可能有多个 + while IFS= read -r parent_dir; do + echo "$parent_dir/$sub_dir/$file" | simply_inf_word + done < <(echo "$SourceDisksNames" | awk -F: "\$1==\"$num\" {print \$2}") + fi + done < <(echo "$inf_txts") +} + +find_file_ignore_case() { + # 同时支持参数和管道 + local path + path=$({ if [ -n "$1" ]; then echo "$1"; else cat; fi; }) + + # 用 / 分割路径,提取成列表 + # 例如: ///a///b/c.inf -> a b c.inf + # shellcheck disable=SC2046 + set -- $(echo "$path" | grep -o '[^/]*') + ( + # windows 安装驱动时,只会安装相同架构的驱动文件到系统,即使 inf 里有列出其它架构的驱动 + # 因此导出驱动时,也就不会包含其它架构的驱动文件 + # 因此这里只警告,不中断脚本 + + local output= + if is_absolute_path "$path"; then + cd / + output=/ + fi + + while [ $# -gt 0 ]; do + local part=$1 + # shellcheck disable=SC2010 + if part=$(ls -1 | grep -Fix "$part"); then + # 大于 1 表示当前 part 是目录 + if [ $# -gt 1 ]; then + if cd "$part"; then + output="$output$part/" + else + warn "Can't cd $path" + return 1 + fi + else + # 最后 part + output="$output$part" + fi + else + warn "Can't find $path" >&2 + return 1 + fi + shift + done + echo "$output" + ) +} + +parse_inf_and_cp_driever() { + local inf=$1 + local dst=$2 + local arch=$3 + local mix_x86_x86_64=$4 + + info false "Add driver: $inf" + + # 首先创建目录,否则无法通过 ls 文件数得到编号 + mkdir -p "$dst" + # shellcheck disable=SC2012 + inf_index=$(($(ls -1 "$dst" | wc -l) + 1)) + inf_old_dir=$(dirname "$inf") + inf_new_dir=$dst/$inf_index + if driver_files=$(list_files_from_inf "$inf" "$arch" "$mix_x86_x86_64"); then + mkdir -p "$inf_new_dir" + ( + cd "$inf_old_dir" || error_and_exit "Can't cd $inf_old_dir" + while read -r file; do + if file=$(find_file_ignore_case "$file"); then + cp -v --parents "$file" "$inf_new_dir" + fi + done < <(echo "$driver_files") + ) + else + if [ $? -eq 10 ]; then + warn "$inf arch not match." + else + error_and_exit "Unknown error while parse $inf." + fi + fi +} diff --git a/windows-setup.bat b/windows-setup.bat index d2a965a..f001b4f 100644 --- a/windows-setup.bat +++ b/windows-setup.bat @@ -22,15 +22,26 @@ rem win8 pe 没有 powercfg call powercfg /s 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c 2>nul rem 安装 SCSI 驱动 -for %%F in ("X:\drivers\*.inf") do ( - call :drvload_if_scsi "%%~F" +if exist X:\drivers\ ( + for /f "delims=" %%F in ('dir /s /b "X:\drivers\*.inf" 2^>nul') do ( + call :drvload_if_scsi "%%~F" + ) + + rem 官网写了可以安装但仅会加载关键驱动 + rem Gcore 的 virtio-gpu 在安装时没有显示 + rem 即使安装时加载了显卡驱动 + rem 进入系统后才有显示 + rem find /i "viogpudo" "%%~F" >nul + rem if not errorlevel 1 ( + rem drvload "%%~F" + rem ) ) rem 安装自定义 SCSI 驱动 rem 可以用 forfiles /p X:\custom_drivers /m *.inf /c "cmd /c echo @path" rem 不可以用 for %%F in ("X:\custom_drivers\*\*.inf") if exist X:\custom_drivers\ ( - for /f "delims=" %%F in ('dir /s /b "X:\custom_drivers\*.inf"') do ( + for /f "delims=" %%F in ('dir /s /b "X:\custom_drivers\*.inf" 2^>nul') do ( call :drvload_if_scsi "%%~F" ) )