ODP.NETのGAC登録

/ .NET, Database

ODP.NETを利用している業務系アプリのWindows 8.1、Windows 10への対応作業中。(主に動作確認レベルですが)
アプリの導入手順としてOracle Clientをインストールしておけば動くはずなのですが、なぜか動きません。
原因はODP.NETがGAC(グローバルアセンブリキャッシュ)に登録されていないため。
ODP.NET(Oracle.DataAccess.dll)を静的参照している場合、それと分かるエラーメッセージなどが出ずにいきなり落ちてしまったりするので結構ハマりがち。
ちなみに少し面倒だけれどもリフレクションを使って動的参照の形で作るといきなり落ちるようなことは防げます。

.Net Frameworkのバージョンが2.0時代の古いアプリなので、Win8.1/10の場合、先にWindowsの機能に「.NET Framework 3.5(2.0)」を追加しておかないと、Oracle Clientのインストーラが.NET 2.0用のODP.NET DLLをGACに登録してくれません。
このような場合に後からGAC登録するには以下のコマンドを実行すれば良いとのこと。(パスは適宜編集してください)

Skylake問題などもあって、企業向けシステムのWindows 10対応が少し早まっているようです。
まぁ、そもそもWindows 7で動いていれば普通に動きそうなものなのですが、High DPIなどの対応まで考慮するとそのままでは厳しい部分もあったりなかったり。


The Big Red X

/ .NET

image
何だか格好良さげなタイトルですが、Windowsフォームアプリの例外関連の話。
上のような画面を見たことのある開発者の方もいるかと思いますが、フォームやコントロールの描画処理で何らかの例外が発生すると描画が中止されて赤い×マーク(バツマーク、バッテン)が表示されます。
通常はユーザコントロールなどの内部処理で落ちた場合などに発生するケースが多いと思うのですが、この×マーク、一旦表示されると元の表示状態に戻すのがなかなか難しく、普通は画面を開き直したり、アプリ再起動くらいしか手段がありません。
この問題を解決すべく、海外のWebサイトを徘徊した結果、見つけた回避策が以下の方法。

OnPaintイベントでわざとエラーを発生させて×マークを表示した後、ボタンクリックで再描画を行うサンプルです。
実際のアプリではOnThreadExceptionで×マークの原因となったスレッド例外を捕捉したら再描画、といった感じになるでしょうか。
ハイライト表示した箇所が強制再描画のくだりですが、リフレクションでSetStateなる内部メソッドを呼び出してエラー状態を解消するという、なかなかの荒業。
SetStateや0x400000の意味などはソースを直接覗くしか知るすべがないようです。
とりあえずVBで書いていますが、参考にさせていただいたこちらのサイトにC#で書かれたサンプルも掲載されています。
もちろん、根本的な描画時エラーを取り除いて×マーク自体を出現させないようにすることが先決ですので、どうしても解決できない場合の参考ということで…


Installer

/ .NET

image
業務で.NETデスクトップアプリの配布用インストーラを作成することがあります。
少し前までは.NET Framework 2.0ベースのアプリ開発が主流で、インストーラもVisual Studio 2005のセットアップウィザードを利用して作成していたわけですが、Windows 7がようやく主流になった昨今は.NET 4ベースのアプリをVS2010で作るようになってきています。
これに合わせてインストーラもVS2010のセットアップウィザードプロジェクトテンプレートを使おうと思ったのですが、実際に試してみるとインストール後の各ファイルのタイムスタンプがビルド時の日時ではなくインストーラ作成時の日時に変わってしまう不具合に遭遇。
こちらのフォーラムでも触れられているように、Windows XP上のVS2010でインストーラを作るとなぜか事象発生しないことは判明したのですが、いまさらXPを使うわけにもいかないので他の方策を検討することに。

最初に調べたのは最新のVS2013とひとつ前のVS2012ではどうなっているか、ということ。
しかし、2012以降のVisual Studioには従来のセットアッププロジェクトテンプレートは含まれておらず、ディスコン扱いになっている様子。
代わりに付いてくるInstall Shieldのサブセット版を試してみるも細かい設定ができないようでこれも却下。
諸事情により有償のフルセット版を使うこともできないため、一時はVM上のXPを使ってビルドするなどして凌いできたわけですが、少し前にようやく問題解決のソリューションを発見。

