2019年1月12日土曜日

The Guild II:Renaissance + MegaModPack 0.95用日本語化

あけましておめでとうございます。
なんでいまさらThe Guild II:Renaissance + MegaModPack 0.95なのか。
それは、以前0.8用の翻訳に手を付けてしまったからです。。。
自業自得です。
そういえば0.8用の翻訳も正月早々にやったんでした。

で、超めんどくせーと思いながらMegaModPack 0.82とMegaModPack 0.95の追加・変更されたテキストを翻訳してみることにしました。

とりあえず差分を比較してみた結果、追加607件、変更221件、削除72件、合計900件もの変更がありました・・・

結局翻訳は手動でやるしかないわけで、追加変更分を涙目になりながら翻訳シートを埋めてみたのがこちらです。ま、ほとんど機械翻訳なんですけどね。
後期中年者から初期老齢者の境目になるとコピペ900回とかかなりツラい。
Weblioさん、Google Translateさん、いつもありがとうございます。
Google Translateさん、奇妙な造語をするクセ、なんとかしてください。

しっかし、あれですな。
久しぶりにシートを眺めると、機械翻訳のままのところ、本当にひどい。
以前からわかっちゃいるけど、訳文、18,000行くらいあるしね。一人じゃ無理だし、そもそも全然需要がないからいいよね。

で、成果物はこちら0.82用との絡みでファイル名をText095.dbtに変えてあります。ダウンロードしたらText.dbtにリネームして使ってください。
ついでに、気に入らない翻訳があったら是非直すのにご協力いただければ幸甚です・・・まぁねえよな

そんなわけで本年もよろしくお願いいたします。


おまけ:
シートから直接dbtを作るスクリプト
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
#!/usr/bin/env python3
 
#
# MegaModPack0.95用翻訳「元」シートから0.095用のText.dbt を生成するpython3 script.
# input:
#       1. 0.95用シートのtsv
#          tg2tsv_095.tsv
# output:
#       0.95用のText.dbt
#           Text095.dbt
#
 
import re
 
def make_dbt():
  regpattern = r"^\"*(\d+)\"*\t\"*(.*)\"*\t\"*(.*)\"*\t\"*(.*)\"*\t\"*(.*)\"*\t\"*(.*)\"*\t\"*(.*)\"*\t\"*(.*)\"*\r*\n$"
  reg = re.compile( regpattern )
   
  with open( r"tg2tsv_095.tsv", "r", encoding="utf-8" ) as fin:
    dic = dict()
    for line in fin:
      m = reg.match( line )
      if not m :
        continue
      index = m.group(1)
      id = m.group(2)
      en082 = m.group(3)
      ja082 = m.group(4)
      vanilla = m.group(5)
      en095 = m.group(6)
      ja095 = m.group(7)
      type= m.group(8)
      if ja095 == "" and en095 != "" :
        raise TypeError('Japanese translation is not completed!!')
      dic[ int(index) ]  = [ index , id, ja095 ]
 
  keys =  sorted(dic.keys())
  isfirst = True
  with open( r"Text095.dbt", "w", encoding="utf-16" ) as fout:
    for key in keys:
      if isfirst == True :
        isfirst=False
        fout.write("//Table File\n//by RUNEFORGE Game Studio\n//Translated by ttgcameback.blogspot.com\n\nTable Description:\n\"id\" INT  0   |\"label\" STRING  0   |\"english\" STRING  0   |\n\nData:")
        fout.write("\n")
      arr = dic[key]
      line = arr[0]
      line +="   \""
      line += arr[1]
      line +="\"   \""
      line += arr[2]
      line += "\"   |\n"
      fout.write(line)
 
make_dbt()

2018年12月20日木曜日

CentOS7.5から7.6にしてsamba4.8にされたらWindows10からつながらなくなった

前提条件として、ドメインなしActive Directoryなし、Workgroupのみの環境です。

smb.confに明示的にserver roleディレクティブを指定しない場合、server roleディレクティブの規定値はautoですが、samba4.8からserver roleautoの場合の判定方法が変わって、security = userと設定してあっても、従来はWindows95用にdomain logons = yesという記述を残しっ放しにしていた場合でもROLE_STANDALONEと判定されていたケースがROLE_DOMAIN_PDCと判定されるように変更されたようです。

故に、記述を削除するか、または、smb.confに明示的に
server role = standalone
を記述すれば4.7以前の挙動に戻ります。

まあ、Linux同士(というかsamba同士)ならほっぽいておいても問題なく接続できます。
Windows10からつながらないことで原因調査に小一時間も無駄にしてしまったという恥を記録する次第です。
十年単位で毎度精査せず設定ファイルを引き継ぎまくってる報いでしょう。
おハズカシイ次第です。

2018年12月10日月曜日

Windows10 October 2018 Updateの新規インストール時の回復ドライブは実は使われていない(カラッポ)

Windows8の頃から回復ドライブネタでいくつか当ブログで記事を書き散らしていますが、記事にコメントをいただいた際に、現時点での最新のWindows10 October 2018 Update(1809)のインストールメディアでクリーンインストールした場合、回復ドライブがどのように配置されるのか試した際に表題の件のような面白いことが分かりましたので記事にしてみたいと思います。

