2016年11月9日

[win10]Windows Update v.s. 私 (敗北)

なんだ、このタイトルは・・・。
経緯は、少し前のブログを見ていただきたい。
hiro99ma blog: [win10]Home版でWindows Updateは止まるか?

今の時刻は、2016/11/09 1:11。
Windows Updateの更新日だ。
Windows10 Proはよいとして、Home版でWindows Updateを行わないようにさせたい。
想定しているのは、通常時はWindows Updateを勝手にしてもらって構わないのだけど、これから2,3日間はPCをつけたままテストを行わなくてはならないため、再起動されては困る、という状況だ。
再起動しないのであれば、別にWindows Updateが動作しても構わないのだ。

で、その準備としてスリープ状態から復帰させたのだが・・・。
以前作った、Windows Updateに関連するスケジュールの停止とタスクの停止を行うバッチファイルを動かしたのだが、止めても止めてもスケジューラが復活してくる。。。
どれかというと、"Scheduled Start"だ。
このタスクは、無効にしても起き上がるし、削除しても復活。
手の打ちようがない。

Scheduled Startのイベント履歴を有効にしているのだが、どうも30分おきにNT AUTHORITY\SYSTEMがイベントを登録しているように見える。
うぅむ、SYSTEMには勝てないような気がする。。

今の時刻は2016/11/09 9:42。

昨晩から電源ONしたままのWindows10 Home版は、まだ再起動していない模様。
通知の方にも何も出ていない。

まあ、それを言えば、今起動したWindows10 Pro版も更新通知をしてこないから、同じことか。
しかし、Scheduled Startタスクはきっと起きているだろう。
そして昨日無効にしたときには、次回の起動が明日の0時くらいになっていたように思う。
仕方ないので、Home版は起動したまま仕事に出ることにしよう。

今の時刻は、2016/11/09 22:28。

まだ、再起動していないようだ。
リストを見ると「要再起動」があるから、やってれば再起動するか、少なくとも通知に出ているだろう。
2016 年 11 月のセキュリティ情報 (月例) – MS16-129 ~ MS16-142 – 日本のセキュリティチーム
ここでWindowsUpdateの設定画面を見てみたいところだが、それをやってしまうと意味がなさそうなので、ぐっと我慢だ。

ただ、今日寝るまでに再起動してなくても、明日の朝まではONにしたままにしておこうと思う。
なんというか、期待する結果としては「Scheduled Startタスクが復活してくるので、これではダメでした」というところなのだ。
もしこの程度で止めることができると、それはそれでなぁ、と複雑な心境になりそうだ。
説明が付けられれば、止まってもいいんだけどね。

今の時刻は、2016/11/10 1:07。

「くっ、大技『日付越え』をくらって生きているとは、おぬし・・・」という心境だ。
ブラウザを使ったりしていたけれど、今までだとその程度だと無視して再起動していたしなぁ。
Excelの編集中ですら、容赦なく再起動されたこともあったし。

もしかすると、最近のアップデートによって、あそこまでの強制的な再起動は行わないようにした、という可能性もある。
または、多少でもユーザが使っている雰囲気があればやらない、とか。
そうだとすれば、Update日を過ぎ、ユーザ操作もなくなるこの一晩は耐えられないんじゃなかろうか。


午前1時30分。
ノートパソコンの方から通知音が。。。
来るべきときが来ただけかもしれない。
明日だ、明日。

今の時刻は、2016/11/10 8:39。

はい、再起動していました。
起動していたアプリはまた立ち上がったものの、復帰に対応していないアプリは単に起動しただけだ。
つまり、私の負けだ。私負けましたわ。

今回分かったのは、こういうところか。

  • WindowsUpdateのタスクを無効にすると、ユーザ操作からも更新できなくなる
  • スケジューラのWindowsUpdate/Scheduled Startは止めても削除してもSYSTEMが復活させる
    • その復活を止めればなんとかなるのかは、不明

となると、どうしてもやりたくないようにするなら、WindowsUpdateタスクを無効にするしかないということか。
Windowsの不要なサービスを停止、無効化する - labunix's blog

