Windows 11でWindows Updateによる勝手な更新を停める (前編)

Windows 10でもWindows 11でもWindows Updateは非常に邪魔。裏で勝手に更新の有無をチェックして更新作業を始めるのもユーザーが気付かない程度におとなしくやってくれるなら正直全然構わないのだが、Windowsのはとにかくユーザー側の操作が邪魔されるくらいリソース激減でディスクアクセスも派手に行われる。特に貧弱なスペックのPCほどその「圧倒的邪魔」っぷりを実感しやすいかと。

以前はさらに更新作業の過程でほぼ強制的に再起動がかかったりで進行中のユーザーの仕事がメチャクチャにされたこともあったが、それはさすがに非難轟々だったので再起動の先送りができるようになった(みたい)。
幕の途中で舞台の見えるところで美術さんが次の舞台セットの用意を始めたり、役者がまだセリフを喋っているのに時間だからと幕を降ろし始める舞台さん、役者が隅の方に追いやられ舞台スタッフが中央でカーテンコールに応える、そんな舞台イヤだよね。でも、それがWindows。全く裏方としてのOSの分をわきまえていない。

ということで、「Windows Updateを停めたい」というのがこの記事。
ただし、OSを最新状態に保つことは重要なので、決して「Windowsで金輪際更新しないようにしましょう」というものではないので念の為。
あくまでもユーザーが望まないときの勝手な更新をさせないというもの。つまり自身で積極的に更新を行う人向け。
この記事ではWindows 11でやってるけどここ最近のWindows 10も同じ筈。

Windows Updateを停める 1
なんかPCが異常に重くてまともに使えないってなって、確認すると勝手に更新チェックとかダウンロードとか始まってるのフザケンナ。

Windows Updateサービスの停止

Windows Updateを停める 2
スタートボタンを左クリックしてスタートメニュー上部の検索テキストボックスに入力。おそらく文字を入力しようとすると次の画面に切り替わる。

Windows Updateを停める 3
英語で service 、または日本語で サービス と入力する。
すぐに下に検索結果が出るので、「サービス」アプリを選択して「開く」をクリック。ここでは特に「管理者として実行」である必要はない。

Windowsベテランの人は上のようなまどろっこしいのではなく[Win]+[R]から「services.msc」でどうぞ

Windows Updateを停める 4
「サービス」が起動したら縦スクロールして「Windows Update」の行を見つける。おそらく「実行中」になっている筈。実行中とはいっても今何か処理中ということではなく「起動済み」とか「常駐中」とかそんな感じ。

Windows Updateを停める 5
「Windows Update」の行で右クリックして「停止」を選択。

Windows Updateを停める 6
Windows Updateの行の「状態」が「実行中」が消えて空白に変わる。つまり「停止」になった。

Windows Updateを停める 7
再び「Windows Update」の行で右クリックして今度は「プロパティ」を選択。

Windows Updateを停める 8
プロパティ窓の左上の「全般」タブの選択状態(最初から選択されて筈)で、「スタートアップの種類」のドロップダウンメニューから「無効」を選択。
右下の「適用」ボタンと「OK」をクリック。

Windows Updateを停める 9
Windows Updateの行のスタートアップの種類が「無効」になった。

Windows Updateを停める 7
さらにもう一度「Windows Update」の行で右クリックして再び「プロパティ」を選択。

Windows Updateを停める 10
プロパティ窓上部の「回復」タブを選択。
「最初のエラー」が初期値では「サービスを再起動する」になっている筈なので「何もしない」に変更する。
右下の「適用」ボタンと「OK」をクリック。

基本的には、これでWindows Updateサービスが停まって「無効化」されたので勝手に更新しないようになった筈だが、実際にはいつのまにかWindows Updateサービスが有効化され勝手に実行中の状態になる。それは関連サービスや関連バッチによるもの。つまりそれらを停めなければ再びWindows Updateが動き出すことになるということ。(以下)

Windows Update Medic Serviceサービスの停止

