2015年1月22日木曜日

HttpWebResponseオブジェクトを使ってループすると、無応答になってしまった現象について (IDispose)

リソース確保したら、解放しましょう。という備忘録です。

複数のサーバーにあるサービスのHTTPステータスを監視したいと思い、
表をループで処理する仕組みを作っていました。

未試験ですが、ざっと以下のようなコードです。

実装時、無応答になることがあったので、もしやと思い、Disposeのコードを追加。

さらっと、流れました。

確か、HTTPだと同時通信数が決まってましたよね。
IDisposeインターフェースを持つオブジェクトは、終わったらきちんと破棄しようと思いました。



    System.Data.DataTable dt;
    if (this.dataGridView1.DataSource != null)
    {
        dt = (System.Data.DataTable)this.dataGridView1.DataSource;

        foreach (DataRow dr in dt.Rows)
        {
            HttpWebResponse res = null;
            try
            {
                res = null;
                req = WebRequest.Create(new Uri(dr["LOGIN_URL"].ToString())) as HttpWebRequest;
                res = (HttpWebResponse)req.GetResponse();
                dr["STATUS"] = res.StatusCode.ToString();
                res.Dispose();
            }
            catch (WebException ex)
            {
                //HTTPプロトコルエラーかどうか調べる
                if (ex.Status == System.Net.WebExceptionStatus.ProtocolError)
                {
                    System.Net.HttpWebResponse errres = (System.Net.HttpWebResponse)ex.Response;

                    dr["STATUS"] = errres.StatusCode;
                } 
            }
            finally
            {

            }
        }
        dt.AcceptChanges();
    }



2015年1月20日火曜日

flickrを使いこなそう(他の人との共有)

flickrには画像共有の機能があります。

あらかじめ友達登録をしておくと、その人はいつでも見れるようになります。

ただ、友達側にもアカウントが必要なのでちょっと面倒くさい。

そんなときのために、ぱっと共有できる仕組みがありました。


https://www.flickr.com/gp/knkryo/Y2hr05/

アルバムを選択
画面右側にある、□に外向き矢印のアイコンをクリック
Grab the linkを選択
表示されるURLを、誰かに送る。

リンクを削除したい時にはGuestPasshistoryをクリックして
該当のリンクでExpireを選択

Chrome リモート デスクトップの精度が高いです。

業務クラウドのヘルプデスク体制を考えていた際に
ひょんなところから「Chrome リモート デスクトップ」というアプリを
見つけました。

能書きともかく、まず使ってみようという事でインストール。
使い勝手としては上々でしたので、iDisplayでの画面ミラーと併せて
使っていきたいと思います。


使ってみた感じ

Androidタブレット (LTE) から、LAN環境のパソコンを操作してみました。
遅延等はあまり感じませんでした。

・タブレットのタップが、マウスクリックになる。
・パソコン側がデュアルディスプレイでも、きちんと認識する。(私の場合、トリプルディスプレイですが)

私の場合には自分のパソコンの画面を見せたいシチュエーションが結構あったりするので
それだけでも、利用価値十分な感じです。

以下に、インストールして利用するまでの概略をまとめておきます。

1.Google Chromeをインストール

私の場合には既にインストールされていたので端折りますが、
Google Chromeで検索すれば、インストールのサイトへ行けると思いますので
そちらでインストールしてください。



2.ブラウザ拡張機能をインストール

Googleウェブストアからインストールします。
URLは変わるかもしれませんが、記事作成時は「こちら」でした。

3.ブラウザ拡張機能を起動

Google Chromeの、左上にある「アプリ」のアイコンを選択後、
「Chrome リモート」を選択すると、画面が開きます。
「アプリ」のアイコンが出ていない場合には、タブの「+」を押してみてください。




リモートの利用方法は、「不特定多数の誰か」と、「自分だけ」の2通りあるようです。

4.リモートサポート


よくある、パソコン間のリモート機能です。
不特定多数によるリモートで、「アクセスコード」を利用して認証を行います。