まず、クリーンインストール直後のパーティション構成は次のようになります。
相変わらず回復ドライブが先頭にあります。
なぜかディスクアドミニストレータではMSRが表示されないため、正確を期すためにdiskpartコマンドで実際のパーティション構成を表示した結果も掲載します。
DISKPART> list part
  Partition ###  Type                Size     Offset
  -------------  ------------------  -------  -------
  Partition 1    回復                 499 MB  1024 KB
  Partition 2    システム                99 MB   500 MB
  Partition 3    予約                  16 MB   599 MB
  Partition 4    プライマリ               59 GB   615 MB
なお、パーティション番号4のプライマリというところがディスクアドミニストレータでは(C:)と表示されている部分に相当し、ここにWindows10がインストールされています。

実は、そもそもこれはマイクロソフト自身が2017年に公開した新レイアウトガイドに違反しています。

回復ドライブ、システム(EFI)、マイクロソフト予約(MSR)、Windowsインストール先パーティションの順にパーティションを構成するのは旧レイアウト仕様です。
MS自身が画定した新仕様ではEFI,MSR,Windowsインストール先パーティション、回復ドライブの順でなければなりません。

おまけに、回復ドライブの容量が499MBしか切ってないので、次回のメジャーアップグレード時に確実に廃棄され、Cドライブの後方が切り取られて回復ドライブにされてしまいます。
これで見事に回復ドライブが増殖するわけです。

MS自身で決めたルールをMS自身が破っているために結果としてユーザの計算機資源を奪うことになるわけです。

まあここまでだったら、ばかばかしいけど単に「相変わらずWindowsのインストーラの品質の低さは折り紙付きだなぁ」で終わりそうです。

しかし、これだけでは終わりません。
ここからがさらにお笑いなのです。

実は折角作成された回復ドライブ用のパーティションは使われていません

何を言っているかわからないでしょう?
言い方を変えます。

回復ドライブ用のパーティションはカラッポです

実際に見てみましょう。
ディスクアドミニストレータでは回復ドライブにドライブレターを割り当てられませんので、diskpartコマンドで割り当てる必要があります。
ここではTドライブとしてアサインしました。
その中身をのぞいてみましょう。
T:\>dir /ash
 ドライブ T のボリューム ラベルは 回復 です
 ボリューム シリアル番号は 2AF2-7EC1 です
 T:\ のディレクトリ
2018/12/10  16:13    <DIR>          System Volume Information
               0 個のファイル                   0 バイト
               1 個のディレクトリ     506,253,312 バイトの空き領域

System Volume Informationディレクトリ回復ドライブとは無関係です。「システムの復元」機能により勝手に全パーティションに生成されるものですので無視してください。
本当に何もないでしょう?

では、じゃあ一体回復ドライブはどこにあるんだ、ということになります。
調べ方はいたって簡単で、reagentcコマンドが教えてくれます。
試しに聞いてみましょう。
T:\>reagentc /info
Windows 回復環境 (Windows RE) およびシステム リセット構成
情報:
    Windows RE の状態:         Enabled
    Windows RE の場所:         \\?\GLOBALROOT\device\harddisk0\partition4\Recovery\WindowsRE
    ブート構成データ (BCD) ID: 31b21218-fc4a-11e8-9a48-f962270261aa
    回復イメージの場所:
    回復イメージ インデックス: 0
    カスタム イメージの場所:
    カスタム イメージ インデックス: 0
REAGENTC.EXE: 操作は成功しました。
赤字のパーティション番号をご覧ください。
partition4とあります。

先のdiskpartコマンドによるパーティション一覧を思い出していただきたいのですが、パーティション番号4は「Cドライブ」を示しています。
従って、C:\Recovery\WindowsRE というところに配置されているというわけです。
つまり、回復ドライブなどははなっから嘘っぱちで実際には、Cドライブに回復環境が配置されているのです

言い方を変えれば、Cドライブが回復ドライブを兼ねているということになります。

その理由はだた一つ、回復環境の容量に対して回復ドライブとしてインストーラが切ったパーティションサイズが不足しているからです。
1809の回復環境のファイルサイズは約485MBで、一見499MBあれば足りると思われるかもしれませんが、実は最低空き容量の規定があり、パーティションサイズが500MBを超える場合は320MBの容量が必要という仕様により、最低でも806MBなければならないために容量不足となってしまうわけです。
但し、最低空き容量が320MBという仕様書にある数値も眉唾でして、実際には、回復ドライブが実際に機能していたバージョンからアップグレードを重ねて1809にした別の環境では回復環境のサイズは510MBとなっておりますが、回復ドライブに奪われたサイズは878MBとなっており、その差が368MBとなっています。つまり仕様書には嘘っぱちの数値がかかれている可能性があり、実際には320MBの空き容量では足りない可能性があります。

ま、要するに新規インストール時に生成される回復ドライブというのは、現在では完全にユーザの計算機資源を無駄にするだけのものでしかないのでした。

しかも、ディスク全体ではなく、Cドライブが死ぬだけで回復環境も起動できないわけです。

自分自身の決め事を守らない上に、自分がインストールしようとするファイルのサイズをもとにパーティションサイズもろくに計算できないインストーラにはもう呆れを通り越して笑うしかないでしょう?

このような間抜けな事態を知るきっかけとなったこちらの記事にコメントをお寄せいただいた方に感謝いたします。
ありがとうございます。

なお、このような間抜けな事態を事前に回避するには、現状ですとWindows10をインストールする前に手動でパーティションを切り、それぞれのパーティションに対してidを振っておくなどパーティション構成を決定しておくほかに手段がありません。

