tsucchi’s diary(元はてなダイアリー)

はてなダイアリー(d.hatena.ne.jp/tsucchi1022)から移行したものです

C#でパスワードつきのexcel を扱う

仕事メモ。

C# でパスワードつきの Excel を取り扱おうとして、Excel._Workbook(だっけ?) の HasPassword()を使ってみたら、Open 時にすでにパスワードを聞いてくるダイアログが上がってしまいダメ。

Open 時に何とかするしかないなー、と思って MSDN 見ても書いてないし。。。

ぐぐってもあんまり情報がヒットしないし...(Open 時には、HasPassword() がダメってのは見つけたけど。。。つーか良く考えたら当たり前だしね。。。)

で、Excel.Workbooks の Open の引数ちゃんと見たら、パスワード(と書き込みパスワード)のフィールドがあるので、「おぉ、これか」と思ったけど、「パスワード指定されてたらほげほげ」みたいな指定ができなさそうだし、つーか「そもそもこの引数 Object 型だけど、いったい何型いれるんじゃ?」みたいな疑問も出てくる。。。(で、調べても出てこない。もーやだ、C#。。。)

「まあ普通に考えたら string だべ」と思い、とりあえず string でパスワード渡したらパスワードつきのファイルを開けた。

で、ココまでで道半ば。実は本当にやりたかったのは、「パスワード付の Excel だったらエラーとして落とす」処理。試行錯誤してみて、空文字列を渡したら動いた。(null と Type.Missing はダメだった)。パスワードが指定されていると例外を吐き、パスワードがかかっていなければ普通に開ける。

断片だけど、こんな感じ。(C#Excel のサンプルみれば、何をしてるかは大体わかるはず。DisposeResources は COM のリソースを開放してるだけです)

try
{
    book = xlBooks.Open(this.filename,
                        0,
                        Type.Missing, Type.Missing, "", "",//パスワードを空としておく
                        Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
                        Type.Missing, Type.Missing, Type.Missing, Type.Missing);

    sheets = book.Worksheets;
    sheet = (Excel.Worksheet)sheets.get_Item(1);
}
catch ( COMException come)
{
    DisposeResources();
    if ( come.Message.StartsWith("入力したパスワードは間違っています") )//本当はエラーコードで拾いたいのだけど、これしか方法が無さそう...
        throw new System.Security.SecurityException("Password Mismatch");
    else
        throw;
}

コメントにも書いているけど、COMException のエラーコードで拾えないのが残念な感じ。(他のエラーなのに、番号が同じものがあるっぽい。ファイルが見つからないエラーとか)

つーか、C# の Office 開発関連のドキュメント雑すぎ。MSDN は情報足りないし、どっかに載っているのかも知れんけど、どこ見れば良いのかさっぱり分からん。。。