記憶域プールでトライブルに見舞われたので覚書2

記憶域プールでトライブルに見舞われたので覚書に続いて、またトラブルに見舞われたので覚え書きを残しておく。

物理ディスクは正常

回復性の低下のエラーが出ているが、物理ディスクセクションは全て正常という状態になった。PowerShellからステータスを確認すると記憶域スペースは確かにDegradedモードになっているが、物理ディスクは全て正常になっている。

PS C:\WINDOWS\system32> Get-VirtualDisk

FriendlyName ResiliencySettingName OperationalStatus HealthStatus IsManualAttach Size
------------ --------------------- ----------------- ------------ -------------- ----
RAID5        Parity                Degraded          Warning      False          3 TB


PS C:\WINDOWS\system32> Get-PhysicalDisk

FriendlyName       SerialNumber         CanPool OperationalStatus HealthStatus Usage            Size
------------       ------------         ------- ----------------- ------------ -----            ----
USBHDD1            0123456789ABCDEF     False   OK                Healthy      Auto-Select   1.82 TB
USBHDD2            0123456789ABCDEF     False   OK                Healthy      Auto-Select   1.82 TB
USBHDD3            00000000354340b930b5 False   OK                Healthy      Auto-Select   1.82 TB

例によってRepair-VirtualDiskは正常に終了して何も教えてくれない。物理ディスクを追加してもDegradedモードから戻らない。前回と異なりchkdsk -rで全セクタのチェックを行っても正常となる。

一見すると正常に使えているのだが、どうも管理領域が破損している物と思われる。仕方が無いので、再び前回と同じように、新たな記憶域スペースを作成してデータを移動したあと、既存の記憶域スペースを削除する事で対応することにした。

せっかく便利な機能なのだから、もうちょっとなんとかならないのだろうか。

VBAを今後どのように扱ったら良いか?

VBAはエンドユーザーコンピューティングとして優れたプロダクトだと思っている。ほとんどのユーザーが購入して持っているであろうOfficeアプリケーションさえインストールされていれば開発できる。高価なミドルウェアを購入したり、面倒なコーディングをしなくても標準でレポーティングツールや、データベースだって利用できる。このような言語は中々代替えがないのだが、VBAと離別すべき時も刻一刻と近づいている。

今VBAが置かれている現状を整理したい。

ActiveX Data Object(ADO)

VBAから直接データベースに接続するにはADOぐらいしか選択肢がありません。にもかかわらずADOのサポートは停滞したままで、ADO2.8がリリースされて以降は新たなリリースがありません。機能的にはSQLServer2005で止まっていて、それ以降に追加された型には対応していません。たとえばXML型とかGEOMETRY型を扱うことができません。特にSQL Azureの動作対象リストからはADOやDAOが外されており、別の方法で接続する事を求められます。
唯一幸いなことは、ADOのコンポーネントはOSとともに配布されているので、OSのサポートが終了するまではセキュリティアップデートが提供され続けることです。

ADO以外の方法でデータベースに接続しようとすると、VBA以外の言語でコードを書く必要が出てきます。どんな手段が考えられるでしょうか?

XML WEBサービス

Visual Studio .NETでは容易にXML WEBサービスを作成する事ができます。これをVBAから呼び出す方法が考えられます。
しかし残念なことに無償で使用できるExpress版ではWEBサービスを開発できません。最も安価なVisual Studio 2015 Professionalでも6万円台になります。エンドユーザーコンピューティングを考えたときに6万円超の負担は避けたいところです。Community版があるじゃないかと考えるかもしれませんが、ライセンス的に業務利用は難しいので対象外とします。
もうひとつ問題となるのがXMLパーサー部分です。XML WEBサービスを使用するクライアント用にMicrosoft SOAP Toolkitが配布されています。しかしながら、このコンポーネントは標準ではインストールされていないため「Officeさえインストールされていれば動作する」と言う利点を失います。
Windowsに標準でインストールされているMSXMLをパーサーとして使用する方法もありますが、MSXMLはInternet Explorerのモジュールです。そしてMicrosoft EDGEはMSXMLに対応しないことがアナウンスされています。将来性を考えるとこれも避けたいところです。

根本的な問題はVBAがCOMを基幹技術としているところです。Microsoftの基幹技術は既にとっくに.NETに移行しており、旧技術であるCOMは完全においていかれています。もういっそ、VBAは完全にあきらめて、VB.NET等の他言語で作成するというのはどうでしょうか?