その方法は手間ではあるものの作業としてはとても単純で、Windows10のインストールメディアさえあればdiskpartコマンドを用いてだれでもできます。
手順は本記事の末尾でご紹介いたしますMS自身が作成したご参考資料内にそのまま実行できるスクリプト形式で掲載されていますので割愛いたしますが、英語が面倒だという方は以前書いたこちらの記事が2015年の記事のため旧レイアウト仕様にあわせているものの、新レイアウトに従った順番に変えるだけですのでお役に立つかもしれません。

ただ・・・敢えてぶっちゃけていってしまいますが、今は亡きWindowsPhoneや特殊な構成のメーカお仕着せPCなどでは一般的なインストールメディアからインストールできないため必要でしょうけど、自分でWindows10をインストールできる人にとっては、この回復環境をわざわざ計算機上に配置する意味なんぞまったくないと思います。
インストールメディア上に全く同じ回復環境が用意されているからです。

今回の大型アップグレードでRedstone系列は終了し、次回はまた別シリーズとなります。
実は当ブログでも幾度か記事にさせていただきました通り、Windows8からWindows 10 November Update(1511、Threshold2)までは容量不足ならばアップグレードの際に無制限に回復ドライブの数が増えていくというとんでもない仕様でしたが、Redstone系列に入ってからは無制限な回復ドライブの増殖は行われなくなり、パーティションサイズを大きくできるなら大きくする、というように改善されました(むろん、今回のようにディスクの先頭にある場合は大きくできないので増殖することになりますが・・・)

次回以後の大型アップグレードの系列では、さらなる改善を期待したいと思います。あとインストーラを含めて品質管理をもうちょっとマシにしてください・・・

以上、お読みいただきありがとうございました。

ご参考:
UEFIの場合の新パーティションレイアウト資料はこちら:
https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/configure-uefigpt-based-hard-drive-partitions

MBRの場合の新パーティションレイアウトの資料はこちら:
https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/configure-biosmbr-based-hard-drive-partitions

UEFIの場合の旧パーティションレイアウトの資料はこちら:
https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-7/dd744301(v=ws.10)

2018年11月21日水曜日

C#のListでGetRange()とToCopy()とBlockCopy()を比較してみた

知ってる人にとってはばかばかしいと思いますが、C#素人の悲しさ故に何でもやってみないとわからないので、恥ずかしながら今回は単純なリストの範囲コピーの速度比較をやってみました。

測定条件:
コピー元: List<float> 100000件
コピー先: float[]
コピー条件: コピー元の4000件目から最後まで(96000件)
コピー回数: 100000回

結果:

メソッドコピー先を毎回確保コピー先を使いまわし
GetRange23327ms(使いまわせない)
ToCopy11499ms1958ms
BlockCopy20000ms11862ms

コピー先を使いまわす版は異常に高いnewのコストを除外するために測定しました。
とりあえずToCopyがいいみたいです。
以上です。

おまけ:
こんなコードで測定しました。
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
public class ListCopySpeedTest
  {
    List<float> fl = new List<float>();
    const int membernum = 100000;
    const int testcount = 100000;
    const int startindex = 4000;
    void init()
    {
      Random r = new Random();
      for ( int i = 0; i < membernum; i++ ) {
        fl.Add( (float)r.NextDouble() );
      }
    }
    float[] GetRange( float[] fa )
    {
      fa = fl.GetRange( startindex, membernum - startindex ).ToArray();
      return fa;
    }
    float[] ToCopy( float[] fa )
    {
      if ( fa == null ) {
        fa = new float[ membernum - startindex ];
      }
      fl.CopyTo( startindex, fa, 0, membernum - startindex );
      return fa;
    }
    float[] BlockCopy( float[] fa )
    {
      if ( fa == null ) {
        fa = new float[ membernum - startindex ];
      }
      Buffer.BlockCopy( fl.ToArray(), startindex, fa, 0, membernum - startindex );
      return fa;
    }
    delegate float[] testfunc_t(float[] floatarray);
    void testfunc( Stopwatch sw, testfunc_t f )
    {
      float[] fa = null;
      for ( int j = 0; j < 2; j++ ) {
        sw.Reset();
        sw.Start();
        for ( int i = 0; i < testcount; i++ ) {
          f( fa );
        }
        sw.Stop();
        Console.WriteLine( f.Method.Name + ": " + sw.ElapsedMilliseconds + "ms" );
        fa = new float[ membernum - startindex ];
      }
    }
    public void test()
    {
      init();
      Stopwatch sw = new Stopwatch();
      testfunc( sw, GetRange );
      testfunc( sw, ToCopy );
      testfunc( sw, BlockCopy );
    }
  }
  class Program
  {
    static void Main( string[] args )
    {
      new ListCopySpeedTest().test();
      Console.Read();
    }
  }

2018年11月15日木曜日

Windows 10 October 2018 Update(Redstone5)では回復ドライブは増殖せず肥大化するのね

ひとつ前の記事でWindows10を1803から1809にしたので、今度こそはまたまた前例通りにパーティションが増殖してくれていることを強く期待して、さっそくディスクアドミニストレータを見てみました。
あ~、今回もパーティションが増えてない・・・

ちぇ、と思って、がっかりするところでした。

が、よーく見ると、なんとサイズが増えて肥大化していたのでした(元は500MBでしたから378MB肥大化しました)。

Threshold2(1511)まではパーティションの数が増えてましたが、どうやらRedstone1(1607)以後はパーティションのサイズを奪い取る成長を遂げていたのですねえ。

それにしても空容量に対して使用量が60%、なんでこんな878MBなんて半端な数値なのかしら。

