ネットワークドライブとWebDAV over SSL

Windows7だとWebDAVをネットワークドライブとして割り当てることができるので、ログオン時はいつも再接続させたい・・・のですが、クライアント認証を使ってアクセスする関係上、自動的に再接続できません。「ログオン時に再接続する」にチェックを入れているのですが、「再接続できませんでした」とかなんとかいうメッセージが出てエラーになってしまいます。

というわけで、今まではデスクトップに、以下のようなコマンドファイルを置いてその都度ダブルクリックすることで回避してました。

;---- allocate_network_drive.cmd ----
net use M: https://webdav_over_ssl/my_folder/
start M:

ただ、ダブルクリックすると、コマンドプロンプトのウィンドウが出たりして、なんかスマートじゃありません。。。

net use なんちゃら の部分を、自前でコーディングすれば事足ります。幸いにも、Windows API には WNetAddConnection2() という便利なAPIがあるので、このAPIをコールすれば一発でできそうです(^^)

早速、C++超手抜きネットワークドライブ・クラスを書いてみました。今年から積極的にC#を使おうとか、宣言しながら、早速C++使ってます。すみません(笑) 直接API叩くのがカンタンなので・・・。

#pragma comment(lib,"mpr.lib")
/**********************************************************
 簡易ネットワークドライブ・クラス 
 NetworkDrive.h
***********************************************************/
#include <windows.h>
#include <strsafe.h>
#include <tchar.h>

class CNetworkDrive
{
private:
  PTSTR m_strURI;
  PTSTR m_strDevice;

public:
  //コンストラクタ&デストラクタ
  CNetworkDrive(PCTSTR uri,PCTSTR device)
    {
      m_strURI    = CreateAndCopyString(uri);
      m_strDevice = CreateAndCopyString(device);
    }
  virtual ~CNetworkDrive()
    {
      DestroyString(m_strURI);
      DestroyString(m_strDevice);
    }

  DWORD Allocate(bool bRemember = false)
    {
      NETRESOURCE NetResource = {0};

      NetResource.dwType       = RESOURCETYPE_DISK;
      NetResource.lpLocalName  = m_strDevice;
      NetResource.lpRemoteName = m_strURI;
      
      return WNetAddConnection2(&NetResource,NULL,NULL,CONNECT_INTERACTIVE | (bRemember ? CONNECT_UPDATE_PROFILE : 0));
    }
  
  DWORD Cancel(bool bUpdate = false,bool bForce = true)
    {
      DWORD dwFlags = bUpdate ? CONNECT_UPDATE_PROFILE : 0;
      BOOL bwForce = bForce ? TRUE : FALSE;

      return WNetCancelConnection2(m_strDevice,dwFlags,bwForce);
    }

//雑関数
private:
  static PTSTR CreateAndCopyString(PCTSTR src)
    {
      DWORD dwNum = 0;
      PTSTR dest = NULL;
      
      if((dwNum = lstrlen(src)) > 0)
        {
          dest = new TCHAR[dwNum+1];
          StringCchCopy(dest,dwNum+1,src);
        }
      
      return dest;
    }

  static void DestroyString(PTSTR str)
    {
      if(str)
        delete [] str;
    }
  
};

これを、使って、以下のようなテストコードで試してみたところ、うまく行きました。

#pragma comment(lib,"user32.lib")

#include <windows.h>
#include <tchar.h>
#include "NetworkDrive.h"

#define URI TEXT("https://my_webdav_site/my_folder/")
#define DEVICE TEXT("Z:")

//スタートアップ
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
  return MessageBox(NULL,
                    (CNetworkDrive(URL,DRIVE).Allocate() == NO_ERROR) ? TEXT("接続しました。") : TEXT("失敗ました。"),
                    TEXT("メッセージ"),
                    MB_OK);
}

最初、エラーで接続できなくてググっても分からず、全く原因が分からくて途方に暮れてたのですが・・・結局ドキュメントを見落としてました。。。英語なんでサラッと流し読みしたのが悪かった(^_^;)

WNetAddConnection2 APIに渡す最後の引数のフラグに、CONNECT_INTERACTIVE を指定していなかったのが原因でした。これを指定することで、クライアント証明書選択ダイアログ(っていうのかな?)が出て正常に認証が済み、無事ネットワークドライブを割り当てることができました。

やっぱりドキュメントはちゃんと読まないといけませんねぇ・・・

今年はC#を本気で使っていこう