sc config "wuauserv" start= disabled

で無効になり、

sc config "wuauserv" start= demand

で手動(トリガー開始)になるようだ。

また来月だな。

2016年11月8日

[c++]catch(...)の「...」は取ってこられないみたい

駅前が陥没して通勤路をどう迂回するか検討中だけど、まあよかろう(よくはない)。

 

pythonで作ったデータをパースしてくれるアプリがいて、そのアプリはC++で書かれている。
データが正しいかどうかはそこそこ判定してくれているのだけど、だんだん複雑なプロトコルを作ることができるようになったためか、とうとう「unknown error」というどうしようもないメッセージしか出してくれなくなった。。。
やむなく、アプリにprintfログを埋め込んで、どこが悪そうなのか当たりを付けることにした。

そうすると、どうやら例外が発生しているようだった。
そして、それはcatch(...)で捕捉していて、その場合に「unknown error」としているようだった。
ちっ。

 

さて、このcatch(...)。
関数の引数であれば、va_argsなどで取ってくることができるけれども、例外はどうなんだろうか?

調べた範囲では、取ってくることはできなさそうだった。
『プログラミング言語C++第3版』の§14.6.3.2に書いてありそうな雰囲気だったのだが、そういう感じではない。
今回のアプリは、どうやら標準例外を使ってくれているようで、別途catchを追加してエラー出力を追加するようにした。

しかしまあ、オープンソースで公開されているアプリとはいえ、規模が大きくてデバッガも使えないような状況だと、例外だけでもソース解析がつらいですな。
例外を投げるしくみにするときは、例外用クラスをぽこぽこ作るのではなく、標準例外を継承して作るようにした方がよいのだろう、たぶん。

[py]エンディアンをひっくり返す(bytearrayの)

pythonをいま使っている範囲では、凝った使い方は全然していない。
計算して、printするくらいだ。

そうなるとどうなるかというと・・・ネタがすぐに切れるということになる。
しばらくpythonネタを続けられるとほくそ笑んでいたのだが。。。

 

小ネタとして、エンディアンをひっくり返す話でも書くとしよう。

struct系のAPIには、<や>を使ってエンディアンを変更する方法があるけれども、bytearrayになっているものは特にAPIが無さそうだった。
自力で回す関数を作ったのだけど、こんなのでよいのか?

def reverse_endian(msg):
    rev = ''
    for lp in msg:
        rev = lp + rev
    return rev

うん、forで1byteずつ抜き出して、頭に追加するだけだ。
間違ってはいないと思うが、まだ格好のよい方法があるのかもしれん。

 

まだdecode('hex')する前の文字列でも、エンディアンを変更したいことがあった。
そっちは、こうやっている。

def reverse_endian_str(msg):
    rev = ''
    for lp in range(0, len(msg) / 2):
        rev = msg[lp * 2: lp * 2 + 2] + rev
    return rev

うーん、2つずつスキップする方法もなさそうだったから、先頭から2文字ずつ抜き出して先頭に追加する、をやっただけだ。
そのまますぎるのだけど、他にないよね?ないよね??

 

最近の言語だから、なんか格好のよいやり方があるかも!と模索して時間を費やしてしまうことが多いのだが、大したことない作業だったら自分でやる、という方がスクリプトとしては良いのかもしれない、と思うことにしよう。

2016年11月5日

[py][nfc]nfcpyでRC-S380を動かす(Windows10)

数週間pythonを触ったので、そろそろnfcpyもわかるようになってきたんじゃなかろうか。

nfcpy/nfcpy: A Python module to read/write NFC tags or communicate with another NFC device.

いつの間にかgithubになってるし、READMEを読んだところではpipでインストールできるらしい。
ドキュメントはこちららしい。

Python module for near field communication — nfcpy latest documentation

 

過去に動かしたことはあるのだが、もうすっかり記憶にないので、ちょうどよいだろう。
うちの環境は、こう。

  • Windows10 Pro 64bit
  • PaSoRi RC-S380/P