先頭にあるパーティション、Windows8.1から10にアップグレードしたときのあまりの増殖っぷりに驚いて大きめにわざわざ折角大きめに切ったのにぜーんぜん使われなくって、今はだぁれも住んでいない昔の回復パーティションなんですが、そこに十分おさまるじゃないですかぁやだぁ。

まあ、HDDなんで容量的にはどうでもいいし、パーティションが無意味に増殖してしまって分断されるよりははるかにましですのでさらにどーでもいいっちゃあいいんですが、Threshold2で勝手に作られた回復ドライブの容量が450MBだったことを思うと倍近いんですね。

もうWindows Phoneは放棄したし、あと必要そうなのは、メーカーお仕着せのノートパソコンのリカバリ用途くらいしかないけど、そういう用途ならOS丸ごと入っていたりするものなのでGB単位で切ってあるからますますこんなちっこい回復ドライブを必死に作る必要ってない気がするけど。

どうせストレージが死んだら道連れですし。

どこまで増やすのかな?

Windows 10 October 2018 Updateが0x800F081F-0x20003で更新に失敗する

まず結論だけ述べます。

1803までで「Windows開発者モード」をインストールしていると「Windows 10 更新アシスタント(Windows10Upgrade9252.exe)」で1809への更新が失敗する場合があります。

結論は以上です。

以下余談です。

0x800F081FとはDISMのエラーコードそのままを吐いています。
枝番の0x20003は、「Windows 10 更新アシスタント」の更新作業の、どの段階で何をしていたかを示します。
0x200はアップグレードで行われる4段階中の2段階目、Safe OSでの作業中に起こった事象ということを示し、0x03がアップデート(この場合のアップデートとはWindows 10 October 2018 UpdateにあてるべきWindows Updateの事を指しています)をインストール中である事を示しています。
アップグレードとアップデートは言葉が似ているのでヤヤコシイ。

で、今回は
Microsoft-OneCore-DeveloperMode-Desktop-Package~31bf3856ad364e35~amd64~~.cab
が原因でした。
DeveloperModeとファイル名にある通り、開発者モード用のパッチですが、これが不具合の原因ですので、これを回避すればいいわけです。

回避するには「Windows開発者モード」をアンインストールします。
アンインストールできる場所は「設定」->「アプリ」->アプリと機能欄の「オプション機能の管理」です。
勘違いしやすいので敢えて画像を添付します。


「設定」->「更新とセキュリティ」->「開発者向け機能を使う」->「開発者モード」ではないので念のためご注意申し上げます。

ちょっとお詳しい方ならDISMときたらsfc /scannowで解決だろ!とおっしゃる方もおいでかもしれません。
ところがどっこい、今回は不整合が検出されない場合のケースです。

redstone系列の最終段階であるWindows 10 October 2018 Updateが満を持して公開!!
・・・のはずが、直後にファイル消失という深刻な障害により公開中止となっていました。
ひと月以上たった昨日、ついに再公開されました。

今回も段階的にインストールできる人を増やしていくとのことで、まだ私の環境にはWindows Update経由ではインストールできませんでしたが、どうせWindows Updateの日なのでパッチが強制的に当たったうえに再起動を強制されるついでですので「Windows 10 更新アシスタント」を用いて一挙に更新してしまうことにしました。

1時間ほどかかった挙句、結局更新に失敗しました。
頭にきたので原因を探ってみました。

まず初回の失敗時の状況です。
当環境ではSandboxieというツールがインストールされているのですが、これをアンインストールしないと絶許ということでしたので、素直にアンインストールしたところ、まだSandboxieがあるじゃんアンインストールしろよと言われてしまい(つまりWindowsからは2つインストールされているように見えているようでした)、とはいっても、当方としてはもうこれ以上アンインストールできません。
とりあえずアンインストールを完了するには再起動しなさいとSandboxieに言われているところでしたので、「Windows 10 更新アシスタント」を中断してから再起動し、再起動後に再度「Windows 10 更新アシスタント」を起動したころ、なんだかWindows 10 October 2018 Updateの更新作業が進みだしてしまいました。

まあ、とりあえずなぜか進んだので、Sandboxieが原因だったのかな、それにしても何でインストールが先に進んでしまったのだろう、2つのうち一つしかアンインストールしていないわけですから進んじゃいけないはずなんだから、それって不具合だよねやっぱりテストしてないよね怖いよね、と思いながら眺めていましたが、今回もやっぱり更新中の再起動一回目の進捗14%のところで失敗して1803に巻き戻されました。

この際、何のエラーコードも表示されず、イベントログにも何も残っていませんでした。
普通こういう大型アップデートをかける場合は寝る前とか帰宅前とかで行うでしょうから、失敗だろうが成功だろうが結果を表示しなければ普通の人は「あ、(正常に)終わったのね」としか思わないはずです。
なんて不親切な設計なのかとびっくりしました。

Sandboxieのアンインストールに伴う再起動がまずかったのかな、と思い、再度「Windows 10 更新アシスタント」で更新を開始しましたが、今度も「Sandboxieをアンインストールしてください」と言われてしまい途方にくれました。

レジストリにゴミが残っちゃったのかしら、と舐めるように点検してもSandboxieなんかないし、どうしたものか、と思っていると、別ドライブにバックアップとしてファイルのコピーだけしてあったSandboxieのファイル群があるのを発見しました。
ダメ元でそのファイルを削除したところ、それだけでインストールが再開されました。

