ラベル C# の投稿を表示しています。 すべての投稿を表示
ラベル C# の投稿を表示しています。 すべての投稿を表示

2012年2月29日

フォルダのファイルを拡張子で絞込みメールに指定サイズで分割して添付して送るツール

本年度も残すところあとひと月余りとなりました今日この頃、
皆様いかがお過ごしでしょうか?

相変わらず年度末が近づくと受注金額に見合わない仕事がやってきます。
サードパーティーのライセンス金額分が予算に入っていない・・・(;-_-) =3
いやそりゃおかしいのでは?と思ったりもしますが、
上がOK出したなら上の人間に責任とって対応してほしいものです以下略




さて、随分と前に作成してデバッグを依頼したあと音沙汰のなかった上のツール
ソースが欲しいってんで差し上げたところ、
そいつの会社の社内システムツールとして
バッチ機能までつけてバリバリ使い始めてた(・・∂)

ツールの謝礼?もちろん貰いましたよ!みそらーめんチャーハンセット!
ファミレスで好きに頼んでいい権利とどちらにしようか迷ったんですが。うん。

。。。


まあ、それで仕事が便利になったっていうのであれば、エンジニア冥利につきるものです。


とりあえず致命的なバグはなさそうだし、そろそろ作者も忘れかけているので
忘れないように公開してしまおう。うん。

が、しかしながら、まだツールの紹介ページは出来上がっていないという。。。
いやはや、お恥ずかしい(〃∇〃) てれっ☆

いるかいないかわからないですが、
使ってみたいという物好きなチャレンジャーがいる可能性は0でないと信じているので
先にツール本体を公開シてしまいます。

こちらです

紹介ページは多分。週末には・・・作れる。。。といいな
それでは!また!

2012年1月15日

フォルダ内のファイルを指定の宛先に一定容量に自動で分割して送る

大切な写真データ、みなさんはどうやって保管されていますか?
パソコンの中で消えたら困るもののTOPに出るであろう画像ファイルたちです。

保存方法は色々ありますが、
CDやDVDだと経年劣化で突然見れなくなったりしますし、
オンラインの画像保管スペースは色々と敬遠する理由があったり・・・

非公開なのに中の人が画像をこっそりチェックしてて規約違反ですよってメールが来たサービスもあったなぁ
ログイン状態管理に脆弱性があって特定操作をするとパスワードなしでアルバム見れたサービスもあったなぁ
ダウンロードしたら画像のEXIF消えてたり勝手に縮小や圧縮されてたりしたサービスもあったなぁ

とまあ、年々増え行く画像ファイルを比較的安全に保管する方法がないかと
かれこれウン年前から考えて、メールでWEBメールに添付送信するのが消去法的に
一番信頼性が高いんではと・・・o( ̄ー ̄;)ゞ
Gmailは7GBあるしHotmailも容量無制限だし
(SkyDriveはロボットがこっそりチェックしている噂)
(メールデータなら通信の秘密とか電気通信事業法とかでチェック面倒くさそうだし※ウイルスチェック除く)