PaSoRiのドライバはインストールされている。
が、たぶんそれは切り離すことになるだろうね。


Overview — nfcpy latest documentation

pythonは2.6以降。でも、3は対応していないとのこと。
それと、libusbを使うようで、そのpythonライブラリがpython-libusb1らしい。
libusbは、APIが0.x系と1.x系があったので、その1.x系ということだろう。
pyserialはPaSoRiでは不要なのだけど、無しでもよいのかな?

 

Getting started — nfcpy latest documentation

pythonは既にインストールしているので、それを使う。
幸い、pipの場所もPATHに追加しているようで、コマンドプロンプトから"where pip"で見えた。

> pip install libusb1

これで、v1.5.3がインストールされたようだった。
これだけだとWindowsではlibusbがないので、そっちは自前でインストールする。

説明ではいろいろ書かれているけど、たぶんこういう手順だろう。

  1. zadigを使って、PaSoRiをWinUSBドライバで扱うように変更する
  2. libusbをインストールする

zadigでドライバを差し替えられるのだが、libusbKやlibusb-win32という名前に引きつけられず、WinSUBを選ぶ。

image

デバイスマネージャでは、こう見えるようになる。

image

 

libusbは、ここから、「Downloads」をクリックするとsourceforgeに飛んでダウンロードされる。
このサイト、ずっと「libusbX」とばかり思っていたのだが、Xに見えていたのは単にケーブルがクロスしている画像だったのか?
いや、libusbxというサイトもあるな。まあいいや。

使うのはDLLファイルだけのようで、私は64bit環境なので、MS64\dll\libusb-1.0.dllになるだろう。
c:\Windows\System32にコピーするよう書かれているが、DLLってPATHのどこかに置けばよいのではなかったっけ。
まあ、試してダメだったらコピーしよう。


次は、bzrで最新版を取ってくるよう書かれているが、これはgithub版でいいや。
pipで取ってこれると書いてあったから、それでよいのかも。
最新のリリース版は、v0.11.1で、これが2016年4月29日。
うーん、半年以上経っているからgithubの最新版を使うことにしよう。

 

以前から気になっていたのだが、こういうライブラリには「setup.py」というファイルがだいたいついている。
これは何だろうか?
説明によると、配布する際の情報を書くようだった。
ということは、このファイルがあればPYTHONPATHなどに書かなくてもよいようにインストールできるのだろうか?

> python setup.py install

なんか、だーっと流れた。
「python27\lib\site-packages」に置いたというようなメッセージが出たので見に行くと、nfcpy-latest-py2.7.eggというファイルがあった。
eggって、卵?
まあ、いいや。


そして、もうexmaplesを動かす。
ここでは、examples/tagtool.pyというコマンドを動かすようだ。
なんとなく、タグを読むサンプルのような気がするので、PaSoRiの上にMIFARE Ultralightのカードを置いておく。

さっきのlibusb-1.0.dllは、うちではC:\Winappliというフォルダの中に置いているので、そこにパスを通す。

>set PATH=%PATH%;c:\Winappli

そして、実行。

>python examples/tagtool.py show
[nfc.clf] searching for reader on path usb
[nfc.clf] using SONY RC-S380/P NFC Port-100 v1.11 at usb:002:015
** waiting for a tag **
Type2Tag 'NXP NTAG203' ID=04079672B92981
NDEF Capabilities:
  readable  = yes
  writeable = yes
  capacity  = 142 byte
  message   = 0 byte

 

へー、これだけで動くんだ。
pynfcもだけど、汎用のUSBアクセスができるlibusbの力は偉大ですな。

 

もしかしたら、Ubuntu on Windowsでも動くのでは?と思ったが、今のところUSB機器をサポートしていないらしい。
http://stackoverflow.com/questions/38954691/is-usb-supported-on-bash-on-ubuntu-on-windows-10

実際、ダメだった。
今後のアップデートでストレージは使えるようになるかもしれないけど、libusbはどうなるか微妙なところだと思う。
好みの環境を作るのは難しいねぇ。