バックアップだろうが何だろうが、どうせ動かないプログラムだろうと何だろうと、とにかくマイクロソフト様が許さないと指名したファイルがあるというだけでインストールさせないほど超コワモテな姿勢です。
動いているデバイスドライバでも何でもないそんなものをチェックする余裕がある癖に、今回のインストールの失敗の原因(説明はこの記事の後のほうになります)は超単純なのにチェックしてないってのがとてもスバラシイ。

ですが、インストールが先に進みはしたものの、やっぱり1回目の再起動後の進捗率14%の段階でロールバックされてしまいました。
これ自体は前回と同じ結果でしたのでSandboxieそのものが原因ではないことはわかりました。
しかし、今回は前回と変わって大きな違いがありました。
ロールバック後に「Windows 10 更新アシスタント」が勝手に画面をポップアップしてエラーコードを表示して教えてくれたのです。
それが「0x800F081F - 0x20003」でした。
さっきは不親切さにびっくりしましたが、今度は「あ、本当は結果を表示するはずだったのね」という意味でびっくりしました。

結果が表示されないのはバグだったんですね。

この後も含めて、結局何回か更新作業を行うことになってしまったのですが、後にも先にもこの時しか「Windows 10 更新アシスタント」さんはエラーコードを教えてくれず、1回目と同様に何も表示されないまま1803にロールバックされました。
当然イベントログにも何の情報もありません(何のためのイベントログなんだか)。
やっぱりこの辺もユーザにエラーを通知する機能のテストが全然できてないものとお見受けいたします。
不安をさらに煽ってくれるいいスパイスとなりました。

でもまあ、いつものように「はじめました」->「やってます」->「できませんでした」という無意味なメッセージではなく、兎にも角にもエラーコードを教えてもらえただけでも幸運でした。

早速エラーコードでgoogle検索様に教えを請いましたところ、エラーコードの意味そのものは引っかかりませんでしたが、DISMがこのエラーコードをよく吐くという文言があちこちの検索結果から目に入りました。
こんな数値、とても偶然の一致とは思えません。

そーいやBCDとかもVistaからだったなあ、あの時なんかすげぇ苦労して今はidすら忘れた某ソーシャルサイトで長い記事書いたっけなぁとか眠い頭で連想するうちにsetupact.logの存在を思い出しました。
アップグレードの手順はVistaのころから変わっておらず、「何回か再起動されます」なんて曖昧なことを言われますが、実はアップグレード時のリブート回数は特殊なデバイスを搭載していない限り決まっています。

たとえば今回のように1803上「Windows 10 更新アシスタント」を用いた場合、リブートの1回目は元のOS上でインストールすべきファイルを収集し終えたあと、2回目はSafeOS上での手順がおわるまで、3回目はそれ以降の手順です。
で、なんで回数なんかに着目するかというと、何回目にリブートされたかによってログが吐かれる場所が変わるからです。

余談ですがこれはVistaSP1のころから変わっていません。さすがWindowsNT6.0というだけあっただけにXPのNT5系列から劇的な変化を遂げています。
製品としてのWindows10も(製品名とカーネル番号だけを合わせたので表示上はWindowsNT10.0ですが)実はカーネルは(まだ)WindowsNT6.4相当なのでその辺はほとんど変更がありません。
実際、1803でもバージョンは10.0.17134のままですし、今回の1809も10.0.17763です。
これらのバージョン情報はエンドユーザからは簡単には見えませんが、実はコマンドプロンプトでverコマンド(winverコマンドではありません)を入力すると確認できます。
まあ、普通の人はコマンドプロンプトなんか使いませんよね。
この国のIT業界ではスマホのほうがメール書くのはえぇっすよぉPCなんかつかってらんねぇっすよぉの世界が普通だそうです(えくせるほーがんしやぱわぽでの資料作成を命じると翌日には求人枠が一つ空くとかあかないとか)

ま、そんなわけですので、Vistaのガワだけ取り替えて見た目は劇的に変わってはいるものの、OSの大規模更新といったようなコアとなるような機能では、Vistaのころからのトラブルシューティングの知見が随分流用できます。

で、今回はsafeos内手順中での作業中の事故ということが0x20003の0x200の部分でも教えてくれていますので、そこにあるべきsetupact.logを検索しました。

すると、こんな行が見つかりました。


2018-11-14 22:10:04, Error                 SP     CAddPackage::DoExecute: Failed to add package Add [1] package C:\$WINDOWS.~BT\DUImageSandbox\Microsoft-OneCore-DeveloperMode-Desktop-Package~31bf3856ad364e35~amd64~~.cab. Error: 0x800F081F

これで0x800F081Fの出所もわかったし確かに枝番からわかる0x200の意味するところのSP_EXECUTION_SAFE_OSで 0x03の意味するところのSP_EXECUTION_OP_INSTALL_UPDATES でエラーが起きたことは確かだということが分かりました。

が、これ、実は、まだこれだけじゃ終わりません。
実際にはこのファイルは正しい形式で既定の場所にダウンロードされており、このMicrosoft-OneCore-DeveloperMode-Desktop-Package~31bf3856ad364e35~amd64~~.cab自体に問題はありません(ファイル名長すぎ)。

ですので、このファイルだけひねくり回しても何の解決にもなりません。

Errorとして報告されていない部分が実際の異常の原因なのでした。

このエラーだけ見るとMicrosoft-OneCore-DeveloperMode-Desktop-Package~31bf3856ad364e35~amd64~~.cabが異常だと思うじゃないですか。
本当は、このcabファイルがさらに必要とするファイルがあって、それがないという情報はErrorではなくInfoとして報告されているのです。

