2011年11月23日

そうだ、SkyDrive、やろう

ご無沙汰です。
最近HDDが高いっすなー、2~3倍近くまで跳ね上がってるものもあるようで
年末こそは新しいPC作ろうと思っていたのですが
HDDの値上り以前に年末の賞与もとい寸志
ほぼ0というレベルのため中止となりましたΣ(T□T)

さらに最近コードを書く仕事が入ってこないので、
非常にコーディング欲が湧いています。
何が悲しくて他社製品のER図とかDFD書かなきゃなんないんだよと(;-_-) =3 フゥ

で、いくつか作ってみたいツールのネタが出たので
欲求不満解消+HDD買えない憂さ晴らしに作ってみた。

その名も

SkyDriveのアカウントを管理して、ついでにワンクリックでログインしちゃうツール


えーっと、機能としてはこれらを満たすように作ったつもりです

1:SkyDriveのアカウントとパスワードを一覧で管理できる
2:ワンクリックでログイン処理が実行できる
3:ログインしたらざっと中の様子を見れる+ちょっとしたファイル操作ができる
4:最後にいつログインしたかが分かるようにする
5:無料

自動でログイン→自動ログアウト機能をつけるべきか迷ったのですが
そういった機能を自分は欲していないので今回はなしとしました<(_ _)>
まあ、あまり自動化しすぎるとSkyDrive側の仕様変更に対応できなくなるし

画面としてはこんな感じです。


SkyDriveは1アカウントで25GB使えるので、
1アカウント20GBの利用量でも5アカウントで100GBいく計算ですな
無限に作れるメールアカウント用意すれば理論上は無制限なファイルスペースが・・・
※あくまでも理論上です。SkyDriveは使用上の注意をよく読み、用法用量を守って正しくお使いください

で、ここから重要です。

どうもこのツール。起動時にインターネット通信を行うためか
ノートンのSONARにマルウェアとして誤検知されますΣ(゚д゚lll)

怪しい処理は何一つしていませんが?ノートン先生?
その証拠としてソースコードも公開しちゃいますよ?

namespace SkyDriveLoginAssistant
{
 public partial class Form1 : Form
 {
  public Form1()
  {
   InitializeComponent();
  }

  private void button1_Click(object sender, EventArgs e)
  {
   //とりあえずテーブルがちゃんと選択されているか確認
   int SelectRowNumber = 0;
   SelectRowNumber = dataGridView1.CurrentCell.RowIndex;
   if (SelectRowNumber < 0)
   {
    return;
   }
   //データを変数にfade-in
   string id = dataGridView1[1, SelectRowNumber].Value.ToString();
   string pass = dataGridView1[2, SelectRowNumber].Value.ToString();

   //入力ボックスにそれぞれ値をセット
   webBrowser1.Document.All.GetElementsByName("login")[0].Focus();
   webBrowser1.Document.All.GetElementsByName("login")[0].InnerText = id;
   webBrowser1.Document.All.GetElementsByName("passwd")[0].InnerText = pass;

   HtmlElementCollection all = webBrowser1.Document.All;
   HtmlElementCollection forms = all.GetElementsByName("SI");
   forms[0].InvokeMember("click");


   //ログインボタンをクリック!
   //webBrowser1.Document.Forms[0].InvokeMember("submit");





  }

  private void button2_Click(object sender, EventArgs e)
  {
   //リストを保存
   //本当はDataGridViewにDataSourceを設定してXML出力したほうが楽
   //でも、ファイルを直でメンテしたかったりするので、あえてCSVをループで出力させる

   string line = string.Empty;
   Encoding enc = Encoding.GetEncoding("Shift_JIS");
   System.IO.StreamWriter sr = new System.IO.StreamWriter(@"ACLIST.csv", false, enc);
   int colCount = dataGridView1.Columns.Count;
            int rowcount = 0;
   
   foreach (DataGridViewRow row in dataGridView1.Rows)
   {
                rowcount++;
                if (rowcount == dataGridView1.Rows.Count)
                {
                    break;
                }
    for (int i = 0; i < colCount; i++)
    {
     //フィールドの取得
     string field;
     if (row.Cells[i].Value == null)
     {
      field = string.Empty;
     }
     else
     {
      field = row.Cells[i].Value.ToString();
     }
     //"で囲む必要があるか調べる
     if (field.IndexOf('"') > -1)
     {
      //"を""とする
      field = field.Replace("\"", "\"\"");
     }
                    if (i == 0 && field == "0")
                    {
                        break;
                    }
     field = "\"" + field + "\"";
     //フィールドを書き込む
     sr.Write(field);
     //カンマを書き込む
     if (colCount-1 > i)
     {
      sr.Write(',');
     }
    }
    //改行する
    sr.Write("\r\n");
   }
   sr.Close();

  }