2016年11月4日

[win10]Bash on Ubuntuで大文字と小文字のファイルが作ることができた

今までWindows上では何かとcygwinを使って開発していたのだが、Bash on Ubuntuが使えるので、そろそろcygwinを使わなくてよいのかもしれない。
コマンドプロンプト風だと使いづらいので、TeraTermでcygtermが動くような感じで使えるとよいのだが。
SSHが動くという話を聞いたので、そのうち試そう。

 

Bash on Ubuntuのファイルシステムは、エクスプローラでパスを直書きしないと見えないようなところにあるのは分かったが、ext4みたいな扱いなのだろうか?
試すのは簡単なので、やってみた。

image

場所はc:\Tempというフォルダで、ドライブはWindows10 Homeプレインストールされている。
バージョンは知らないが、NTFSだ。

FAT32まではなんとなく仕様を把握していたのだが、このレベルでLFNにはならなかったはずだ。
cmd.exeで”dir /x”としても、違うファイル名があるわけではない。
ということは、少なくともNTFSでは大文字小文字で別に判断するようになったということだろうか。

エクスプローラでも別のファイル名として見えはするのだが、アクセスできるのは大文字のファイル名の方だけだ。
ここら辺は、FATの仕様を踏襲しているのかも。

[py]C言語風に書けない条件式

エスケープシーケンスはC言語と同じように書けたpythonだが、そんなことを気にせず書いていてエラーになったところがある。
条件式だ。

if (len(message) == 3) && (message[0] == 'K'):
  print 'けけけ'

とか、

result = some_boolean_method()
if !result:
  print 'oops!'

とか。

括弧の数が合っていないのでは、とか、前の方に書いた式がどこか間違っているのでは、とかとか、いろいろ調べて、ようやく&&やら||やらが無いということに気付いた次第だ。

 

否定はnotよりも!のほうがうれしいのだけど、論理積と論理和はandとorでいいんじゃないかな、と思う。
ぼーっとして、ビット演算の&や|と間違うことがたまにあるのでね。

[win10]Home版でWindows Updateは止まるか?

みんな悩んでいるWindows10のUpdateで勝手に再起動問題。
うちはPro版しか無かったので気にしていなかったのだが、最近Home版のPCを購入した。
もはや他人事とは言っていられない…。

なお、今回は新しいPCからブラウザで更新しているので、普段と見栄えが違うかもしれん。

Windows Updateはサービスだから、まずはサービスを止めてみた。
「スタートアップの種類」を「無効」にしたのだ。
まあ、一番確実そうな手段だ。

しかし、これはよろしくなかった。
自動での更新を止めて、手動でボタンを押して更新するように仕様と考えていたのだが、更新ボタンを押すとエラーになってしまったのだ。

そこで元に戻したのだが、よく見ると「手動」ではなく「手動(トリガー開始)」になっている。
調べてみると、トリガー開始というのはタスクスケジューラなどのトリガーで開始するようだ。


管理ツールのタスクスケジューラを開き、タスクスケジューラライブラリの中のMicrosoft/Windows/WindowsUpdateを開いた。
(どうでもよいことだが、「タスクスケジューラー」と延ばさないんだな。。)

そこには、項目が4つあった。
  • Automatic App Update
  • Scheduled Start
  • sih
  • sihboot
Appはストアアプリっぽいから生かして置いてもよい気がするが、よくわからんので4つとも無効にしてみた。
Windowsを再起動させても、無効は維持できているようだ。


これが効くかどうかは、よくわからん。
WindowsUpdateが確実に行われる日に動作しなかったら、たぶん効いているのだろう。
ただ、このタイマの2番目は、手動でWindowsUpdateを行うと開始されるようだ。
だから、手動で更新して、再起動する必要がないようであれば、サービスとスケジュールの両方を止めればよいような気がする。
サービスはsc.exeを管理者権限で呼び出せば止まりそうだけど、スケジューラはschtasks.exeで制御するのかね。