ということで、これまたウン年前から構想だけして
面倒くさくてプログラムを作っていなかったのですが(;´▽`A``

受験生がセンター試験で学校に引きこもってることだし、
貧乏プログラマも家に引きこもってちょっとやれるとこまでやろうじゃないかと。
(寒くて外に行きたくないだけだ)

で、あっさりと1日で出来上がってしまったので、構想ばかりしていた自分の過ぎ去りし日々は
一体何だったのかと、、、まさに案ずるより産むが易しですな(〃∇〃)

さて、てなわけで今回作ったツールはこんな仕様になっています。

○仕様書

・指定されたフォルダ内のファイルを決められた宛先に添付ファイルで送信する
・一通辺りの添付上限サイズは任意に決定できることとする
・フォルダ内のファイルで送信を行いたくないファイルの除外機能を持つ
・一度に送信されるファイルの総容量の制御を可能とする
・メールの送信間隔を任意に制御できるようにする
・件名/連番を任意で編集可能な仕組みを用意する
・本文に添付されるファイルの名称及びファイルサイズが記載できるようにする
・宛先やサーバ情報などはローカルに保存できるようにする
・SMTP認証やSSL通信に対応する
インストールを必要としない!
無料!

うん。こういうとってもシンプルな要点のみ書かれたモノの方がプログラムは作りやすい
足りない部分は自由に作っていいわけだし、( ̄▽ ̄)V

実際のところ、フォルダ内のメールを自動で送信するツールっていうのは。
はるか昔から色々出ているのですが、
無駄にグラフィカルだったり、容量で分割出来なかったり、Excelマクロだったり、
フォルダ内全部を一括で送ることしか出来なかったり、インストールが必要だったり
有料だったり・・・・

やはり、自分の欲しい機能を満たすものは自分で作るのが一番!
My Tool Made Myself
で、完成したプログラムの画面がこちら
「フォルダ内のファイルをメールに添付して送るツール。容量で分割もできるのだ」


ごちゃっとしているようですが、必要なものをコンパクトにまとめたらこうなりました。
無駄なグラフィックなどは一切排除!です

知恵袋などで「フォルダ内のファイルを自動で添付してメールで送れるソフトはないですか?」
とかの質問をたまに見るので、そういったことにも使えるのではなかろうかと。うん。

突貫工事的に作ったが故、エラーチェックがまだ甘いので一般公開はちょっと待ってください。
仲間内でコードレビューとバグチェック(人柱)してから公開しようかなと。

どうしてもすぐ欲しい!って人がいたら教えて下さい。α版で良ければ・・・

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点満点のプログラムはコストも時間も掛かり世界じゃ通用しません。
ま、動けばいいんです。バグったらその時直します。

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

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

2011年9月29日

GoogleCodeJamに挑戦。挫折寸前


お昼休みに激安弁当つつきながらGoogleCodeJamの練習問題というのを解いてみました。

まあ、あれです。昼休みなのに客先サーバの動作が不安定っていう理由で座席に縛り付けられているのです(;-_-) =3
なので気分転換にやってみました。
とりあえずは「数珠繋ぎ」だけですが、
C#で解いたよっ♪
っていう記事が見当たらなかったのでC#で解いてみた結果を載せてみます。

ロジックとしては単純な処理しかしていません。
というか、複雑な処理を組む気はないっす(;´▽`A``

問題としては、

  • 1個以上の電気的スイッチが存在している
  • スイッチの終端には電球がセットされている
  • 終端以外のスイッチの出力には次のスイッチが接続されている
  • スイッチは指を鳴らすという動作によってON/OFFが切り替わる
  • 先頭のスイッチは電力を供給するプラグに接続されている
  • スイッチは電力が供給されている場合のみON/OFFを切り替え、電力が遮断されている場合には変化しない

さて、指をN回鳴らしたとき、K個連結されたスイッチの終端にある電球は光るでしょうか?

脳内で解読した限りこんな感じの要点ではないかと。
興味の出た人はCodeJamのページを読んでみてください。
(練習問題が消えてしまってたらごめんちゃい)

さて、どう解こうかな~、と紙にスイッチの動きを書き出してみたところ
「4個のスイッチ(A-B-C-D)がつながっている場合」
試行回数:スイッチの状態(0:OFF/1:ON)
0:0-0-0-0
1:0-0-0-1
2:0-0-1-0
3:0-0-1-1
4:0-1-0-0
5:0-1-0-1
中略
13:1-1-0-1
14:1-1-1-0@まだ電球は点かない
15:1-1-1-1@ここで電球点灯
16:0-0-0-0@また消える

・・・うん。2進数だ
2進数でスイッチの数の桁数下位ビットがすべて1の時に点灯するな、これ(^_^;)

てことは。
指を鳴らした数を2進数で変数にセット
その数にスイッチの数だけ下位ビットから1を並べた2進数を論理積する
論理積した結果がスイッチの数とイコールであれば電球は点く
ということではないかと。

紙にちょっと書き出して検算中・・・検算中・・・β(□-□ )
うん。たぶんおっけー

で、こんなソースになりましたとさ

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;

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

		string Fileadd = string.Empty;
		int counter = 0;
		int[] snapper;
		int[] finguer;
		bool[] light;

		private void button1_Click(object sender, EventArgs e)
		{
			//ファイルを開くボタンを用意して、ファイルを開くと同時に処理スタート

			OpenFileDialog ofd = new OpenFileDialog();

			if (ofd.ShowDialog() == DialogResult.OK)
			{
				Fileadd = ofd.FileName;
			}
			else
			{
				return;
			}

			//FileLoad
			//全データをStringの配列に突っ込む
			string[] lines = System.IO.File.ReadAllLines(Fileadd);

			//先頭に問題数が記載されているのでそれを取り出して各配列の初期値に使う
			counter = int.Parse(lines[0]);
			snapper = new int[counter];
			finguer = new int[counter];
			light = new bool[counter];

			for (int i = 1; i <= counter; i++)
			{
				//スイッチの数と指を鳴らす回数はブランクで繋がっているので数値に変換して取り出す
				snapper[i-1] = int.Parse(lines[i].Split(' ')[0]);
				finguer[i-1] = int.Parse(lines[i].Split(' ')[1]);

			}

			//電球点灯状態を一括チェック
			Calc();

			//結果を出力
			OUTPUT();

			//めでたしめでたし
		}

		private void Calc()
		{

			for (int j = 0; j < counter; j++)
			{
				//指を鳴らした数
				uint a = (uint)finguer[j], x;
				//スイッチの数から論理積に使用するビット列を作る。-1するのを忘れないように
				int n = (int)Math.Pow(2, (snapper[j]));
				uint b = (uint)n-1;
				//指を鳴らした数と1になっているべき値を論理積
				x = a & b;
				//電球が点灯しているかを判断
				if (x==b)
				{
					light[j] = true;
				}
				else
				{
					light[j] = false;
				}

			}

		}


		private void OUTPUT()
		{
			//ファイルに一気に出力する
			StreamWriter sw = new StreamWriter(@"z:\output.txt");
			for (int k = 0; k < counter; k++)
			{
				if (light[k])
				{
					sw.WriteLine("Case #" + (k + 1).ToString() + ": ON");
				}
				else
				{
					sw.WriteLine("Case #" + (k + 1).ToString() + ": OFF");
				}

			}
			sw.Close();
			sw.Dispose();
		}

	}
}