こんな具合です。
2018-11-14 22:10:03, Info                  CBS    FOD: Missing payload: Microsoft.WebDriver~~~~0.0.1.0
2018-11-14 22:10:03, Info                  CBS    Missing payload found on FOD execution [HRESULT = 0x800f081f - CBS_E_SOURCE_MISSING]
2018-11-14 22:10:03, Info                  CBS    Exec: Failed to retrieve FOD payload [HRESULT = 0x800f081f - CBS_E_SOURCE_MISSING]
2018-11-14 22:10:03, Info                  CBS    Failed to download and plan capabilities [HRESULT = 0x800f081f - CBS_E_SOURCE_MISSING]
2018-11-14 22:10:03, Info                  CBS    Failed to plan execution. [HRESULT = 0x800f081f - CBS_E_SOURCE_MISSING]
2018-11-14 22:10:03, Error                 CBS    Failed to process single phase execution. [HRESULT = 0x800f081f - CBS_E_SOURCE_MISSING]
2018-11-14 22:10:03, Info                  CBS    WER: Generating failure report for package: Microsoft-OneCore-DeveloperMode-Desktop-Package~31bf3856ad364e35~amd64~~10.0.17763.1, status: 0x800f081f, failure source: CBS Other, start state: Absent, target state: Absent, client id: DISM Package Manager Provider

つまり、WebDriverが必要なのにそれを適用しようとせずに、セットアップスクリプトが依存関係を無視してMicrosoft-OneCore-DeveloperMode-Desktop-Package~31bf3856ad364e35~amd64~~.cabを入れようとしてるのが悪いわけです。

これもバグですよねぇ。

なぜなら、Windows開発者モードが搭載された
「Windows 10 Anniversary Update(1607,redstone1)」
から、その後の
「Windows 10 Creators Update (1703,redstone2)」、
「Windows 10 Fall Creators Update (1709,redstone3)」、
「Windows 10 April 2018 Update (1803,redstone4)」
まで、3回もの大型更新ではまったく問題がないんですから完全にアウトですよねえ。

なぜ今回問題となったかというと、Features on Demand(FoD)化にあるんだと思います。
WebDriverは1908からFoDとしてDISMからインストールできるのですが、1903まではFoD化されてません。インストーラ経由でのインストールになります。

新機能を追加したのにテスト設計チームに全然伝わっておらず、テスト仕様書からごっそりと抜け落ちていたんでしょう。
最近のMSくぉりちーがここにも遺憾なく発揮されてしまったようです。
MS製WebDriverをわざわざ入れる人って極めて貴重なEdgeマニア(そんな人いるのかな)か、業務でEdgeらされている人だけでしょう。
業務としてはお気の毒ではありますがこのバグには遭遇しないと思いますので、日ごろの艱難辛苦が報われたことは誠にご同慶の至りです。

そして、1809になったらなったで、今度は「Windows開発者モード」が「設定」->「アプリ」->アプリと機能欄の「オプション機能の管理」->「機能の追加」から消えてしまっています。

これは多分、「設定」->「更新とセキュリティ」->「開発者向け機能を使う」->「開発者モード」を選択したら自動的にインストールされるからいいだろ、ということだと思います。
実際にやってみたところ、選択すると自動で「Windows開発者モード」がインストールされてしまいます。
明示的にユーザがインストールしたわけじゃないのに無理やりされちゃいます。
但し、インストール済みとして表示はされるようにはなるので、そのことを知ってさえいれば削除は可能です。

ところで、1809ではその代わりに、今度は「設定」->「アプリ」->アプリと機能欄の「オプション機能の管理」->「機能の追加」にWebDriverが追加されています。
このためにFoD化したんですよねきっと。

上記のラジオボタン選択による「Windows開発者モード」の強制インストールが行われても、一見WebDriverはインストールされないように見えて実はされちゃいます
どうせ一緒にインストールされちゃうなら、折角の大型アップグレードなんだから一緒のパッケージにすればいいのに。

まあ、要するにこのラジオボタン選択で自動で行われるインストール作業がアップグレード時には行われないのが今回のバグの原因ということなんでしょう。

こんなんじゃ近いうちにまたWindows Updateで問題が起きるかもしれません。
開発者モードはWindows 10 Anniversary Updateでbashが使いたいときにどうしてもインストールしなくちゃいけなかった機能でしたが、その後のWindows 10 Fall Creators Updateからは開発者モードにしなくても使えるようになりましたので、いまでは(もしかしたらUWPの案件が・・・なんて淡い期待とともに、あるいは完全に忘れっぱなしで)そのままにしておいた人や、本当にUWPの開発をしていてWebDriverが不要だった人に直撃です。

本気でUWPを普及させたいから、自分で「Windows開発者モード」を選択してインストールしなくても黙って入れちゃえよ~ともかく敷居だけでも下げられねぇかな~たのむよ~なんとかしてくれよぉ~、という経営上の要請が、WebDriverのほうもやっぱり、Edge普及しねぇんだよぉ~あのFirefoxにも負けてんだよぉ~たのむよぉ~インストーラなんか探さなくても手軽に入れられるようになんねぇかなぁ~、という市場戦略上の要請が、それぞれありありと見えますが、それでこんなバグだしてんだから世話ねえやね。

わはは。

UWP早くなくなれ。

ところで。
インストールの最終段階の全画面でのあの無意味な「こんにちは」から始まる一連のやつは今回も健在でした。
もう結構です。
口だけは達者と言われちゃっても知らないぞ。