それかもう、スケジューラから設定を削除してしまって、サービスを止めるだけにしてしまう、という手段もとれるかもしれない
エクスポートして残しておけば心配は少ないのだが、忘れそうだ。。。

いっそのこと、スケジューラを使ってWindowsUpdate関連を定期的に止めてしまうようにしてしまえばよいかもしれん。
ただ、管理者権限で実行できるようにできるのかわからん。


まったく、再起動のタイミングを制御できないというだけで、ここまで苦労することになろうとは。。。

[2016/11/04更新]
だめだ・・・。
いつの間にかスケジューラが起動しているようだ。
現代の知識では、まだ克服できそうにない。

おそらく、Windows Updateの処理が始まってしまうと、再起動まで止めることはできないように思う。
気付けば再起動オプションで変更できるかもしれないが、数日放置するテストをしているときなんかは、気がつかないかもしれない。
であれば、何か長時間の処理を行う前にWindows Update関連を止めてしまえばなんとかならないだろうか。

そんなことを考えて、こういうバッチファイルを作った。

schtasks /change /TN "Microsoft\Windows\WindowsUpdate\Automatic App Update" /Disable
schtasks /change /TN "Microsoft\Windows\WindowsUpdate\Scheduled Start" /Disable
schtasks /change /TN "Microsoft\Windows\WindowsUpdate\sih" /Disable
schtasks /change /TN "Microsoft\Windows\WindowsUpdate\sihboot" /Disable
sc stop wuauserv
pause

最後のpauseは、結果を見たいだけだ。
これを管理者権限で実行すると、取りあえず書いている内容については止まるようだ。
だからといって、これでWindows Updateが停止できるかどうかというのは、また別の話だ。
さて、どうやって確認したものか。。。


[2016/11/05更新]

Scheduled Startタスクが強い・・・。

このタスクがいつも準備状態になるので削除したのだが、スリープから復帰するとタスクが生き返っていた。
スリープから復帰する程度で甦るんだったら、ずっと起動しているだけでも復帰させられてしまいそうな気がする。

 

それとは別の話だが、ちょうど今、新しいデバイスをUSB接続しようとしているので、その前後でタスクやサービスが自動で起き上がるか見ておこう。
なお、デバイスドライバを自動でダウンロードする設定は「いいえ」にしている。

 

いざ!
・・・あれ、デバイスマネージャで普通に認識されてしまった。
PaSoRi RC-S380だったのだけど、NFC Forum認証デバイスだけあって、既に組み込まれていたのだろうか?
ただ、NFC Port Softwareまではインストールさせなかったので、完全ではないだろう。

しかし、これはダウンロードしない設定だったからというよりも、ユーザに確認する画面で私が「いいえ」にしたからインストールされなかっただけで、自動でやらない設定にしていたためではないような気がする。
試しに、空のタグを置いてみたのだが、タグを認識した音が聞こえた。
うーん、もっと特殊なデバイスじゃないとわからんな。

そしてサービスとタスクスケジューラだが、タスクスケジューラに変化はなかったものの、Winodws Updateサービスは実行状態になっていた。
油断がならん。

直近のWindows Updateの日は、来週の水曜日だ。
何時くらいなのかは、PC依存なのか。。。
ということは、火曜日の寝る前に作ったバッチファイルを動かしてそれっぽいものを停止させ、PCを付けたまま寝て、翌朝確認すればよいのだな。
おっと、無操作のスリープや休止状態を無効にしておかないとな。
https://technet.microsoft.com/ja-jp/security/hh224643

2016年11月3日

[win10]ドライバの「ダウンロード」をしたのにインストールまでされた

単なる事例報告だ。

Windows10 Proを使っているが、自動的に再起動されると困るので、gpedit.mscでWindows Updateは「ダウンロード前に通知」にしている。
ダウンロードとインストールを別々に操作するのが多少面倒だが、作業している間にダウンロードしてしまって、終わったらインストール、というようにしている。
「ダウンロードしたら通知」もあるけど、ダウンロード自体したくないかもしれないのでね。

 