その名も「Visual Studio 2013 Installer Projects」というアドインです。
VS2013の拡張機能として登録するだけで、Windows Installer形式のインストーラが作成できます。
Windows 8.1上のVS2013に入れて試した限りでは、従来とほぼ同様の操作でインストーラの設定ができて、インストールしたファイルのタイムスタンプ問題も発生しない模様。
英語版しかないものの、作成したインストーラはこれまでどおり日本語表示されるので、特に問題なく乗り換えられそうです。
モノ自体はMicrosoftの中の人が作っているようですし、今後登場するVS2015への対応も期待できそうなので、当面これでやっていけそうです。


Office文書のPDF変換

/ .NET, C#

Offce2007以降、PDF形式へのエクスポートが標準でサポートされるようになりました。
というわけで、.NETアプリケーションからOfficeファイルのPDFエクスポートを実行する方法を紹介したいと思います。

静的な参照設定を行う場合は、必要なOfficeアプリのObject Libraryを参照設定しておいて、普通にVBAオブジェクトを.NETアプリから操作すれば良いわけですが、これだとそもそもOffice2007以降がインストールされていないPCでは参照エラーで正常動作しません。

そこで登場するのが遅延バインディング(Late Binding)という方法。
論より証拠、Excel→PDF変換のサンプルコードを載せておきます。

Word、PowerPointについても同様のイメージで実装できますが、Officeアプリによってそれぞれライブラリ仕様が異なりますので、流用できるのは基本的な流れ(アプリインスタンス作成→ファイルオープン→エクスポート→クローズ)だけになります。
そのため、少し面倒ですが、各OfficeアプリのMSDN Developer Referenceなどを参照してプロパティやメソッドの利用方法を調べつつ、実装していく必要があります。
VBAのオブジェクトをインテリセンス無しに記述して操作することになるので、とにかくパラメータの数や位置に注意が必要です。
リファレンス無しではまず作れないわけですが、どうも英語の資料しかなさげなのが厳しいところです。

ここでは単純にOK/NGを返すだけのメソッドになっていますが、実際にはエラー処理などの追加が必要になるかと思います。
また、パスワードロックされているOffice文書を開いた場合など、変換処理中にOfficeのウィンドウが表示されることがあるのですが、そのウィンドウが前面表示されないために操作感が悪くなってしまうケースが見受けられました。
これについては、Win32APIのFindWindow+SetForegroundWindowメソッドで最前面表示する手法を使うことによって回避できるようです。


コードスニペット

/ .NET

なんというか、今更感ありまくりですが、Visual Studioのコードスニペットの話。
正直、今までコードスニペットのお世話になることはほとんどなかったので(たまーにリファレンス代わりに出してみる程度)、スニペットの自作方法を知らなかったのですが、調べてみるとXMLでチマチマ書かなければいけない様子。
こんなん手打ちするくらいならコピペコードで済ませたるw、と言いたいところですが、最近のコードはお約束的な記述が必要な箇所がやけに多くてしんどいので、コードスニペット作成用のツールを物色。

で、使ってみたのが、VS2010の拡張機能マネージャでランキング上位に挙がっていた「Snippet Designer」。
英語のツールですが、基本的な使い方は簡単で、スニペット化したいコードを選択してショートカットメニューから「Export as Snippet」コマンドを実行すると、新しいウィンドウに編集画面が現れます。
データ型や変数を編集できるように設定したい場合は、編集画面で対象の文字列を選択してショートカットメニューから「Make Replacement」コマンドを実行すると、選択されている文字列がキーワードとなって置換設定ができるようになります。
また、プロパティウィンドウの「Shortcut」に適当なキーワードを設定しておくと、キーワードの一部+[TAB][TAB]押下でインテリセンス呼び出しができるようになるので、更なる入力効率向上が狙えます。
編集が済んだら、適当な名前をつけて保存すれば登録完了。
登録したスニペットは、「表示」-「その他のウィンドウ」メニューにある「Snippet Explorer」で検索、再編集することができます。