Microsoft Office Interop

Visual Studioで作成したアプリケーションからMicrosoft Office Interopを使用してOfficeアプリケーションを操作する方法があります。幸いなことにOffice InteropはExpressエディションからも使用できるので追加投資も不要です。.Net Frameworkのバージョンを適切に選択すれば、実行ファイルをコピーするだけでも動作することが多く、展開も手軽です。
しかしながらOffice Interopはお世辞にも使いやすいlibraryではありません。単純なCOMのラッパーなのでインスタントの解放はプログラマーの責任で記述する必要があります。実際にコードを書くとインスタンスの生成と解放ばかりになって効率が悪いです。ライブラリが不出来なのが要因でコーディングの難易度が上がるのは、エンドユーザーコンピューティングでは避けたいところです。

Visual Studio Tools for Office(VSTO)

.NETでOfficeのプラグインを作成するために提供されたミドルウェアです。作成したプラグインを動作させるにはインストール作業が必要になるため展開はやや面倒になります。残念なことにVSTOもExpress版では使用できません。

Apps for Office

.NETでOfficeのプラグインを作成するために提供されたミドルウェアです。作成したプラグインを動作させるにはインストール作業が必要になるため展開はやや面倒になります。残念なことにApps for Office もExpress版では使用できません。

ClosedXML

ClosedXMLは Microsoft Open XML Formatのファイルを読み書きできるオープンソースの.NET用のミドルウェアです。Office2007以降ファイル拡張子がXMLXやDOCXに変更され、ファイル仕様が完全に公開されるようになりました。もちろんExpress版からも使えます。
この辺りが現実解では無いでしょうか。VBAを扱っていた経験があるなら、VB.NETに慣れるのもそれ程時間はかからないでしょう。Powersellから呼び出すのも面白いかもしれません。PowersellはWindows7以降に追加された、OSの操作に使用する言語です。Powersellからしか設定できない項目などもあり、Windowsを使う上で覚えておくととても便利です。

Excel REST API

https://channel9.msdn.com/Events/Visual-Studio/Connect-event-2015/315
まだPublic preview段階ですが、OneDriveやOffice365のクラウドストレージに保存したExcelファイルを編集するためのWebAPIです。現在、新しいOffice製品はクラウドストレージとの連携を前提として開発されています。WebAPI経由なら言語は選びませんし、各種のオープンデータとの連携も取りやすくなります。もしかしたらエンドユーザスクリプトの主流になるかもしれまけん。

VSTOやApps for Officeには無償でProfessional相当の機能を使えるCommunity版という選択もあるのですが、商用利用は著しく制限されているため、業務でのエンドユーザーコンピューティングには使いにくいです。私の場合には、ぐるっと回って「C#デスクトップアプリケーション + LINQ for MSSQL + ClosedXML」で組んでいくことにしてみました。