先ずは停めるべきはここまでで操作してきたWindows Updateサービスのすぐ下にあった「Windows Update Medic Service」。これはWindows Updateの正常な状態を保つためのサービス。
ところが、この「Windows Update Medic Service」はWindows Updateサービスのように生易しくない。

Windows Updateを停める 11
「Windows Update Medic Service」をWindows Updateや他のサービスと同様にコントロールしようとしても「アクセスが拒否されました」になってしまう。これは管理者権限でコマンドでサービスコントロールを行おうとしても、普通に使える最高権限のシステムアカウントであっても全て拒否されるので操作できないサービスらしい。
そこで・・・(以下)

Windows Updateを停める 12
この記事の最初の方の手順と同じスタートボタンからアプリケーションを検索する方法で「レジストリ」でレジストリエディタを開くか、または[Win]+[R]で「ファイル名を指定して実行」の小窓に「regedit」を入力して[OK]でレジストリエディタを開く。

Windows Updateを停める 13
レジストリエディタの左列でツリー構造の「HKEY_LOCAL_MACHINE」→「SYSTEM」→「CurrentControlSet」→「Services」→「WaaSMedicSvc」を辿る。
「WaaSMedicSvc」を左クリックすると右列にそのサービスに関連するレジストリがいくつか表示される。
コンピュータ\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WaaSMedicSvc であることをしっかり確認する。
「Start」の行を見つける。StartのDWORDは初期値が3の筈。 (上の画像では既に4になっているが)
「Start」を左ダブルクリックする。

Windows Updateを停める 14
DWORD編集画面になるので値を3から4に変更する。
「OK」ボタンをクリック。

Windows Updateを停める 15
再び、「サービス」を表示すると例の「Windows Update Medic Service」の「スタートアップの種類」が無効になっている。

既に知っている人なら当たり前、そうでなくても勘が良い人ならもうここで気付いたかもしれないが、サービスの制御ってほとんどレジストリエディタの\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Servicesで操作できるのよね。

めでたし、めでたし。とはいかないんだな、これが。
長くなりすぎるので関連タスクの停止は次記事で。

ESP32マイコンボードとMAX7219 LEDディスプレイ4連x2でNTPクロックを作ってみた

NTPクロックを作ってみた。

電波時計が自動的に時刻合わせをしてくれないので正確な時刻を表示する時計が欲しくなったというのは前の記事で書いた。
で、Arduino互換のマイコンカードと8x8のLEDマトリクスディスプレイが4つ繋がったものを2つ買ってそれを接続して表示できるうになったというのも書いた。マイコンボードでNTP時刻合わせをするというのも書いた。
今回は、NTPで正しい時刻を取得してその時刻をLDEディスプレイに表示する。つまり元々の目的のものを作る。

普通に日付と時刻を表示しようとしたらディスプレイの表示範囲を超過してしまった
MAX7219 LEDディスプレイモジュールは4連を2個。元々の予定では4連を2つ重ね(2行)にするつもりでいたが、時刻表示(HH:MM:SS)を4連1枚に表示するのは難しいことがわかったので 4連を並べて8連(1行)にした。4連にHH:MM:SSを表示しようと思ったらかなり細いフォントを使うか縮小フォントを使うかになるけど1モジュールが8x8のLEDディスプレイなので細い字にするのも限界がある。読みやすさを犠牲にするのはイヤなので。
ちなみに、工夫なしに普通に日付と時刻を表示しようとしたら表示範囲に収まりきらずに秒の表示が切れてしまった。

何をどのように表示するかを考えた。

  • 時刻は秒まで表示する。HH:MM:SS形式で、これは絶対。
  • 時刻は常時表示にしたい。
  • 日付も表示したい。
  • 曜日も表示したい。
  • 西暦の年も表示したい。できたら4桁で。
  • 他の情報は要らない。

以上から、時刻(HH:MM:SS)を常時表示するエリアと日付のゾーン(エリア)に2分割する。
時刻のゾーンは固定表示。
「年」、「月/日」、「曜日(英字3文字)」を縦スクロールで上下移動して表示。そして、月/日の表示回数が多くてかつ表示時間を長めにする。
年 → 月/日 → 曜日 → 月/日 → 年 のような繰り返し。