初回のみ、拡張ソフトウェアのインストールを求められます。

接続されたいパソコン上で「共有」ボタンを押すとアクセスコードが出てきます。



接続するパソコンでは「アクセス」ボタンを押して、その後、接続したいパソコンで
表示されているアクセスコードを入力します。


5.マイパソコン


自分のパソコンをgoogleアカウントに紐づける機能です。

これを設定した後に、AndroidアプリからPINを入力すると
AndroidアプリからPCを操作できるようになります。


まとめ

私的には今後のメインツールになりそうです。
Google.Inc提供のツールなので、Googleのサービスポリシーに則って使う事が
できそうです。

Google製というと、ハングアウトなんてチャットツールもあるので、
業務クラウドシステムのサポートインフラをGoogle製品で作成できるかなと思いました。


その他雑記

iOS (iPhone)でもアプリがあるようです。MacでもOKとのこと。(未検証です


2015年1月19日月曜日

Excel活用術 Tips (INDIRECT,SheetName列挙)

IT関係の仕事に勤めていると、Excelの手軽さって、あまり業務に活用されないのですが、
改めて使ってみると、大変便利なツールだなと、日々感じています。

⇒いわゆる業務システムだと、Excelの柔軟さが仇となったりするので、
 きっちりした業務がお好みのお客様には使えないのです。

ワークブックのシート名を列挙する


○名前の管理にて、以下関数を埋め込み。 (ここでは例として、名前をSheetNamesとします)

=IF(GET.WORKBOOK(4)>=ROW(),MID(INDEX(GET.WORKBOOK(1),ROW()),FIND("]",INDEX(GET.WORKBOOK(1),ROW()))+1,31)&T(NOW()),"")

○どこかのセルに、=SheetNames と記述

これだけで、シート名が出ます。
縦に並べて貼り付けると、シート名一覧の出来上がり。
※ネットで拾った情報の備忘録です。(MARBIN)さん、ありがとうございます。



別シートの参照





=IF(INDIRECT("'参照シート'!A1")="","",INDIRECT("'参照シート'!A1"))

別のシート名を動的に指定して、実装する例です。
これを、先ほどのワークシート名列挙と合わせると、全部とれたりします。

シート名をシングルクォーテーションで括ることを忘れないでください。


上記を組み合わせた使い方


=INDIRECT("'"&C3&"'!AU4")

シート名を動的に参照し、値を表示しています。
シート名列の横に並べれば、動的に全シートの指定値が取得できます。


ちょっと注意事項

関数をあれやこれや活用すると、ものすごく便利なのは確かですが、
エクセルを開いた際、または、初回に関数が評価されるときなどには
たくさんの処理が動き、かたまった状態に見える事も出てきます。

適切に使いたい分だけを使う、時には疎結合 (ブック間のリンクなど )も
意識して使うことも大事になります。


2015年1月7日水曜日

Oracleで、テーブルスペースを切り替える

今使っているtablespaceを切り替える必要が出てきたので
実施内容を纏めておきます。

データファイル名、テーブルスペース名、テーブル名などは実環境に読み替えてください。


手順概略

1.新しいテーブルスペースを作成
2.データを、新しいテーブルスペースへ移動
3.インデックスを、新しいテーブルスペースへ移動
4.ユーザーのデフォルト表領域を新しいテーブルスペースへ移動

手順

1.新しいテーブルスペースの作成

CREATE TABLESPACE "tablespacename";
DATAFILE 'D:\ORADATA\ORCL\"tablespacename";_xxx.DBF' SIZE 10240M AUTOEXTEND ON NEXT 100M MAXSIZE UNLIMITED
/


2.データを、新しいテーブルスペースへ移動

ALTER TABLE <tablename> MOVE TABLESPACE "tablespacename";

3.インデックスを新しいテーブルスペースへ移動

ALTER INDEX <indexname> REBUILD TABLESPACE "tablespacename";

4.ユーザーのデフォルトテーブルスペースを変更

alter user <username> default tablespace "tablespacename";


別アプローチとして、一旦exportして、drop user , createuserでテーブルスペースを変更 , impでテーブルスペース指定なんてこともできそうです。
→今回はデータベースの移行だったので、こちらを採用しました。

2015年1月6日火曜日

TortoirseSVNのアイコンが変わらなくなった件への対処法

今まで利用していたパソコンが、2年を経過し動きが不安定になってきたので
OS環境から再構築しなおしたところ、TortoirseSVNの状態アイコンが表示されなく
なってしまいました。

原因

アイコンオーバーレイの上限に達したようです。
Microsoft公式の情報は残念ながら見つかりませんでしたが、
15個 (そのうち4個はシステムが利用) が上限という仕様のようです。

アイコンオーバーレイって?

通常のアイコンの上に、さらに画像を重ねて見せる仕組みです。

TortoirseSVNのみならず、DropboxやGoogleDriveなど、
クラウド系アプリには結構使われています。

状態を確認してみました。

ShellExViewというツールを使って確認してみました。

レジストリを直接確認しても良いようです。
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers


http://www.nirsoft.net/utils/shexview.html



DropBoxが 8個 GoogleDriveが5個 TortoirseSVNが9個となっていました。

このツール上から、「有効」「無効」を切り替えられるので、DropBoxとGoogleDriveの状態を
「無効」へ変更しました。

【変更後】



レジストリ周りの変更を行ったので、一旦ログオフして、再度ログインする事で
設定した結果が反映されました。

2015年1月5日月曜日

簡単にhtmlファイルの取得解析を行う方法 (.net)

一昔前であれば、HttpWebRequestなどを利用して自前でhttp通信を確立して
文字データを取得して、その後加工。なんて方法しか思い浮かばなかったのですが
今ではライブラリも相当充実し、簡単な記述でhtmlファイルを操作できるようになっていました。

SGMLReader

https://www.nuget.org/packages/SgmlReader/

これ以外にもライブラリはあると思いますが、個人的にはこれで十分。

HTML規格のベースであるSGMLのライブラリなので、DOM操作も容易です。

実装


using System.Xml.Linq;
using Sgml;

public System.Xml.Linq.XDocument getXml(string url)
{
  XDocument xml;
  using (var sgml = new SgmlReader() { Href = url })
  {
    sgml.IgnoreDtd = true; // DTDがなくても読み込みを続行する
    xml = XDocument.Load(sgml); // たった3行でHtml to Xml
  }
  return xml;

}

Linq To Xml

汚いコードですが、ご参考に。queryを作ってeachで抜いてDataTableへ入れています。


System.Data.DataTable dt = new System.Data.DataTable();

dt.Columns.Add("DATE", System.Type.GetType("System.String"));

dt.Columns.Add("StartValue", System.Type.GetType("System.String"));

dt.Columns.Add("MaxValue", System.Type.GetType("System.String"));

dt.Columns.Add("MinValue", System.Type.GetType("System.String"));

dt.Columns.Add("EndValue", System.Type.GetType("System.String"));

System.Xml.Linq.XDocument xml = getXml(url);

var ns = xml.Root.Name.Namespace;

var query = xml.Descendants(ns + "table").Last()
.Descendants(ns + "tr")
.Skip(1) // テーブル一行目は項目説明なので飛ばす
.Select(ee => ee.Elements(ns + "td").ToList())
.Select(es => new
{
  Date = es.First().Value,
  StartValue=es.Skip(1).First().Value,
  MaxValue = es.Skip(2).First().Value,
  MinValue = es.Skip(3).First().Value,
  EndValue = es.Last().Value
});
foreach ( var rec in query)
{
 System.Data.DataRow dr;
 dr = dt.NewRow();
 dr["DATE"] = rec.Date;
 dr["StartValue"] = rec.StartValue;
 dr["MaxValue"] = rec.MaxValue;
 dr["MinValue"] = rec.MinValue;
 dr["EndValue"] = rec.EndValue;
 dt.Rows.Add(dr);
}

その他

SGMLReaderは、NuGetにて取得できます。