参考:
Roadmap for Apps for Office, VSTO, and VBA(http://blogs.msdn.com/b/vsto/archive/2013/06/18/roadmap-for-apps-for-office-vsto-and-vba.aspx)

.NET Framework 3つのDB接続方法の使い分け

.NET FrameworkではADO.NET、LINQ to SQL、Entity Frameworkの三種類の接続方法が提供されています。どの接続方法を選択するのが良いのでしょうか?

ADO.NET

もっとも古くから提供されている接続方法です。
原則としてSQL文を直接記述するので、SQL Serverのすべての機能を利用することができます。一方で静的型チェックなどの恩恵を受けることが難しい(型付きDataSetを使えば可能だが面倒)のでコーディング効率が落ちそうですが、ユーザーコントロールとのデータバインディングを使用すればコーディング効率も決して悪くはありません。

LINQ to SQL

SQL Serverのスキーマを元にクラスを自動生成する簡易的なORマッパーです。
原則として自動生成されるSQLを使うことになるので、一般的なORマッパーと同じく非効率なSQL文が生成される事によるデメリットもあります。その一方で一旦データベースから取得したデータに対して、さらに検索や集計をかける事も容易にできるのでうまく活用すればデータベースの負荷を下げる可能性もあります。静的型のチェックによる恩恵もあるのでADO.NETに比較してコーディングは楽になるでしょう。
.NET 3.5から提供されていますが、その後は殆どアップデートされておらず、プロダクトの継続性に疑問符が付きます。

Entity Framework

LINQ to SQLとほぼ同時期、.NET 3.5 SP1から提供されている接続方法です。
Entity Frameworkはクラス設計を元にSQL Serverのスキーマを生成するORマッパーです。先にクラス設計を行うので既存のデータベースに対して利用するのは難しく、利用できるのは新規に設計するときに限られます。また逆にEntity Frameworkを使わずにSQL Serverにアクセスする必要が生じた場合に苦労する可能性があります。

何を使えばよいのかは時と場合によります。私は静的型のチェックによる恩恵を得られ、既存データベースへ適用できる点でからLINQ to SQLの活用機会が多いです。

Windows 記憶域プールは使わない方が良い

Windowsの記憶域プールは追加投資無しでRAID0~6相当のドライブを作ってデータを保護でき、 シン・プロビジョニング(後からディスクを追加して容量を増やしたりできる)にも対応している。USB3.0を使用すれば多数のドライブを接続できるし、SSDと併用して高速化もできる。設定もGUIベースで簡単にできる。良いことづくめに見えるが、私は他者に記憶域プールの使用は進めない。

管理機能の不足

Windowsの記憶域プールのGUIは管理機能を殆どで提供しない。異常が発生しても「壊れています」以上の詳細な情報はGUIでは把握できない。標準GUIで把握できない事態に陥った場合には、PowerShellというWindowsの独自言語を使ったプログラミングが必須となる。この時点で初心者はお手上げになってしまう。

復旧機能の不足

致命的なことに復旧機能がほとんど提供されていません。ディスクの異常が発生して修復に失敗してしまうと、記憶域プールに作成した仮想ディスクを破棄して作り直す以外の方法がありません。これはPowerShellを使っても同じで、Repair-VirtualDisk(自動修復を実行する)というコマンド以外に普及方法が提供されていません。
一般的なハードウェアRAIDであれば強制的にミラーを解除して再構成をすることも出来るのですが強制的に解除するコマンドは用意されていないのです。これでは上級者でもお手上げになってしまいます。

RAID1対応のNASでも安いものなら2万円を切る価格(除くHDD)で購入できることを考えると、安価なRAID対応NASを使うほうが良いでしょう。

ClosedXMLでSortによる並び替えができない

Microsoft Excelで作成したxlmxファイルをClosedXMLで開いて捜査している場合、Sortメソッドによる並び替えに失敗する場合があります。ソートしようとしている範囲内にClosedXMLが対応していない書式情報があるのが原因です。Microsoft Excelでファイルを作成するときに並び替え範囲内の書式を削除しておくと、正常に並び替える事ができます。

Windows Server 2012でVB6.0のアプリケーションを動かす

Support Statement for Visual Basic 6.0 on Windows Vista, Windows Server 2008, Windows 7, Windows 8 and Windows 8.1, Windows Server 2012, and Windows 10」に互換性に関する情報があります。このページに「Supported Runtime Files to Distribute with Your Application」として動作保証されている再配布ファイルのリスト(全言語共通の物と、日本語など言語固有の物にリストが分かれています。)が公開されています。このファイルを別のフォルダにコピーしていきます。

また上記のリストではOSに付属していることになっていますが、msvbvm60.dllはWindows 2012に含まれていませんので、これもコピーします。

Visual Basic 6.0 Service Pack 6:ランタイム再頒布可能パッケージ (vbrun60sp6.exe)」をダウンロードします。ダウンロードしたVB6.0-KB290887-X86を解凍するとvbrun60sp6.exeが得られます。vbrun60sp6.exeのインストーラはCAB形式の自己解凍ファイルになっています。vbrun60sp6.exeを解凍すると、vbrun60sp6.exeがインストールするいくつかのファイルが得られます。その内の「W95INF32.DLL、W95INF16.DLL、ADVPACK.DLL」はリストに載っていませんがコピーします。

用意したランタイムファイルをWindows Server 2012の適当なフォルダ(ここではC:\VB6Runtimeとします)にコピーします。システムのPATH設定にC:\VB6Runtimeを追加したあと、拡張子がOCXの物についてはregsvr32コマンドを使用してレジストリに登録していきます。C:\Windows\System32にコピーした場合はregsvr32コマンドに失敗します。C:\Windows\System32にはランタイムを置かないで下さい。

「Supported and Shipping in Windows Vista, Windows Server 2008, Windows 7, and Windows 8」に含まれているファイルを誤って配布しないように注意してください。C:\Windows\System32を見てもmsado150.dllやmfc40.dllが が見当たりませんが、規定のインストール先がC:\Windows\SysWOW64やC:\Program Files (x86)\Common Files\System\Ole DBに移っているだけで、きちんと存在しています。無闇に導入してしまうと別の問題を引き起こす恐れがあるので、Supported and Shipping~の対象は絶対にコピーしないでください。

VB6.0のランタイムをインストールするためのフリーウェアがありますが、それらはC:\Windows\System32に複製しても問題なかった時代に設計された物がほとんどのはずです。無闇に利用するとトラブルの原因となり得ます。同じ理由で昔自作したインストーラも危険です。気をつけましょう。

Windows7のデスクトップショートカットが削除される

Windows7のコントロールパネルにある「トラブルシューティング→設定の変更」にて、コンピューターの保守が有効になっている場合、定期的にスクリプトが動作してクリック先ファイルの見つからないショートカットや、一定期間使用していないデスクトップアイコンを自動的に削除します。

Google等で検索すると、対処方法として「コントロールパネルの設定で無効にする」とか、「レジストリのLinkResolvelgnoreLinkInfo、NoResolveTrack、NoResolveSearchを無効に設定する」とか、「TS_BrokenShortcuts.ps1を編集する」といった回答がヒットします。これらは当時緊急に模索された方法です。現在は解決方法としてMicrosoftからKB2642357が提供されいてるので、この情報にしたがって対応するのがよいでしょう。

解決方法は「KB2642357 :Broken shortcuts are deleted from the desktop in Windows 7(日本語訳は機械翻訳の質がすごく悪いので英語を読んだほうがよい)」に記載されています。ここで提供されているHotFixをダウンロードしてインストールしてから、記載内容にしたがってレジストリを編集します。

インストール手順

HotFixのダウンロードURLは公開されていないので、ダウンロードボタンをクリックした後、メールアドレスを入力してCAPTCHAによる認証を行います。その後、登録したメールアドレスにダウンロードURLを記載したメールが送られてくるので、そこからダウンロードします。

ダウンロードしたファイルは自己解凍の圧縮ファイルになっているので、適当なフォルダに解凍します。 解凍したWindows6.1-KB2642357-x86.msuをダブルクリックしてインストールします。

合わせて以下のレジストリ値を作成して設定します。

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\ScheduledDiagnostics]
"IsBrokenShortcutsTSEnabled"=dword:00000000
"IsUnusedDesktopIconsTSEnabled"=dword:00000000