Largeの問題を1秒程度で解いてくれると思っています。
さらに速度を上げるのであれば、、、そうすなぁ~
スイッチの数であらわすことのできる2進数値よりも指を鳴らす回数のほうが小さいときは即座にOFFと判断できるんじゃないかと。

ここまで書いておいてなんですが、
きっと毎回参加される方々はもっと早くプログラム作って解けるんだろうなぁ~と。
C#でビット演算ってあまりやらないよなぁ~と。

こういうの好きな高校とかの先生は次回のテストで
+αのボーナス問題に穴埋めにしてこの問題使いそうだな
と思ったところでお開き。

土曜の予選に参加できるかどうかはサーバが安定するかにかかっている( ̄▽ ̄;)

2011年7月24日

ファイル名でフォルダを作って移動するツール。公開

相当前にソースだけ載せていた

フォルダを指定し、その中にあるファイルのファイル名をフォルダを作って移動するツール

ですが、
某知恵袋という場所で欲しがっている人が居たという衝撃の情報を入手。
うわ。やばい(;´▽`A``

さっさと公開していなかったが故、無駄な時間を取らせてしまったとは・・・
この場を借りて深くお詫び申し上げます<(_ _)>

と、いうわけで。

こんなツール公開してどうするんだというツッコミが来ても
欲しがっている人がいたっていう事実があったわけで

公開してもOKという自分の中での免罪符を得られたわけです

はい。

貧乏プログラマの休日出勤

もちろんこのツールもノンインストール・ノンレジストリで実行OKです

飽きたらゴミ箱に放りこんでください
また必要なときにダウンロードしてくれればいいですから~ ̄ー ̄)ノ彡

まあ、相変わらずスッカスカのページとブログですが、
ニッチの中のニッチな需要のため、ひっそりと生き続けていくんだろうと思います。

※バグがあっても、どうか、生温かぁ~い心で見守ってください

2011年6月29日

枠に囚われたくない、でも枠が表示されない

最近困ること、それはWindows7でのみ発生する現象について客から聞かれること

だっておいらのPCまだXPだもんヽ(`Д´)ノ
そして最近あったものはこんなご連絡

客「なんかさ~表示がなんだけど~」
貧「え~っと、どのように変なんでしょうか?」
客「うん、なんていうの?今までと違うの」
貧「はい、それでどこが違っているのでしょうか?」
客「いや~どこがって言われてもね~、古いパソコンもうないし」
(グダグダと10分ほどカチカチクリック音が鳴り響く)
貧「あの、では違和感を感じる部分だけでも教えていただけないでしょうか?」
客「あ~、この辺かな~(電話越し)」
貧「はい、どのような感じでしょうか」
客「感じって言われても。なんか違和感・・・」
貧「今からお伝えする通りにキーボード操作してください。その画面をメールに添付できるようにしますので」

と。PC分かっている人になら
キャプチャ撮ってメールで送って
5秒で済む話を15分ほど続けられ、
送られてきた現象を要約するとこんな感じ