それにしても、なんだかんだ言って使いやすいOSであることには違いないのになぁ。

先日のライセンス認証サーバがこけちゃう大ポカとか、ファイル消失なんてあっちゃいけないバグが分かってて出荷して出荷停止にする激ポカとか、小一時間は軽くかかるアップデートでこんなくだらないバグを出すとか、FHDだろうが4Kだろうが8Kだろうがお構いなく全画面でこんにちはとか言ってるようじゃどうしようもないんじゃないかなあ。

折角のOSの魅力を自分でスポイルするのはなんかの呪いなんですかねぇ。

2018年10月31日水曜日

KB4462933をインストール後HID準拠ゲームコントローラー(ジョイパッド)が接続されているとスリープしない・・・?

変な表題ですが、理由があります。
結論だけ言うと「KB4462933を再インストールしたら再現しなくなった」ように見せかけて「やっぱり再現した」ものの「再インストールしなくても再現しなくなった」です。
何が何だかさっぱりわかりません。

調査を進めてみると、もしかしてこの事象が発生するのはKB4462933に限らないかもしれない可能性が疑われました。
さらにその後、やっぱりKB4462933が原因だろうと考えざるを得ない事態が出来しました。
ちょっと複雑なので、順を追ってご説明いたします。

まず、以前にもありましたが、またもやUSBで接続されたジョイパッド(MS用語では"HID 準拠ゲーム コントローラー")が接続されていると、アイドル状態が続いて既定の時刻になってもスリープどころかブランクスクリーン(MS用語では"ディスプレイの電源を切る")にもならなくなりました。

あくまでもアイドル状態が指定時間続いた場合にスリープに入らないので手動でスリープを指示すれば正しくスリープに入ります。
ジョイパッドを抜去すると再度アイドル状態が続いた後に自動でスリープに入るようになります。

今回はKB4462933を適用した直後からこの事象が発生しました。

イベントログで確認しても、このKB4462933がインストールされてから丸一日後(たまたま長時間不在の中での更新でした)に気が付いて、試しに手動でスリープボタンを押下するまでスリープに入っていないことが記録されています。
家族に聞いても(常時私のPCを監視しているわけではないのでイベントログほど確実性はないものの)画面がつきっぱなしだったと言われましたので、スリープに入っていないことは確実です。

前回同じようなことを経験しているので、試しに接続されたままだったジョイパッドを抜去して待ってみると、正常に一定時間経過によって自動的にスリープしました。

試しに再起動してみても、ジョイパッドを接続しなおしたり接続ポートを変更してもこの状況は変わりませんでした。

一応、極めて黒に近い灰色に思われましたが、このまま犯人だと決めつけて間違っていたら間抜けなので、念のためにKB4462933をアンインストールして同様の試験したところ、自動的にスリープに入ることを確認しました。

さらに念のため、アンインストール前と設定が変わっていないかどうかの比較のため、以前のようにデバイスマネージャで電源設定を確認したりコントロールパネル->電源オプション->プラン設定の編集をチェックしましたが、両者の間で変更点は全くありませんでした。
powercfg.exe /requestsの結果も双方「なし。」の羅列で阻害要因なし。
powercfg.exe /energyの結果も双方阻害要因なし。

言い方を変えれば、powercfg.exe /requestsの結果および/energyの結果にKB4462933適用済の時とKB4462933未適用の時での差異が一切ありません(が挙動は異なる)という状況でした。

ここまでで犯人もわかったことだし、面倒ではあるけど対策はあるわけだからよしとして、暇なときにでも今度はもうちょっと原因を突っ込んで調べてみよう、ということでこの記事も一旦終わるはずでした。

ところがどっこい、そうは問屋が卸してくれませんでした。

KB4462933を再インストールしたところ、なんとジョイパッドを接続しっぱなしでも今度は正常に指定時間ピッタリに自動的にスリープに入るのです。

同様に再起動してみたり接続ポートを変えたりしてみても、時間経過で正常に自動的にスリープします。
電源設定もpowercfg.exeも再インストール前とアンインストール前の結果と比較してみましたが、やっぱり同一です。

しかし、KB4462933を初回インストールしたあとの再起動後から一切スリープしなくなったのは確かです。
なぜなら、私が不在時にこのWindowsUpdateによる更新が行われましたので、操作者がいない以上、正常ならば再起動してから一定時間経過後にイベントログにKernel-Powerのイベント42、「スリープの理由: System Idle」が記録されていなければなりませんが、その記録がないことからも明らかです。
スリープしているはずの時間帯だけでなく、翌日手動でスリープするまでにどっさりESENTイベントID916などのゴミログがイベントログに大量に、かつ間断なく記録されているのも傍証となります(まさかあのゴミログが役に立つとは!!)。

問題は、KB4462933そのものが原因ではないことです(後述しますがこの段階ではそう見えたものの、この結論は実は早すぎるようです)。
アンインストールして再インストールしたら事象が再現しないのですからそう言わざるを得ません。

(ここから上記の誤った結論に基づいた仮説が縷々続きますが、その後の新しい現象が確認されたことにより無駄な文章となっております。表題の趣旨としては合致しないため、本来は削除すべきですが、スゴイ恥ずかしいのでblogの趣旨としてどう恥ずかしいのかしっかり残すために文字を一回り小さくして残させていただきたいと思います。)
ただし、ここから先は事実ではなく仮説になってしまいますが、今回のケースではKB4462933を入れたことによってスリープをしなくなったものの、再インストールを行うことによって正常にスリープするようになったという現象自体を見ると、WindowsUpdateで品質更新プログラムを適用する際に実行されていると思しき何らかの作業スクリプトに不備があり、このケースと同様にスリープしなくなるという現象を惹起する可能性に思いを致さざるを得ません。
ということは、つまるところ、別の品質更新プログラムや機能更新プログラムでもその修正・追加内容に拘らず同様の事象を再現する可能性があるということになります。