グループポリシーでの展開方法

グループポリシーから行う場合には、Windows6.1-KB2642357-x86.msuをスタートアップスクリプトでインストールします。Windows6.1-KB2642357-x86.msuを共有フォルダに配置しておき、Windows Update Standalone Installer(wusa.exe)を呼び出す次のようなBATファイルを作成します。これをグループポリシーの「コンピューターの構成→ポリシー→Windowsの設定→スクリプト」にてスタートアップスクリプトに登録します。

@ECHO OFF
SET LOGFILE=%SystemRoot%\Logs\Windows6.1-KB2642357-x86.log

IF EXIST %LOGFILE% GOTO EXIT
md %SystemRoot%\Logs
echo "Windows6.1-KB2642357-x86.msuを適用しました。" > %LOGFILE%
wusa.exe "\\adsv\share\HotFix\Windows6.1-KB2642357-x86.msu" /quiet /warnrestart

:EXIT

合わせてレジストリの設定も必要になるので、グループポリシーの「コンピューターの構成→基本設定→Windowsの設定→レジストリ」にてIsBrokenShortcutsTSEnabledとIsUnusedDesktopIconsTSEnabledを作成するように設定します。

Adobe Flashをグループポリシーで配布するには

Adobe FlashをActive Dierctoryのグループポリシーで配布する手順をメモ

1.再配布ライセンスの取得手続き