ゾーン分割とアニメーションの表示方法についてはMD_Parolaライブラリに付属のスケッチ例からParola_Zone_TimeMsgを参考にした。

モジュール並びとゾーン分け
2021年10月18日: モジュールの並びとゾーン分けについて、↓の2段落分の説明がヘタクソで書いた本人もなんかよく判らんかったのでこの画像を追加

LEDモジュールは8x8の単体タイプを並べようが4連タイプを並べようが、右から左に制御するモジュール番号が付く。つまり7 6 5 4 3 2 1 0のようになる。
ゾーンを分割すると右からゾーン0、その左にゾーン1・・・のように並ぶ。つまり、モジュールもゾーンも右から左に並ぶ。英数字は左から右に書くので感覚としては逆並び。

時刻表示部分は、HH:MM:SSの8文字、日付側は年表示がYYYYで4文字、月日表示はMM/DDの5文字、曜日は英語の短縮形3文字とする。つまり時刻表示の方が文字数が多いので日付表示と時刻表示の表示範囲を1:1ではなく3:5で分割して表示することにした。4連モジュール2個を使うので4連を上下に並べる(4列x2行)表示はこの時点でムリということになった。
3:5と書いたが、モジュールとゾーンは右から左に0から数字が付くのでモジュール 7, 6, 5 がゾーン1でモジュール4 3, 2, 1, 0 がゾーン0になる。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include <NTPClient.h>
#include <WiFi.h>
#include <WiFiUdp.h>
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#include "GF4x8p.h"  // 4x8 font

//Wi-Fi
#define SSID "Wi-Fi-SSID"
#define WIFIKEY "WI-FI-PASSWORD"

//NTP client
#define ntpServer "NTP Server" //Host name or IP Address
#define tzOffset 32400     // JST = 3600 * 9

//MAX7219
#define MAX_DEVICES 8 // eight modules
#define CLK_PIN   27
#define DATA_PIN  12
#define CS_PIN    14

#define SPEED_TIME  25  //Small numbers are faster. Zero is the fastest.
#define PAUSE_TIME_L  1200 //1200ms for month/day long pause
#define PAUSE_TIME_S  300 //300ms for month/day short pause

#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
// Hardware SPI connection
//MD_Parola P = MD_Parola(CS_PIN, MAX_DEVICES);
MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, ntpServer, tzOffset, 3540000); //59 minutes : 59(min) x 60(sec) x 1000(ms) = 3540000


void setup() {
  WiFi.begin(SSID, WIFIKEY);

  while ( WiFi.status() != WL_CONNECTED ) {
    delay ( 500 );
  }

  timeClient.begin();

  P.begin(2); // 2 zones
  P.setZone(0, 0, 4);  //00011111 <- Zone 0  for Time display
  P.setZone(1, 5, 7);  //11100000 <- Zone 1  for Date display
  P.setFont(0,GF4x8p);
  P.setFont(1,GF4x8p);
  P.setIntensity(0);  //Darkest
}