現象
Windows7(Vista)でチェックボックスに点線(破線)の枠が表示されない

・・・20行ほどの無駄な前振りについてはここで謝ります。
m(_ _)m


さて、この現象ですが、
ざっと調べてみると、WindowsVista/7で発生する
Microsoft的に「仕様」な現象みたい
仕様ですか、なら仕方ないですね。チャンチャン♪

ま、こんな感じ↓
(7を使っている人が帰るのを待って検証した結果)

が、ただまあ、何とかしないといけないわけで
対処法をいろいろ試しました。
参考:VistaでComboBoxにフォーカスを移すためにSetFocusするとコンボの見た目が変わらない。
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=43887&forum=7

で、C#上で何とかするには以下のロジックをどこでもいいので実行すれば良いみたい

ロジック:
Windows7やVistaでチェックボックスやコンボボックスの枠線が初期表示されない現象をC#で対応する

[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern int SystemParametersInfo(UInt32 uiAction, UInt32 uiParam, bool pvParam, UInt32 fWinIni);

const uint SPI_SETKEYBOARDCUES = 0x100B;
const uint SPIF_UPDATEINIFILE = 0x0001;
const uint SPIF_SENDWININICHANGE = 0x0002;

int Result = SystemParametersInfo(SPI_SETKEYBOARDCUES, 0, true, SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);

一番手っ取り早いのは
public partial class Form1 : Form
{
の直後でしょうか

Administrator権限を持っていてUACの制御がちゃんと行えていれば
再起動してもそのまま枠線が表示されるみたいです

単純に
SystemParametersInfoをCALLして
SPI_SETKEYBOARDCUESの制御をお願いしているだけですが・・・

ちゃんと↓の用に枠線が見えるようになりました
(使いたい時に限って遅くまで仕事してるもんだからおいらは終電ギリまで以下略)

2011年4月23日

ファイル名小文字化ツール。公開

以前、ここで載せた戯れツール一号
ファイル名を小文字化するだけのツール、欲しいっていう奇特な友人がいたので
無謀ながら、ザ・公開

機能としては
フォルダを指定→対象拡張子を指定→実行→フォルダ内のファイル名が全部小文字に♪
以上です(;´▽`A``

ですが、ここでは画像以外のファイルを保存できないもんですから
FC2のページを使用して配布するとです。

貧乏プログラマの休日出勤

残りの戯れツールもこの際なので、
出来上がり次第ばらまいてしまおうと( ̄∇+ ̄)v

※バグがあっても怒らないで<(_ _)>

自分自身がインストールが必要なツールとか好きでないので、
このツールもノンインストール・ノンレジストリで実行OKです

飽きたらゴミ箱に放りこんでください
また必要なときにダウンロードしてくれればいいですから~ ̄ー ̄)ノ彡

2011年2月27日

My Tool Made Myself

Vectorとかを探しても自分の欲しいツールが見つからない。
見つかっても操作性が自分に合わなかったり
なによりインストールを求められたりするのがイヤ

て、場合はやっぱりセルフメイドが一番ですな
欲しい機能を自分が使いやすいようにデザイン
あーでもないこーでもないと試行錯誤している時間が実は楽しかったり('-'*)エヘ

そういうわけで今回作ったのはこちら
てってれてってって~んてて~ん♪
指定フォルダの中にあるファイルをそのファイルの名前のフォルダを作って移動するツール~♪

まとめるなら:ファイル名でフォルダを作って移動するソフトです、( ̄▽ ̄)V


機能としてはこんなの
・フォルダを指定(内部にフォルダがないこと)
・指定したフォルダ内のファイルチェックしてファイル名を自動リスト化
・作ったリストからフォルダを作成(拡張子は自動で除去)
・ファイル名と同じ名前のフォルダにそのファイルを移動
・当然インストール不要、レジストリなど一切ノータッチ
・以上!

何に使うの?って言われると困るんですが(;´▽`A``
大量の大きな動画ファイルを分割転送する必要に迫られて作ったのです
フォルダに分けてしまえば、あとは分割ツールでフォルダごとに分割コマンドを実行すればいいので
というか詳しくは聞かないで(*/∇\*)キャ

使い方は人それぞれですので、どうぞ自由に使ってください。
メイン部分のソースコードを載せときます。
載ってないのはデザインとフォルダを開く部分だけっす、改変も引用も好きにして(*^-゜)v♪

string[] files = System.IO.Directory.GetFiles(textBox1.Text, "*", System.IO.SearchOption.AllDirectories);
if (files.Length != 0)
{
 for(int i = 0; i< files.Length;i++)
 {
  System.IO.FileInfo fi = new System.IO.FileInfo(files[i]);
  string name = files[i].Split('.')[0];
  if (name.EndsWith(" "))
  {
   name = name.Substring(0, name.Length - 1);
  }
  System.IO.Directory.CreateDirectory(name);
  textBox2.Text = textBox2.Text + "\n" + "Create:" + textBox1.Text + "\\" + name;
  fi.MoveTo(name + "\\" + fi.Name);
  textBox2.Text = textBox2.Text + "\n" + "Move:" + files[i];
  }
 }
textBox2.Text = textBox2.Text + "\n" + "Finish!";
自分の環境で動くことを確認しただけですので、 もしバグっても大目に見てください(*_ _)人


というか、このツール欲しい人っています?
周りに載ってるであろうソフトのほうが高性能だろうから
ま、いらないだろうな・・・。。。ρ(-ω- ) イジイジ・・・


追記:ツール公開しました。知恵袋の方、気付くの遅くてSorry

2011年2月19日

ボタンは目立ったイカでいい♪

というのは冗談で。
プログラムのお仕事をしていると、レイアウトだとかデザインといったものが後回しにされがちです。


ですが、実際に仕事で使う人(エンドユーザですね)にしてみれば
「中でどう動こうが知ったこっちゃない!それよりこのごちゃごちゃした画面何とかしてくれ!」


ってのが大半だったりします。(いやいや、内部の動きも知ってほしいんですけど(^_^;))もっとも、作るほうもごちゃごちゃした画面はキライです
時間はかかるしバグはできやすいしテスト項目多いし・・・
機能はシンプルに!ロジックは安定性を!ソースコードのコメントでケンカするな!(最後のはスルーで)

で、愚痴はここまで。
小さな画面で小さなプログラムを作っていると、どうしてもひとつのボタンに複数の機能を割り振らないと
スペース的にどうにもならん!ってことがあります
(アイコン画像+説明がセットで一個のボタン。みたいな)

でもそれ、一個一個手でグラフィック作ってたら気が遠くなりますし
画像ファイルの総数もバカバカ増えていき、
アイコン部分と文字部分を分けて作っても今度はプログラムがごちゃごちゃしていくという・・・

で、おいら自身ひどい仕様書のせいで死亡寸前な目にあったので
CompactFrameworkで動的にボタンに文字を描画するコントロールを作りました

イメージとしてはこんな感じです(貰った仕様書は文字のみの手書きでもっと難読化済み・・・)







左側の□はアイコン画像で、右側に文字を動的に描画します。
背景の黒部分が全体のサイズとなるので、アイコン部分、文字部分共に一個のボタンとして動作可能です。
通常のFrameworkならこんなことしなくても比較的楽にできますが、
CompactなのでPaint部分をオーバーライドして、ええ、コンパクトなもんで・・・

using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;

namespace TestButton
{
 //文字表示機能付きボタンコントロール
 public class Button2 : System.Windows.Forms.Control
 {

 // プライベート メンバ
 private Image image; //表示したい画像を設定
 private Point point; //画像の表示位置を設定
 private Color color; //文字色を設定
 private bool bPushed; // ボタンが押されたかどうかの状態を示すフラグ
 private Bitmap m_bmpOffscreen; //描画用のBitmap

 public Image Image
 {
  get
  {
   return image;
   }
  set
  {
   image = value;
  }
 }

 public Point Point
 {
  get
  {
   return point;
  }
  set
  {
   point = value;
  }
 }

 public Color Color
 {
  get
  {
   return color;
  }
  set
  {
   color = value;
  }
 }

 public Button2()
 {
  bPushed = false;
  // 既定の最小サイズ(あまり小さいとデザイン画面で行方不明に・・・)
  this.Size = new Size(21, 21);
 }

 protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
 {
  Graphics gxOff; // 画面上に表示されない画像
  Rectangle imgRect; // 画像用の四角形
  Brush backBrush; // 背景を設定するためのブラシ

  if (m_bmpOffscreen == null) // Dバッファリング用のビットマップ
  {
   m_bmpOffscreen = new Bitmap(ClientSize.Width, ClientSize.Height);
  }

  gxOff = Graphics.FromImage(m_bmpOffscreen);
  gxOff.Clear(this.BackColor);

  if (bPushed) //ボタンプッシュの判定
  {
   // ボタンが押されたときも背景はそのまま。
   backBrush = new SolidBrush(Color.Black);
  }
  else
  {
   backBrush = new SolidBrush(Parent.BackColor);
  }

  gxOff.FillRectangle(backBrush, this.ClientRectangle);

  if (image != null)
  {
   // コントロールの中央に画像を設定します。
   int imageLeft = (this.Width - image.Width) / 2;
   int imageTop = (this.Height - image.Height) / 2;
   if (bPushed)
   {
    // ボタンが押された場合。
    // 画像を 2 ピクセル移動します。
    imgRect = new Rectangle(imageLeft + 2, imageTop + 2, image.Width, image.Height);
   }
   else
   {
    imgRect = new Rectangle(imageLeft, imageTop, image.Width, image.Height);
   }
   // 透過キーを設定します。
   //フォーム自体の背景色が可変になっていたり、ボタンとしての背景色が一定でなかったりすると
   //四角い枠がそのまま出てきます。もっとも、そう表示したいのであれば透過は不要です
   ImageAttributes imageAttr = new ImageAttributes();
   imageAttr.SetColorKey(BackgroundImageColor(image), BackgroundImageColor(image));

   // 画像を描画します。
   gxOff.DrawImage(image, imgRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, imageAttr);
  }

  if (bPushed) // ボタンが押された場合。押したという枠を出す
  {
   // 四角形を準備します。
   Rectangle rc = this.ClientRectangle;
   rc.Width--;
   rc.Height--;
   // 四角形を描画します。
   gxOff.DrawRectangle(new Pen(Color.Black), rc);
  }

  // メモリ内にあるビットマップから描画します。
  e.Graphics.DrawImage(m_bmpOffscreen, 0, 0);

  Brush bBrush = new SolidBrush(Color);
  float x = Point.X;
  float y = Point.Y;
  if (bPushed) // ボタンが押された場合。
  {
   x = x + 2;
   y = y + 2;
  }
  e.Graphics.DrawString(this.Text, this.Font, bBrush, x, y);

  base.OnPaint(e);
 }

 protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs e)
 {
  base.OnPaintBackground(e);
 }

 private Color BackgroundImageColor(Image image)
 {
  //透過色を左上ピクセルとしています
  Bitmap bmp = new Bitmap(image);
  return bmp.GetPixel(0, 0);
 }

 protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs e)
 {
  bPushed = true;
  this.Invalidate();
 }

 protected override void OnMouseUp(System.Windows.Forms.MouseEventArgs e)
 {
  bPushed = false;
  this.Invalidate();
 }

 }
}

描画の順番としては
最上:文字
中間:イメージ画像
最下:背景色


になっているので、グラフィックツール等で立体的なボタンイメージを作り
その上に動的に文字を描画するという使い方が一番メインでないかと


改めて見直すと、もうちょっとシンプルに作れるような気もしますが
ま、いっかъ( ゜ー^)♪


このへん参考です
http://msdn.microsoft.com/ja-jp/library/aa446518.aspx

2011年1月30日

見たくない物も、事前にトレーニングすればなんとかなる

と、見たくないものの代表格
ブルースクリーン」DEATH、です。

プログラム作っててこれが出た日にゃあ、
Windowsへの怒りと共に、保存ボタンを押さなかった自分がむかつきます(/□≦、)

突然この画面を見るとひやっとして心臓に悪いので
日頃から画面を見て慣れておこう、と。
避難訓練をすることで災害時に冷静に動けるようなものでしょうか?
消火訓練とかもそうですね。消火器は火の元に向かって使うんですよъ( ゜ー^)♪

で、普段からブルースクリーン、ブルーバック画面を見るために、こんな壁紙を作りました。

ブルースクリーンの壁紙です!
こちらはワイド画面用

そして4:3サイズ用のブルーバックの壁紙です

実際のブルースクリーンはこんなにくっきりと文字出ないですけど(^^ゞ
VGAくらいのを拡大したんじゃ?的なのをよく見ます(多分グラボ絡みのエラーなんでしょう)

ただ・・・
慣れないうちはデスクトップが見えるたびにヒヤッとします(T▽T)

誤字脱字があるかもしれないけど、そこんとこはご愛嬌ってことで!
ブルースクリーンとブルーバック、人によって言い方違うよね?どうでもいいけど。

2010年7月29日

ファイル名も態度も、小さく控えめのほうがいい

単純にファイル名を小文字化したいだけです。

古い人間は自分が見やすいように大文字や小文字を織りまぜてファイルを作ります。

まあ、別に普通に使うには何ら問題ないんですが。


「DBとかにファイル名を格納し、ソートすると爆死する」(*/∀\*)

ので一旦綺麗に小文字化しましょう。という話です。
大文字じゃないのは単に自分の好みですw









こちらが完成品のイメージです。

実際に作ったのはもうちょっと業務で使えるような文面ですが、
自分用にはこんなゆるーい表現のほうが使いやすいです。

バグも愛嬌!
エラーが出たらその時直せばいい!
100%の稼働率なんて幻想だ!

というわけでまずはデザインのソースから
あ、当然C#で作ってます(ノ∀`*)



  1. namespace FileName_small
  2. {
  3.         partial class Form1
  4.         {
  5.                 ///
  6.                 /// 必要なデザイナ変数です。
  7.                 ///
  8.                 private System.ComponentModel.IContainer components = null;
  9.  
  10.                 ///
  11.                 /// 使用中のリソースをすべてクリーンアップします。
  12.                 ///
  13.                 /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。
  14.                 protected override void Dispose(bool disposing)
  15.                 {
  16.                         if (disposing && (components != null))
  17.                         {
  18.                                 components.Dispose();
  19.                         }
  20.                         base.Dispose(disposing);
  21.                 }
  22.  
  23.                 #region Windows フォーム デザイナで生成されたコード
  24.  
  25.                 ///
  26.                 /// デザイナ サポートに必要なメソッドです。このメソッドの内容を
  27.                 /// コード エディタで変更しないでください。
  28.                 ///
  29.                 private void InitializeComponent()
  30.                 {
  31.                         this.textBox1 = new System.Windows.Forms.TextBox();
  32.                         this.label1 = new System.Windows.Forms.Label();
  33.                         this.button1 = new System.Windows.Forms.Button();
  34.                         this.label2 = new System.Windows.Forms.Label();
  35.                         this.textBox2 = new System.Windows.Forms.TextBox();
  36.                         this.label3 = new System.Windows.Forms.Label();
  37.                         this.label4 = new System.Windows.Forms.Label();
  38.                         this.label5 = new System.Windows.Forms.Label();
  39.                         this.SuspendLayout();
  40.                         //
  41.                         // textBox1
  42.                         //
  43.                         this.textBox1.Location = new System.Drawing.Point(14132);
  44.                         this.textBox1.Name = "textBox1";
  45.                         this.textBox1.Size = new System.Drawing.Size(49919);
  46.                         this.textBox1.TabIndex = 2;
  47.                         //
  48.                         // label1
  49.                         //
  50.                         this.label1.AutoSize = true;
  51.                         this.label1.Location = new System.Drawing.Point(6135);
  52.                         this.label1.Name = "label1";
  53.                         this.label1.Size = new System.Drawing.Size(4012);
  54.                         this.label1.TabIndex = 1;
  55.                         this.label1.Text = "フォルダ";
  56.                         //
  57.                         // button1
  58.                         //
  59.                         this.button1.Location = new System.Drawing.Point(259113);
  60.                         this.button1.Name = "button1";
  61.                         this.button1.Size = new System.Drawing.Size(20623);
  62.                         this.button1.TabIndex = 6;
  63.                         this.button1.Text = "実行";
  64.                         this.button1.UseVisualStyleBackColor = true;
  65.                         this.button1.Click += new System.EventHandler(this.button1_Click);
  66.                         //
  67.                         // label2
  68.                         //
  69.                         this.label2.AutoSize = true;
  70.                         this.label2.Location = new System.Drawing.Point(6174);
  71.                         this.label2.Name = "label2";
  72.                         this.label2.Size = new System.Drawing.Size(4112);
  73.                         this.label2.TabIndex = 4;
  74.                         this.label2.Text = "拡張子";
  75.                         //
  76.                         // textBox2
  77.                         //
  78.                         this.textBox2.Location = new System.Drawing.Point(14172);
  79.                         this.textBox2.Name = "textBox2";
  80.                         this.textBox2.Size = new System.Drawing.Size(10019);
  81.                         this.textBox2.TabIndex = 5;
  82.                         //
  83.                         // label3
  84.                         //
  85.                         this.label3.AutoSize = true;
  86.                         this.label3.Location = new System.Drawing.Point(344143);
  87.                         this.label3.Name = "label3";
  88.                         this.label3.Size = new System.Drawing.Size(36412);
  89.                         this.label3.TabIndex = 7;
  90.                         this.label3.Text = "実行前に読み取り専用は外しておいてね。ハングすっからヾ(;´▽`A``アセアセ";
  91.                         //
  92.                         // label4
  93.                         //
  94.                         this.label4.AutoSize = true;
  95.                         this.label4.Location = new System.Drawing.Point(50555);
  96.                         this.label4.Name = "label4";
  97.                         this.label4.Size = new System.Drawing.Size(15212);
  98.                         this.label4.TabIndex = 3;
  99.                         this.label4.Text = "サブフォルダは見に行かないです";
  100.                         //
  101.                         // label5
  102.                         //
  103.                         this.label5.AutoSize = true;
  104.                         this.label5.Location = new System.Drawing.Point(468);
  105.                         this.label5.Name = "label5";
  106.                         this.label5.Size = new System.Drawing.Size(61312);
  107.                         this.label5.TabIndex = 0;
  108.                         this.label5.Text = "指定したフォルダの指定した拡張子のファイルを全部小文字にリネームってか置き換え。とっても処理は雑です( v ̄▽ ̄) イエーイ♪";
  109.                         //
  110.                         // Form1
  111.                         //
  112.                         this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
  113.                         this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
  114.                         this.ClientSize = new System.Drawing.Size(723162);
  115.                         this.Controls.Add(this.label5);
  116.                         this.Controls.Add(this.label4);
  117.                         this.Controls.Add(this.label3);
  118.                         this.Controls.Add(this.textBox2);
  119.                         this.Controls.Add(this.label2);
  120.                         this.Controls.Add(this.button1);
  121.                         this.Controls.Add(this.label1);
  122.                         this.Controls.Add(this.textBox1);
  123.                         this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
  124.                         this.Name = "Form1";
  125.                         this.Text = "ファイル名小文字化(というより強制リネームツール)";
  126.                         this.ResumeLayout(false);
  127.                         this.PerformLayout();
  128.  
  129.                 }
  130.  
  131.                 #endregion
  132.  
  133.                 private System.Windows.Forms.TextBox textBox1;
  134.                 private System.Windows.Forms.Label label1;
  135.                 private System.Windows.Forms.Button button1;
  136.                 private System.Windows.Forms.Label label2;
  137.                 private System.Windows.Forms.TextBox textBox2;
  138.                 private System.Windows.Forms.Label label3;
  139.                 private System.Windows.Forms.Label label4;
  140.                 private System.Windows.Forms.Label label5;
  141.         }
  142. }


そしてメインのソースです。
つーかデザインより短いのよ(。-∀-)ノ


  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Text;
  7. using System.Windows.Forms;
  8.  
  9. namespace FileName_small
  10. {
  11.         public partial class Form1 : Form
  12.         {
  13.                 public Form1()
  14.                 {
  15.                         InitializeComponent();
  16.                 }
  17.  
  18.                 private void button1_Click(object sender, EventArgs e)
  19.                 {
  20.                         if (textBox1.Text == string.Empty || textBox2.Text == string.Empty)
  21.                         {
  22.                                 MessageBox.Show("未入力項目があります""入力確認");
  23.                                 return;
  24.                         }
  25.                         string pass = string.Empty;
  26.                         string[] files = System.IO.Directory.GetFiles(textBox1.Text"*." + textBox2.Text,System.IO.SearchOption.TopDirectoryOnly);
  27.                         if(textBox1.Text.EndsWith("\\"))
  28.                         {
  29.                                 pass = textBox1.Text;
  30.                         }
  31.                         else
  32.                         {
  33.                                 pass = textBox1.Text + "\\";
  34.                         }
  35.  
  36.                         //小文字化
  37.                         if (files.Length != 0)
  38.                         {
  39.                                 for(int i = 0; i< files.Length;i++)
  40.                                 {
  41.                                         string filename_s = files[i].Replace(textBox1.Text"").Replace("\\","").ToLower();
  42.                                         //変換
  43.                                         try
  44.                                         {
  45.                                                 System.IO.File.Move(files[i], pass + filename_s);
  46.                                         }
  47.                                         catch
  48.                                         {
  49.                                                 MessageBox.Show("変換エラーが発生しました","変換エラー");
  50.                                         }
  51.                                 }
  52.                                 MessageBox.Show("変換が完了しました","変換完了");
  53.                         }
  54.                         else
  55.                         {
  56.                                 MessageBox.Show("条件に該当するファイルは存在しません","対象ファイルなし");
  57.                         }
  58.                 }
  59.         }
  60. }




大文字化するならLowerしてるとこをUpperに変えるだけですし

なんか使えますかね?このソース(爆)