というのは、一般的にはこういった更新適用スクリプトには固有の手続き以外の共通化できる手順というのがあって、そういった部分は毎回書き直したりせず、使いまわされることが多いからです。
その部分に、たとえば更新中は一時的に自動スリープを抑止するような手続きが含まれており、かつ何らかの条件で抑止を解除する手続きの中で一部正常に元に戻せなくなるケースが見逃されているのではないか、などの可能性が考えられます。
また、様々な環境用に一切合切まとめられてしまっている品質更新プログラムの中から、当環境に適したモジュールを抽出して適用する際、特定条件下ではスクリプト部分に問題があって、誤適用してしまう可能性も考えられます。

もしこの仮説が正しければ、の話ですが、もしも今回同様なケースに見舞われた方がおいででしたら、スリープしなくなってしまった直前に適用された品質更新プログラムや機能更新プログラムを再インストールしてみてはいかがでしょうか。
もしかしたら、今回のケースのようにあっさり直ってしまうかもしれません。

今回のケースでも「アア、マタカ」と面倒くさがってジョイパッドを抜去するだけの対策で済ませていたら、品質更新プログラムの再インストールで正常な挙動に直せることが分からずじまいでした。

仮説を唱えるなら実証して見せろ!とお叱りを受けそうです。
ごもっともです。

これは言い訳ですが、KB4462933のインストールとアンインストールと各段階でのデータどりを1ターンとすると、当環境では1ターン当たり2時間弱かかります。
しかも、一般的に機能更新プログラムなどがWindowsUpdateで適用される前の再起動は「前回の」WindowsUpdateでリブートがかかった後、何日~何十日も再起動されないままで適用されるという条件もあります(今回の事案では12日間再起動されていませんでした)。
私にはそれを検証するだけの時間的資源がありません。本当に申し訳ございません。

言い訳だけでなく、危うくKB4462933冤罪事件を免れましたので、恥の記録としてここに記録する次第です。
お読みいただきありがとうございました。

・・・とは終われませんでした
問屋が卸してくれない状況で輪をかけてこれですから、言うなれば元売りも卸してくれないとでも言えばいいのでしょうか。

KB4462933を再インストールして正常にスリープをすることを確認したその当日の数時間後には、スリープしなくなる現象がまたもや再現したのです。

KB4462933を再インストールして正常にスリープができたことを何度も確認してから、そのままジョイパッドを接続したまま再起動もせず、数時間PCを使った後、所用で1時間ほど離席して帰ってくると、画面がまばゆく輝いていました。

イベントログも確認しましたが、離席した時刻以後は確かにスリープが記録されていません。

その間、繰り返しになりますが、検証のための最後のスリープを確認して復帰させた後は再起動などシステムに手を加えるようなことは何もしていません。
テキストエディタとブラウザを使っていただけです。

仕方がないのでもう一度ジョイパッドを抜去してスリープするか確かめたところ、抜いてあれば時間経過でスリープすることを確認しました。

もうなんだこれ?と途方に暮れつつ、ジョイパッドを接続したままにして、まだ用事が済んでいなかったため再度離席したのち所用を終えて帰ってくると、今度はスリープしているではありませんか。

うーん。魂消たなあ。
この現象はこれまでとはまた違った新現象です。

KB4462933のアンインストール前でのケースでは、ジョイパッドを接続しなおしてもシステムを再起動しても兎にも角にもジョイパッドが接続されている限りスリープに入らない状態は変わらなかったのですが、今回はKB4462933をアンインストールしなくともスリープに入ってしまったわけです。
当然、電源周りの設定とpowercfg.exeの出力も比較しましたが、これまた他と同様、まるで違いは認められません。

前回のアンインストール前の挙動とは明らかに異なります。
いったい何なんだろう。
帰ってきてまたまたパッドを挿抜したりなどのこれまでと同様のテストを行いましたが、正しくスリープに入ってしまいます。

こうなると、現時点では一度スリープから復帰して何時間も使ったあとはスリープに入らなくなったという事しか言えなくなりました。

一度はKB4462933は冤罪とみなしそうになりましたが、実はそうとは言い切れないのではないかという疑いが再浮上してしまいました。むしろ、このパッチが当たるまでは何の問題もなかったのですからますます疑惑が深まってしまいました。

(ひょっとして、その間にスリープ抑止リクエストが入った場合はどうなるかと思いついてしばらくwindows media playerでDISPLAYとDRIVERとPROCESSに抑止が入るようにして使った後、スリープに入るかどうか試してみましたが、正しくスリープに入りましたのでこれは関係ないようです。確かに再インストールしてから特別なスリープ抑止リクエストがかかるようなアプリを起動した覚えはないので、無意味なテストでした。)

とにかく私の先の仮説とやらは大仰に書きまくった割には大外れでとっても恥ずかしいので、このblogの趣旨にとてもふさわしいため、このままこの記事を公開させていただきます。

いやほんと、魂消たなあ。
新たな仮説を打ち立てないと検証方法も設計できないし、今のところお手上げです。

原因を特定することが果たしてできるのか先行きが大変不安な展開となっております。
申し訳ございません。