今日は起動すると通知が出てきたので更新内容の一覧を見ると、グラフィックドライバ1件だけだった。
異論は無いので「ダウンロード」ボタンを押したのだが・・・・インストールまでされてしまった。
グラフィックドライバがインストールされると、デュアルモニタで開いているウィンドウが1つに集められるし、ウィンドウサイズもVGAくらいに小さくなってしまうので、元に戻すのが面倒なのだ。

 

インストールを自動でされた理由がまだ分かっていないのだが、これだろうか?

image

 

別のことを調べてるとき、Windows10でExcelがうまく動かない現象は、プリンタのデフォルト出力先設定をOSが行うようにする(既定)を戻したら直った、という情報を見たこともある。
こういう風に、どの設定がどこに関わっているか分からないというのは、なかなかつらいものだ。

 

こうなった私の予想としては、今までWindows Updateをしなくて不具合が起きたことによるサポート電話とかがひどく多かったので、「ええい、うるさい!」ということでHomeを使っているユーザが一番多いだろうから強制的にインストールやらUpdateやらさせるようにした、というものだ。

来年の頭にまた大きいアップデートがあるらしいから、そこに期待するか。。
変更が柔軟になったのはそこそこ喜ばしいのだが、OSの基本機能が許容できる範囲になっていないとつらいものだ。

2016年11月2日

[py]エスケープシーケンスで16進数

pythonで16進数を扱うのに疲れてきた・・・。
前回classを作ってはみたものの、お仕事で作っているライブラリはもう終わりかけなのでわざわざ書き直す気になれないけれども、使っているとやっぱりミスをしばしば。。。

 

さて、今まで16進数をbytearrayに突っ込むのに、文字列で16進数を書いてdecode('hex')する、という技しか知らなかったのですが、エスケープシーケンスが使えることをようやく知りました。
今さらかよ、私・・・。

'1234'.decode('hex') ==> '\x12\x34'

うん、固定値の場合はこっちの方がわかりやすい。
いやぁ、いままで1byteのときも「'01'.decode('hex')」などと書いていて、げんなりしていたのだ。

まだ応用が利かないので、じわじわやっていくしかないですな。

 

 

この辺の書き方がC言語と同じなのは、興味深いところだ。
ただ、Cだとお尻に\0が付いてしまうので、{ 0x12, 0x34 }と書く方を私は使う。

使うのだけど、プロトコル中に埋め込む文字列を定義するときは、{ 'h', 'e', 'l', 'l', 'o' }などと書きたくないので、目をつぶって"hello"と書いて、sizeof()して1引いて使っている。

ろ、ROMに余裕が無いときは、ちゃんとやってますから!

2016年11月1日

[py]pyCharmのProject表示とStructure表示を別にする

pyCharmをほぼ初期状態で使っている。
キーバインドは覚えられないので、Eclipse設定にして、知っているものだけ使っているくらいで、ぜんぜん使いこなしている感じはしない。。

まあ、これからだ。

 

pyCharmは、初期状態だとだいたいこういうウィンドウ構成になっていると思う。

image

左側のTool Buttonsのところに、ProjectとStructureのボタンが並んでいる。
(まあ、Windowsだけか知らんが、文字が化けていて読めないのだが。。)

そのボタンを押すと、黄色の部分に表示される内容が、Projectだとファイル構成になるし、Structureだと関数一覧などになる。

 

しかし、右側が広く空いているのだ。
長い行数にするとエディタが警告してくるので、自然とテキストウィンドウエリアは幅を取らなくなってしまう。
もったいないので、右側にStructureを移せないだろうか?

 

調べて分かったのだが、Tool Buttonsのボタンはドラッグアンドドロップで移動できるようだ。
しかも、違う場所へも移動できる。
つまり、ウィンドウの右側にボタンを移動させることができるのだ。

そうすると、ボタンの近い方に窓が開いた。

image

そして、近い方の内容をちゃんと表示してくれるようだ。