と、思ってます(^^;

本来は年始の挨拶ですが、喪中なので、「寒中お見舞い申し上げます」 です(m_m)

C#はちょこちょこと触ってつまみ食い程度に使っていたのですが、JScript/Perlなどの便利なLL言語の手軽さに負けてあまり本気で使っていなかったのですが、とある解説本を読んでC#に傾倒しつつあります。

C# 3.0 になって、これまでのC# 2.0 のときに感じた僕の不満点が一気に解決されていました。特にラムダ式とLINQは、非常に煩わしいコード記述を、まるでスクリプトを書いているような感覚で、うまく使えば非常に読みやすいコードの記述ができる武器になりそうです。 普通ならスクリプトで組むようなものでも、これからは気軽にC#を使っていこうかな、と思うようになってきました。

C#といえば、事実上、Windows の .NET Framework上でしか動作しない、という認識でしたが、オープンソースで開発されている Monoをインストールすれば、Windows以外のプラットフォームでも十分使えるようです。CentOSに mono をインストールして、Windows上でビルドしたプログラムが動くかテストしてみましたが、すんなり動くことにちょっと感動しました(笑) フォームを使ったものも含めて、完全に互換性が保てるようになれば、状況が変わると思いますねぇ。

いままでは、どんな小さなプログラムでも、使うか使わないかは別にしてWebサーバーでの使用も考えて、Perl や PHP を使ってコーディングすることがほとんどでしたが、Mono がもっとオープンソース系のサーバー系OSで普及してくれれば、今まで以上にC# を気軽に使えるんですがねぇ~。どうなんでしょうねぇ~。

よくC# と Java は設計思想が似てて、言語的にC#はJavaを真似してる、という意見もありますが、C# を知れば知るほど、Javaとは全く違う言語だということが分かります。

いろんな意見がありますが、僕的に思うことは、 趣味でプログラムするなら、JavaよりC#の方が断然面白い、です。

が、ちょっと、「それはやりすぎじゃね?」 と思うこともあります。
たとえば・・・

/* C# 2.0のときは、*/
List&lt;string&gt; a = new List&lt;string&gt;();

と記述しますが、C++のtemplateときもそうだったんですが・・・同じ語が繰り返し出てきたりして、ずーーーーーと前から不満でした。が、 C# 3.0になって var キーワードが使えるようになったおかげで、スマートに書くことができますよね。

/* C# 3.0 では・・・*/
var a = new List&lt;string&gt;();

これはいい。a の型をコンパイラが考えてくれる。

/* でもこれは・・・すでに何をやってるのか僕には見当もつきません(^^;;;*/
var ar = new[]{1,2,3};

/*  これは下と同じですが */
int[] ar = new int[]{1,2,3};

/* こっちの方がわかりやすいし何をやっているかも一目瞭然だと思うのですが・・・。 */
var ar = new int[]{1,2,3};

こんなやりすぎ感が漂う C# ですが、Perl ほどワケワカメな書き方はできないし、この、程々のやり過ぎ感がちょうどいいんじゃないかと思います(^^;;;

.NET Framework のライブラリが膨大すぎて、必要なクラスがどの名前空間にあるか、すでにライブラリ・クラスの海の中におぼれかけてますが、今年からC#を極力使っていきたいと思います。

でもWindowsでちょっと凝ったことしたいときは、やっぱり Windows APIを直接叩く必要があるのを、次のWindows8でどうにかしてほしいです。。。

MySQL Connector/.NETのインストールが失敗する

Visual C# 2008 Express Editionで以前作ったフォームを使ったちょっとしたアプリを、ちょこっとと修正しようと、Subversionのレポジトリからチェックアウトしてプロジェクトを開いたら、MySQL 関連の参照が切れている、という警告がでました。

そういえば、XPからWindows7にバージョンアップした際に、MySQL Connector/.NETを入れ忘れてたのを思い出して(^^;;; MySQLのサイトからConnector/.NETのGAリリースの最新版(6.3.5)をダウンロードしてインストールを試みたのですが・・・

なぜか、インストール途中でエラーが発生し、ロールバックされてインストールされません。。。

ん?なんで? Visual Studio 2008環境下でのインストールエラーが結構検索で引っかかってきます。これってインストーラーの不具合なのかなぁ?

ちょっと検索してみたけど、解決方法が見つからず・・・古いバージョン(5.2.7)のものがまだ配布されていたのでこれをダウンロードしたらちゃんとインストールされました。

最新のConnector/.NETはVisual Studio 2008環境はサポート外なのかなぁ・・・・?ちょっと時間がなかったので詳しく調べなかったけど・・・

Visual Studio 2010にバージョンアップすればいいんでしょうけど、、、なんか動作が重いっていう話ですし・・・。

う~ん・・・

ブラウザでレポジトリ管理

Windows7を起ち上げたら、Windows Live Essentials 2011の更新が。。。更新してWriterを起ち上げたら・・・ああ! リボンUIになっとる!(怒) (^^;;;; う~ん・・・前のUIの方が良かったな。。。画面がワイドなので、ウィンドウ上部にメニューやボタンやらあるより、ウィンドウ横方向(サイド側)に持ってきた方が、作業領域が大きくなってイイと思うんだが・・・・。ノートPCの狭い解像度だとこれが致命的なんですよね・・・。

そんなことはどうでもよく・・・。

SubversionのレポジトリをVPSサーバーに置くことで、WindowsクライアントからTortoiseSVNを使ってソースコードの管理ができると、ネット環境があればどこからでもノートPCを使ってゴニョゴニョできるので便利です。

現状、レポジトリの置き場をUSBメモリにしているのですが、持ち歩かないと行けないし、無くしたり、落としたり、どこかに忘れてきたりすると非常に困るわけです。

このレポジトリをVPSに置いて運用したいと思い、レポジトリ自体の管理を行うブラウザベースの管理システムを探しました。探したと言ってもググっただけですけど(^^;;;、見つけたのは2つ。

  • USVN 
    【 http://www.usvn.info/ 】
  • Submin
    【 http://supermind.nl/submin/index.html 】

ここでいう管理というのは、あくまでレポジトリ自体の管理・・・要は svnadmin コマンド のフロントエンドみたいなイメージです。

ブラウザベースで管理できる機能で僕が欲しいのは・・・

  • レポジトリの作成・削除
  • レポジトリをhttpsアクセスできるように設定
  • レポジトリをホットコピーとアーカイブ(圧縮)化とそのダウンロード
  • レポジトリのダンプをダウンロード(圧縮)
  • ユーザー管理

とまぁ、これぐらい、自分で組めよ、と言われそうだけど・・・。

まだ、両方とも試せてませんが、週末にでも試してみて、両方とも使えなさそうなら、自分でカンタンなUIを作ろうかな、と思ってます。

とりあえず、早く会社のサイトを仕上げてしまわないと・・・。

ああ、いいかげん VC2008EE を Visual Studio 2010 Express へバージョンアップしたいし・・・開発マシン用に安PCを一個買おうかなぁ・・・。う~ん・・・またグチで終わってしまった。。。

ファイルをバラバラにして分散保存

任意のファイルを任意のサイズ(or ランダムサイズ)で分割して、複数のサーバーに分散して保存したい。

まずグーグル先生に聞いたけど、聞き方(検索の仕方)が悪いのか、なかなか見つからない。「分散ファイルシステム」とかがいっぱい検索結果に出てくるけど、求めているのとは全く違う。

ん~、やっぱり簡単な方法でいいから、自分で組むしかないか・・・と思って、下のような感じにしたいと思い、仕様を考え始めたんだけど・・・ちょっと大げさになりそう感じが・・・(--;;;

ファイル分割

要は、元のファイルを簡単な暗号を施して、バラバラにして、各サーバーへ放り込んでくれればいい。その際散らばったファイル群を元に戻すための情報をエクスポートしておけば、元に戻せる。ただそれだけ。

おおざっぱに・・・

  • 暗号化する処理
  • バラバラに分割する処理
  • 分散して保存する処理
  • 分散したファイルを集める処理
  • バラバラにしたファイルの正当性を検査する処理
  • バラバラのファイルを統合する処理
  • 復号化する処理 と、こんな感じでしょうか。

欲を言えば、ファイルだけじゃなくてバイト列(ストリーム)に、とか、任意の暗号化処理を選択・追加したいとか、やりだすと、抽象化を行わないといけないし・・・どこまで手を出すべきか・・・

ある機能の仕様を決めるってホント、メンドクサイですね・・・(^^;;; ちょこっと使えればいいだけなんだけど・・・考え出すと泥沼にはまり込んでしまいます。

実装言語はどうしよう・・・Perlか、C#か・・・。

来週の連休中にでもやるか。。。