C#

.netでSFTPをしてみる 2

in

案件ではパスワードを使わず鍵だけでログインする仕様になりそうなので引き続き調べたところ、addIdentity()で鍵ファイル指定を追加してやるだけであっさりできました。(StrictHostKeyCheckingの設定はC# - SSH / SFTP connection issue using Tamir.SharpSshを参考にしました。)

private void sftp_pubkey_j
  (string host, string user, string identify,string passphrase,Int32 port)
{
  Tamir.SharpSsh.jsch.JSch jsch = 
    new Tamir.SharpSsh.jsch.JSch();
  jsch.addIdentity(identify,passphrase);

  System.Collections.Hashtable hashConfig = 
    new System.Collections.Hashtable();
  hashConfig.Add("StrictHostKeyChecking", "no");

  Tamir.SharpSsh.jsch.Session session = jsch.getSession(user, host, port);
  session.setConfig(hashConfig);
  session.connect();

  Channel channel = session.openChannel("sftp");
  channel.connect();

  ChannelSftp c = (ChannelSftp)channel;
  Tamir.SharpSsh.java.io.FileInputStream source = 
    new Tamir.SharpSsh.java.io.FileInputStream("a.txt");

  c.cd("temp");
  c.put(source, "a.txt");

  c.exit();
  session.disconnect();
}

ラッパークラスを使えばもう少しスッキリしたコードになるし、JavaXXXなんてのを目にしなくても良いです。

.netでSFTPをしてみる

in

FTP/SSLか、SFTPの実装が必要になりそうなので準備。C#でやろうと思っているので、FTP/SSLのほうは.net標準のFtpWebRequestにまかせてSFTPのほうをググってみたら

この2つが見つかりました。サンプルをザッとながめてみたらSharpSSHがのほうが簡単そうだったのでとりあえずサンプルコードを書いてみました。

private void runUpload()
{
  Tamir.SharpSsh.jsch.JSch jsch = new Tamir.SharpSsh.jsch.JSch();
  Tamir.SharpSsh.jsch.Session session = jsch.getSession("foo", "example.com", 22);
  UserInfo uinfo = new MyUserInfo();
  session.setUserInfo(uinfo);
  session.connect();
  Channel channel = session.openChannel("sftp");
  channel.connect();
  ChannelSftp c = (ChannelSftp)channel;      
  Tamir.SharpSsh.java.io.FileInputStream source = 
    new Tamir.SharpSsh.java.io.FileInputStream("xyz.txt");
  c.cd("temp/data");     
  c.put(source, "abc.txt");
  c.exit();
  session.disconnect();
}

public class MyUserInfo : UserInfo
{
  public String getPassphrase() { return null; }
  public String getPassword() { return "foovar"; }
  public bool promptPassword(String message) { return true; }
  public bool promptPassphrase(String message) { return true; }
  public bool promptYesNo(String message) { return true; }
  public void showMessage(String message) 
  { 
     MessageBox.Show
       (message, "SSH", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); 
  }
}

これ、Javaで実装されたjschのAPIを利用していてそこここにJavaの名前が見えるところが面白いっちゅうか世界は広い。暗号化関連はMentalis.org Crypto Libraryを使ってます。

サンプルではMyUserInfoのところをUI実装してごにょごにょしていましたが、僕の場合はそこらへんは不要なのでそのまま値を返すように変更。とりあえずテストはできたのでこれで検討してみます。後はパスワードじゃなくて鍵を使う場合のほうも調べなきゃいけないし、週明けもう少し詳しく調べてみる予定。

CocoaとC#のデリゲート

以前作成したアプリをv10.6SDKベースでコンパイルしたら警告がでました。何でかなーと思って調べてみるとアプリケーションで使用しているNSRuleEditorのdelegateメソッドがNSRuleEditorDelegateプロトコルに昇格(?)していました。なので、delegateメソッドを実装するクラスは<NSRuleEditorDelegate>しなければいけませんでした。ドキュメント10.6 Symbole Changesを見てみるとNSWindowはじめ多くのdelegateがプロトコル化されていることがわかります。

Objective-C 2.0でプロトコルでもオプション指定ができるようになったので、カテゴリ(非形式プロトコル)定義されていたデリゲートが形式プロトコル化されるのは自然な流れかもしれません。これまではよほど大量のデリゲートメソッドを実装するのでなければ、コントローラクラスの片隅にチョコっとデリゲートメソッド実装していましたが、オブジェクトの独立性や保守性を考えれば、今後はきちんとデリゲート用のクラスを作成するという方向になっていくのでしょう。

デリゲートといえば、前エントリでは嬉々としてデリゲート便利!などと騒いだ手前恥ずかしいのですが、冷静になってみるとInvoke(delegate)はやっぱり単なる「関数ポインタ」と言ったほうがいいのじゃないかと思ったりしてます。設計上の理由によりメソッドの実装を”他オブジェクトに譲(ってもいい|るべきだ)”とすることをデリゲートと呼ぶのであって、たとえばコールバックでの関数ポインタの代替として(文法上)のデリゲートとは意識的に分けて考えたほうが正しいあり方のように思います。

C#でサブスレッドからプログレスバーにアクセスする(デリゲート・ラムダ式は快適!)

in

C#/.Netへの移行は徐々に軌道に乗りつつあります。MFC時代は面倒だったクエリを別スレッドで処理しつつメインフォームのプログレスバーをインクリメントするのも簡単に実現できたので気分良くしてます。

スレッドを起こすのは実に簡単。引数も渡せます。

C#/.NET Frameworkに移行を決意。さらばVC++

in

悩んだ末、Windows系の開発環境をC#/.NET Frameworkに移行することに決めました。長らく親しんだVisual C++は世間的にも傍流へと向かいつつあるいま、慣れたVC++でもう少し行くかどうかは悩ましいところだったのですが、やはり"流れに棹さす"ために移行を決めました。とりあえず、Office2000系で作成されたアプリをC#/.NETに移植(というか書き直)すのが目下のミッション。一日かけてDB周りのコードとListViewあたりの感触をつかむためお試しコードを書いて遊びましたが意外とスムーズに移行できそうな予感がします。

気になっていた実行速度も意外や意外ベンチを取ったわけではありませんが体感的には十分速い。というかむしろVC++より速いのじゃないかという気がしました。それだけ僕の書いていたVC++のコードがイモでまだまだ最適化の余地が大きいということなのでしょう。.NETを使うことで最適化の恩恵をロハ(んな、分けないとは思うけど)で享受できるのはイイ取引な気がします。まぁ、勉強しなくてはいけないことは山とありそうですが、どこまで楽しめるか?ちょっと面白くなってきました。

コンテンツの配信