  private void Form1_Load(object sender, EventArgs e)
  {
   //CSVファイルからDataGridViewに値を格納
   //CSVからDataSourceに使えるテーブルにしたほうがいいかと思う
   //だが直接セットを貫いてみる。仕事で作るソフトじゃないし(*^-゜)vィェィ♪
   if (!System.IO.File.Exists("ACLIST.csv"))
   {
    //ないものはない
    return;
   }

   System.Collections.ArrayList csvRecords = new System.Collections.ArrayList();
   System.Collections.ArrayList csvFields = new System.Collections.ArrayList();
   Encoding enc = Encoding.GetEncoding("Shift_JIS");
            System.IO.StreamReader sr = new System.IO.StreamReader("ACLIST.csv", enc);


   string csvText = sr.ReadToEnd();
   sr.Close();
   sr.Dispose();

   //前後の改行を削除しておく
   csvText = csvText.Trim(new char[] { '\r', '\n' });

   int csvTextLength = csvText.Length;
   int startPos = 0, endPos = 0;
   string field = "";

   while (true)
   {
    //空白を飛ばす

    while (startPos < csvTextLength &&
      (csvText[startPos] == ' ' || csvText[startPos] == '\t'))
    {
     startPos++;
    }

    //データの最後の位置を取得

    if (startPos < csvTextLength && csvText[startPos] == '"')
    {
     //"で囲まれているとき

     //最後の"を探す

     endPos = startPos;
     while (true)
     {
      endPos = csvText.IndexOf('"', endPos + 1);
      if (endPos < 0)
      {
       throw new ApplicationException("\"が不正");
      }
      //"が2つ続かない時は終了

      if (endPos + 1 == csvTextLength || csvText[endPos + 1] != '"')
      {
       break;
      }
      //"が2つ続く
      endPos++;
     }

     //一つのフィールドを取り出す

     field = csvText.Substring(startPos, endPos - startPos + 1);
     //""を"にする
     field = field.Substring(1, field.Length - 2).Replace("\"\"", "\"");

     endPos++;
     //空白を飛ばす

     while (endPos < csvTextLength && csvText[endPos] != ',' && csvText[endPos] != '\n')
     {
      endPos++;
     }
    }
    else
    {
     //"で囲まれていない

     //カンマか改行の位置
     endPos = startPos;
     while (endPos < csvTextLength &&
       csvText[endPos] != ',' && csvText[endPos] != '\n')
     {
      endPos++;
     }

     //一つのフィールドを取り出す

     field = csvText.Substring(startPos, endPos - startPos);
     //後の空白を削除
     field = field.TrimEnd();
    }

    //フィールドの追加
    csvFields.Add(field.Replace("\"", "").TrimEnd(' '));

    //行の終了か調べる

    if (endPos >= csvTextLength || csvText[endPos] == '\n')
    {
     //行の終了

     //レコードの追加
     csvFields.TrimToSize();
     csvRecords.Add(csvFields);
     csvFields = new System.Collections.ArrayList(csvFields.Count);

     if (endPos >= csvTextLength)
     {
      //終了

      break;
     }
    }

    //次のデータの開始位置
    startPos = endPos + 1;
   }

   csvRecords.TrimToSize();

   for (int i = 0; i < csvRecords.Count; i++)
   {
    try
    {
     int Num = int.Parse(((System.Collections.ArrayList)csvRecords[i])[0].ToString());
     string id = ((System.Collections.ArrayList)csvRecords[i])[1].ToString();
     string pass = ((System.Collections.ArrayList)csvRecords[i])[2].ToString();
     string day = ((System.Collections.ArrayList)csvRecords[i])[3].ToString();

     dataGridView1.Rows.Add(new Object[] { Num, id, pass, day });
    }
    catch
    {
    }
   }

  }

  private void button3_Click(object sender, EventArgs e)
  {
   int SelectRowNumber = 0;
   SelectRowNumber = dataGridView1.CurrentCell.RowIndex;
   if (SelectRowNumber < 0)
   {
    return;
   }
   dataGridView1[3, SelectRowNumber].Value= DateTime.Now.ToString("yyyy/MM/dd");
  }

        private void button4_Click(object sender, EventArgs e)
        {
            webBrowser1.Navigate("https://skydrive.live.com/");
        }
 }
}


どうでしょうか?怪しい動きはありましたか?
デジタル署名すればSONARの誤検知を防げるという情報も見ましたが
「無料で公開するツールにそんなお金かけられるかっての!」
※デジタル署名に必要な証明書の入手には大抵お金がかかります

なので無料のVisualStudioで出来る範囲の対応しかできませんことをお詫びします<(_ _)>
もし誤検出されちゃったら復元してもらえるとありがたいです。
ついでにSymantecにクレームしてくれても構いません(;´▽`A``

正直まだまだバグが残っていますが、
必要最低限の機能は確保できているので
あとは運用でカバーしてください。
100点満点のプログラムはコストも時間も掛かり世界じゃ通用しません。
ま、動けばいいんです。バグったらその時直します。

ダウンロードはこちらからどうぞ!

いやー、意味もなく長い仕様書とか標準化とか画面定義書とかない
自由に作れるコーディングはやっぱり楽しいです。ものづくりバンザイ!ヽ(^◇^*)/