void loop() {

  time_t epTime = timeClient.getEpochTime();
  static uint8_t  dsw = 0;
  struct tm  ts;
  char bufD[15], bufT[9]; // "yyyy mm/dd aaa" + 1 = 15,  "hh:mm:ss" + 1 = 9   
  char *parr[15];
  ts = *localtime(&epTime);

  timeClient.update();

  P.displayAnimate();

  //Zone 1 Date
  if (P.getZoneStatus(1)) {
    strftime(bufD, sizeof(bufD), "%Y %m/%d %a", &ts);
    parr[0] = strtok(bufD, " "); // year
    parr[1] = strtok(NULL, " "); // month/day
    parr[2] = strtok(NULL, " "); // day of the week

    switch (dsw) {
      case 0: // month/day down
        P.displayZoneText(1, parr[1], PA_CENTER, SPEED_TIME, 0, PA_NO_EFFECT, PA_SCROLL_DOWN);
        dsw++;
        break;
      case 1: // year down
        P.displayZoneText(1, parr[0], PA_CENTER, SPEED_TIME, 0, PA_SCROLL_DOWN, PA_NO_EFFECT);
        P.setPause(1, PAUSE_TIME_S);
        dsw++;
        break;
      case 2: // year up
        P.displayZoneText(1, parr[0], PA_CENTER, SPEED_TIME, 0, PA_NO_EFFECT, PA_SCROLL_UP);
        dsw++;
        break;
      case 3: // month/day up
        P.displayZoneText(1, parr[1], PA_CENTER, SPEED_TIME, 0, PA_SCROLL_UP, PA_NO_EFFECT);
        P.setPause(1, PAUSE_TIME_L);
        dsw++;
        break;
      case 4: // month/day up
        P.displayZoneText(1, parr[1], PA_CENTER, SPEED_TIME, 0, PA_NO_EFFECT, PA_SCROLL_UP);
        dsw++;
        break;
      case 5: // day of the week up
        P.displayZoneText(1, parr[2], PA_CENTER, SPEED_TIME, 0, PA_SCROLL_UP, PA_NO_EFFECT);
        P.setPause(1, PAUSE_TIME_S);
        dsw++;
        break;
      case 6: // day of the week down
        P.displayZoneText(1, parr[2], PA_CENTER, SPEED_TIME, 0, PA_NO_EFFECT, PA_SCROLL_DOWN);
        dsw++;
        break;
      case 7: // month/day  up
        P.displayZoneText(1, parr[1], PA_CENTER, SPEED_TIME, 0, PA_SCROLL_DOWN, PA_NO_EFFECT);
        P.setPause(1, PAUSE_TIME_L);
        dsw = 0;
        break;
      default:
        break;
    }
    P.displayReset(1);
  }

  //Zone 0 Time
  if (P.getZoneStatus(0)) {
    strftime(bufT, sizeof(bufT), "%T", &ts); // %T: hh:mm:ss
    P.displayZoneText(0, bufT, PA_CENTER, SPEED_TIME, 0, PA_PRINT, PA_NO_EFFECT);
    P.displayReset(0);
  }

  delay(50); //Don't remove this delay, and don't make it too small
}

