saber 酱的抱枕

Fly me to the moon

03/16
2016
软件

关于Win7离线补丁的安装

如果有安装win7离线补丁的经历,应该都会认为一开始那个“正在此计算机上搜索更新”慢得令人发指吧。

尤其是每个都要跑一遍。

那么怎么办!?

方法零:永远不要打补丁

方法零点五:永远不要离线打补丁,都交给windows update在线打

方法一:永远不要用windows update检查更新。只要你没有检查过,就没有这个问题
但是那样怎么知道要打哪些啊!
不过倒是挺适用于事先确定了列表要制作集成镜像的情况。

方法二:利用其他工具(仍然是windows自带的工具)安装。我才不会承认我是看到数字君的一个专利才想起来的

当然其他现成的工具,比如dim++都行。

我自己则是解包msu,然后用dism安装补丁。
为了方便,自己用c++写了个生成批处理的程序。代码见下。我的编译平台是vs 2015
我当然知道c++其实并不适合……但我只会这个233

使用方法:首先利用dir命令生成待安装补丁的路径列表
示例:
dir "%~dp0patch" /s /b >"%~dp0list.txt"
上面是将当前文件夹(即%~dp0)下的patch文件夹里的所有文件路径生成到当前文件夹里的list.txt中(自动创建)
然后将list.txt(不要改名!)与exe放在一起,运行exe后会生成(替代原有文件)wusa.bat及dism.bat。依次运行即可。
当然这会在补丁文件夹里生成临时文件的文件夹。
补丁数量上限定义在N了,当前是50

#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
using namespace std;
#define N 50
int main()
{
 cout << "请将dir命令生成的list.txt与本程序置于同一目录" << endl;
 system("pause");
 int i, j, k;
 string patch_path[N], dir[N], patch_name[N];
 const string wusa1 = "wusa.exe ", wusa2 = " /extract:";
 const string dism1 = "dism /online /add-package", dism2 = " /PackagePath:";
 ifstream list;
 ofstream wusa, dism;
 list.open("list.txt", ios::in);
 if (!list)
 {
  cout << "文件读取出错" << endl;
  system("pause");
  return 0;
 }
 for (i = 0; !list.eof(); i++)
 {
  getline(list, patch_path[i]);
 }
 list.close();
 for (j = i - 1; j >= 0; j--)
 {
  if (patch_path[j].length()<1)
   i--;
 }//验证文件最后是否有空行
 for (j = 0; j < i; j++)
 {
  dir[j] = patch_path[j];
  patch_name[j] = patch_path[j];
 }
 for (j = 0; j < i; j++)//去除.msu
 {
  dir[j].pop_back();
  dir[j].pop_back();
  dir[j].pop_back();
  dir[j].pop_back();
 }
 for (j = 0; j < i; j++)
  for (k = patch_name[j].length() - 1; k > 0; k--)
  {
   if (patch_name[j][k] == '\\')
   {
    patch_name[j].erase(0, k);//清除最后一个反斜杠(不含本身)之前的
    patch_name[j].pop_back();
    patch_name[j].pop_back();
    patch_name[j].pop_back();//去除msu但保留.
   }
  }
 wusa.open("wusa.bat", ios::out | ios::trunc);
 if (!wusa)
 {
  cout << "文件1创建出错" << endl;
  system("pause");
  return 0;
 }
 for (j = 0; j < i; j++)
 {
  wusa << wusa1 + '"' + patch_path[j] + '"' + wusa2 + '"' + dir[j] + '"' << endl;
  if (wusa.bad())
  {
   cout << "文件1写入出错" << endl;
   system("pause");
   return 0;
  }
 }
 wusa << "@echo off" << endl << "pause";
 wusa.close();
 dism.open("dism.bat", ios::out | ios::trunc);
 if (!dism)
 {
  cout << "文件2创建出错" << endl;
  system("pause");
  return 0;
 }
 dism << "@echo off" << endl << "echo 请自行确定是否是右键以管理员身份运行该批处理" << endl << "echo 若否,请重新以管理员身份运行" << endl << "pause" << endl << "@echo on" << endl;
 dism << dism1;
 for (j = 0; j < i; j++)
 {
  dism << dism2 + '"' + dir[j] + patch_name[j] + "cab" + '"';
  if (dism.bad())
  {
   cout << "文件2写入出错" << endl;
   system("pause");
   return 0;
  }
 }
 dism << " /norestart" << endl << "@echo off" << endl << "pause";
 dism.close();
 cout << "生成成功" << endl;
 system("pause");
}

关于Win7离线补丁的安装