Adobe Readerの再配布にはAdobeランタイム/Reader配布許諾契約(https://distribute.adobe.com/mmform/index.cfm?name=distribution_form&pv=fp&loc=ja)が必要です。リンク先のWEBページにて手続きをしてください。手続きを終えるとメールが送られてきます。

2.インストーラーのダウンロード

送られてきたメールにインストーラのダウンロードURLが掲載されています。当該サイトからMSI形式のインストーラをダウンロードします。

3.グループポリシーに登録する

MSIファイルが確保できれば後は簡単ですね。クライアントパソコンからアクセス可能な共有フォルダにMSIファイルを配置して、グループポリシーの「コンピューターの構成→ポリシー→ソフトウェアの設定→ソフトウェアインストール」にMSIファイルを設定すれば配布できます。

Adobe Reader DCをグループポリシーで配布するには

Adobe ReaderをActive Dierctoryのグループポリシーで配布する手順をメモ

1.再配布ライセンスの取得手続き

Adobe Readerの再配布にはAdobeランタイム/Reader配布許諾契約(https://distribute.adobe.com/mmform/index.cfm?name=distribution_form&pv=fp&loc=ja)が必要です。リンク先のWEBページにて手続きをしてください。手続きを終えるとメールが送られてきます。

2.Adobe Reader DCをダウンロードします
Adobe Acrobat Reader DCの配布(http://get.adobe.com/jp/reader/enterprise/)からOSの種類や言語を選んでインストーラをダウンロードします。

3.インストーラを解凍して共有フォルダに置

Adobe Readerのインストーラは7z形式の自己解凍圧縮ファイルとして作成されています。7zを扱える解凍ツールを使うと、インストーラに含まれているファイルを解凍する事でMSIファイルを得る事ができます。

4.グループポリシーに登録する

解凍したファイルをクライアントPCから参照可能な共有フォルダに配置します。 グループポリシーの「コンピューターの構成→ポリシー→ソフトウェアの設定→ソフトウェアインストール」にMSIファイルを設定すれば配布できます。

5.インストーラ修正プログラムの配布

このままだとバージョンのAdobe Readerがインストールされるだけで、最新のパッチは適用されません。先ほど解凍したファイルに含まれているインストーラー修正プログラム(MSPファイル)もインストールする必要があります。MSPファイルはスタートアップスクリプトから起動してインストールします。

ログファイルが作成されていなければインストールされるように、次のようなバッチファイルを作成して「C:\Windows\SYSVOL\sysvol\\scripts」などに配置します。

@ECHO OFF
SET LOGFILE=%SystemRoot%\Logs\AcroRdrDCUpd1500820082.log
SET ERRFILE=%SystemRoot%\Logs\AcroRdrDCUpd1500820082.err

ECHO "ログファイルの有無でインストール状況を判定し、インストーラを起動する"
IF EXIST LOGFILE GOTO EXIT
msiexec.exe /p "\\adsv\INSTALL\AdobeReader\AcroRdrDCUpd1500820082.msp" /qn /log %ERRFILE%

IF NOT ERRORLEVEL 0 GOTO EXIT
RENAME %ERRFILE% *.log

:EXIT

グループポリシーの「コンピューターの構成→ポリシー→Windowsの設定→スクリプト」のスタートアップに作成したバッチファイルを設定すればパッチが適用されます。

Java Runtimeをグループポリシーで配布するには

JREをActive Dierctoryのグループポリシーで配布する手順をメモ

1. インストーラのダウンロード

Java SEのDownloadサイトからJREをダウンロードする。ダウンロードするファイルはオフラインインストール用の実行ファイル(jre-8u60-windows-i586.exe、jre-8u60-windows-x64.exe)をダウンロードする。配布対象が32bit OSであればjre-8u60-windows-i586.exeだけでよい。jre-8u60-windows-x64.exeに32bit版ブラウザ用のプラグイン等が含まれていないため、64bit OSに配布する場合には jre-8u60-windows-i586.exe、jre-8u60-windows-x64.exeの両方が必要になる。

2.MSIファイルを取り出す

ダウンロードした実行ファイルを起動してインストール確認画面が表示されているときに、C:\Users\ユーザー名\AppData\LocalLow\Oracle\Java\以下を参照するとMSIファイルが作成されます。このMSIファイルをコピーして、グループポリシーからのインストールに使用します。なんと、これ、公式の手順です。「Active Directory を使用する JRE の配備(http://docs.oracle.com/javase/jp/7/technotes/guides/deployment/deployment-guide/install-msi.html)

3.グループポリシーに登録する

MSIファイルが確保できれば後は簡単ですね。クライアントパソコンからアクセス可能な共有フォルダにMSIファイルを配置して、グループポリシーの「コンピューターの構成→ポリシー→ソフトウェアの設定→ソフトウェアインストール」にMSIファイルを設定すれば配布できます。
配布対象が64bit OSの場合は、32bit版のJREと、64bit版のJREの両方をインストールする必要がある事に注意してください。