void loop(){} の中はひたすらループ処理が行われるが、P.getZoneStatus(#Zone)が1でなければそのゾーンのアニメーションの制御はループに邪魔されず(実際は多少邪魔される)に進行する。逆に言えばアニメーションの動作が完了してP.getZoneStatus(#Zone)が1になるまでアニメーションの処理に邪魔されず(実際は多少邪魔される)にループが進行するのでアタマがこんがらかるような余計なことを考えなくて済むのでとてもラク。
void loop(){}の最後にディレイを入れているが、値(ミリ秒)が小さすぎるとループ処理が速く行われすぎて動作異常になると思われる。ただし大きすぎても今度は動作が遅くなったり処理開始のタイミングが狂うかもしれないので適度な大きさの数値にする。50msより少し小さい程度?

今回は狭い表示範囲に文字を詰め込むため専用にフォントを作成した。時計の表示は時・分・秒が変わる度に表示位置がガタガタ変わるのはイヤなので数字は4ドットの固定幅(英字も)で数字は4x8の大きめにし、記号は幅を最小限に1〜3ドット(列)の可変幅というハイブリッド型プロポーショナルフォントにした。
ゼロはアルファベットのOと区別がしやすいよう斜線付きタイプにしたが敢えて超少数派の逆斜線にしてみた。(Øと斜線の向きが逆)
一応、フォントのリンクを貼っておくのでダウンロードできます。

GF4x8p.h

まぁ素敵なフォントを作ってやろうという意欲はあるんだけど、残念ながらデザインセンスと実力がからっきし無いので字の見た目が残念かもしれない。もっと良いのが欲しいという人は自分で作っていただければ。 で、ダウンロードしたフォントのファイルをスケッチと同じディレクトリに置く。上の例ではファイル名が GF4x8p.h でフォント名が GF4x8p 。つまり、スケッチの最初の方で#include "GF4x8p.h" と指定してやればそのフォントがインクルードされ、P.setFont(0,GF4x8p);のように指定することで0番ゾーンでそのフォントが使われる(P.setFont(1,GF4x8p);なら1番ゾーン)。なのでゾーン単位でフォントを使い分けることができる。

予定通りに日付と時刻がきれいに表示されるようになった
日付、時刻ともにそれぞれのゾーンの中で中央寄せ。日付表示は8x8 LEDディスプレイ3モジュール分のゾーンなので5文字表示の「月/日」ではカツカツだが、時刻ゾーンは左右の端に余裕がある感じ。

関連記事:

Windows 11のシステム要件を満たさないPCでWindows10からWindows11にアップグレード

これまでシステム要件を満たさないPCでWindows 11をインストールする記事を幾つか書いたが、Windows 10などからWindows 11にアップグレードするというのは書いていなかった。「がとらぼ」の中のは人はクリーンインストール派なのでOSのメジャーバージョンが変わるときに古いバージョンから更新というのは考えに入っていないから。
なので先日公開したWindows 11インストールメディアでレジストリを変更してインストールする方法で、途中のメニューの「アップグレード」を選択すれば「インストール」と同様にWindows 11が入るものだと思っていた。でも、指摘されて確認したらインストールメディアで起動した場合はアップグレードできない。ならメニュー表示するなよ💢、そういうところMicrosoftさんダメだよね。

そうなるとMicrosoftが先日公表したレジストリを使って更新することになるかと思うが、実際のところは「TPM 2.0はカンベンしてやるけどTPM 1.2は必要ね」という嫌がらせになっている。古いPCは結構多く動いている筈で、TPM 1.2どころかTPMってなんじゃらほいというPCも多く残っていると思う。このようなPCではWindows 10のサポート期間中はWindows 10を使って、その内にWindows 11のシステム要件を満たすPCを買ってねということなのだろうが、そういうのが気に食わない。そこで、例によってWindows 11のシステム要件を満たさないWindows 10のPCをWindowsにアップグレードする。今回もISOファイルの改造は行わない。ただし、起動しているWindows 10からのアップグレードは以前に「がとらぼ」で紹介したレジストリでもシステム要件チェック回避はできないようなので別の方法で。

システム要件を満たさないPCでWindows 11にアップグレード 1
今回用意したPCはまたもやSandy Bridge世代、でもCeleron B820を搭載したノートPCではなくcore i3を搭載したデスクトップPC。マザーボードが悪くなっているのかプチフリ連発で使い物にならなくて押入れの肥やしになっていたのを引きずり出してきた。Windows 10が入っていたので最新状態まで更新したが、元が不調機なので更新に24時間以上の時間がかかり、Windows 10をクリーンインストールした方が早かったと後悔。

システム要件を満たさないPCでWindows 11にアップグレード 2
一応、PC正常性チェックでWindows 11システム要件を満たしているか確認。もちろん満たしていない。
特にTPMについてはMicrosoftが提供しているレジストリでも救済できないTPM 1.2未満。というか、このPCはそもそもTPMなんてものに全く対応していない。
なのでこの記事的には好都合。

システム要件を満たさないPCでWindows 11にアップグレード 3
Windows 11のISOファイルをDVD-DLに焼いたものをDVDドライブにセットした。今回はDVDだが、USBメモリでも問題ない筈。

システム要件を満たさないPCでWindows 11にアップグレード 4
Windows 11インストールメディアのドライブを開き、setup.exeを実行する。(拡張子表示していないならsetup)

システム要件を満たさないPCでWindows 11にアップグレード 5
Windows 11のインストーラーが起動する。この画面のまま「次へ」ボタンを押さないで次の説明に進む。

システム要件を満たさないPCでWindows 11にアップグレード 6
開いている窓は1つ前の画像と同じ。
普通はここで何も考えないで右下の「次へ」を押すと思うが、この時点では押さない。ここで先に「セットアップでの更新プログラムのダウンロード方法の変更」をクリック。これがキモ。

システム要件を満たさないPCでWindows 11にアップグレード 7
「今は実行しない」を選択。(重要)
「次へ」をクリック。

システム要件を満たさないPCでWindows 11にアップグレード 8
この画面に戻るかどうかは記憶がアヤフヤだが、この画面になったら今度は右下の「次へ」をクリック。 この画面が出なければ次へ。

システム要件を満たさないPCでWindows 11にアップグレード 9
システム要件のチェックが行われ「このPCは現在Windows 11のシステム要件を満たしていません」の表示が出る。
それで構わないので「ダメじゃん」と諦めずに次へ。

システム要件を満たさないPCでWindows 11にアップグレード 10
ここで、Windows 11インストーラーは閉じずにそのままにして、いったん離れる。
[Win]+[E]でも何でも良いのでエクスプローラーを起動し、Cドライブを開く。

システム要件を満たさないPCでWindows 11にアップグレード 11
エクスプローラー上部のタブで「表示」を選択。
隠しファイルのチェックボックスをチェック。(ついでにファイル名拡張子のチェックボックスも)
ファイルリストに隠しファイルや隠しディレクトリが表示されるので「$WINDOWS.~BT」隠しディレクトリをクリックして開く。($Windows.~WSではない)
さらにその下のSourcesディレクトリに進む。

システム要件を満たさないPCでWindows 11にアップグレード 12
現在のPathが C:\WINDOWS.~BT\Sources であることを確認する。
ファイルの多いディレクトリなので少し下にスクロールして、appraiserres.dllを見つける。似た名前のファイルがあるので間違えないようしっかり確認してからそのファイルを削除する。管理者権限での削除になるので確認を求められるがもちろん承認。
appraiserres.dllを削除したらエクスプローラーを閉じる。
なお、このC:\WINDOWS.~BTというディレクトリはWindows 11インストーラーが一時的に作ったものなのでappraiserres.dllファイルの削除は躊躇しなくて大丈夫。

システム要件を満たさないPCでWindows 11にアップグレード 13
Windows 11のインストーラーに戻る。
ここで、「戻る」ボタンを押す。(ここに普通は無い筈の「戻る」ボタンがあるというのが重要。少し前の方でやったことによるもの。)

システム要件を満たさないPCでWindows 11にアップグレード 14
前の画面に戻ったところで再び「次へ」ボタンをクリック。
戻ったり進んだり無駄なことをしてそうに思うかもだが意味がある。
ここで、戻って進んだなら再びシステム要件チェックが行われて「このPCは現在Windows 11のシステム要件を満たしていません」が出るかと思いきや、それがスキップされて次に進む。

システム要件を満たさないPCでWindows 11にアップグレード 15
ライセンス条項をよく読んで自己責任で同意してください。
また、今回は単にライセンス条項に同意するだけでなく、システム要件を満たさないPCに無理やりWindows 11を入れるリスクも認識してください。Windows 11にすることで今後発生する不具合やトラブル、損害の発生については「がとらぼ」では全く責任を負えませんので念の為。

システム要件を満たさないPCでWindows 11にアップグレード 16
鉄郎、この画面が最後の機会よ。そこを過ぎたら二度と引き返せないわ。決してね。
「インストール」を押すとWindows 10とは「さよなら」です。

システム要件を満たさないPCでWindows 11にアップグレード 17
数時間後。
Windows 11になりました。今回はWindows 10からのアップグレードなので壁紙はWindows 10のときのままです。他にもWindows 10時代の名残がそこかしこに。

システム要件を満たさないPCでWindows 11にアップグレード 18
バージョンを確認するとWindows 11のOSビルド22000.194になったことを確認できた。

appraiserres.dllがシステム要件のチェックに関わっているので削除すれば要件チェックをスキップできそうというのはWindows 11の最初のプレビューが漏洩?したころから言われていたが、それを削除したことでインストーラーが停まってしまうのでは本末転倒。そこでインストーラーが停まらないでappraiserres.dllを削除してシステム要件チェックによるインストーラー強制終了も避けることがも可能なのが上の手順。

関連記事: