GitHub for Windows をプロキシ経由で使う

git をプロキシ経由で使うための設定はググって分かった。
でもこれだと、自分でローカルに作った新規リポジトリに対してしか設定できなくて、既にGitHub上にあるプロジェクトをどうやってローカルにクローンするのかが分からない。
GitHub for Windows そのもののプロキシ設定をしたい、と。
社内から繋ぎたいんだよ。。

で、Getting git to work with a proxy serverを発見。


Git Shell を起動して、

$ git config --global http.proxy http://proxyserver:proxyport

or

$ git config --global http.proxy http://proxyuser:proxypwd@proxyserver:proxyport

で、既にGitHub上にあるプロジェクトをローカルにクローン出来ました。

AutoMapper + NUnit 環境を作る

環境は Windows8 x64 + Visual Studio Professional 2012。
AutoMapper を試してみたかったんだけど、ちょこちょこ嵌ったのでメモ。


まず、プロジェクト作成で ASP.NET MVC を選択。プロジェクト名は「AutoMapperSample」とでも。
4 が使えるので 4 を選んだけどおそらく MVC3 でも同じはず。

次に NUnit 用のクラスライブラリプロジェクトをソリューションに追加。
「AutoMapperSampleTest」とした。


で、VSから「ツール」→「ライブラリパッケージマネージャー」→「パッケージマネージャーコンソール」と辿って、
NuGet で以下必要なライブラリをインストール。

PM> Update-Package

PM> Install-Package AutoMapper

PM> Install-Package NUnit


次に NUnitGUI の設定。
TestDriven.Net を使ったら VS と連携できるとかあるみたいなんだけど、業務で使う場合はライセンス云々とかあるようなので、今回はパス。
NUnit の公式サイトからインストーラーをダウンロードしてインストール。

C:\Program Files (x86)\NUnit 2.6.2\bin の下に nunit.exe ってのがあるので叩くと、 .NET3.5 入れてーと言われる。.NET4以下は入れる気がないので、キャンセル。

同ディレクトリにある nunit.exe.config を開いて以下のように変更。

<startup useLegacyV2RuntimeActivationPolicy="true">
    <!-- Comment out the next line to force use of .NET 4.0 -->
    <supportedRuntime version="v4.0" />
</startup>


これで nunit.exe が動くようになるので、開いたら「Tools」→「Settings」→「IDE Support」で「Enable Visual Studio Support」にチェックを入れる。
これで nunit.exe から Visual Studio のプロジェクトファイルが開けるようになりますです。

あとはテストコードとアプリコードを書くだけ。

AutoMapper のサンプルコードは以下のサイトを参考にさせていただきました。
Model・ViewModelのマッピングに便利なAutoMapper

テストコードで1つ嵌ったことがあって、各テストコードは1つずつだとオールグリーンになるんだけど、クラス単位でテスト実施するとエラーになる。
色々と調べたんだけど、マッピング前にリセット処理を入れるとオールグリーンになるようになった。

[SetUp]
public void Setup()
{
    Mapper.Reset();
}


今回は上記のようにテスト毎にリセットしてるんだけど、、、これってアプリ側で色んなオブジェクトをマッピングするとき、毎回実施前にリセットが必要ってことかな?

基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~ や AutoMapper + ViewModel In MVC その2 を参考にさせていただいたのだが、ここで出てくる

Mapping.AutoMapperBootstrapper.Configure();


ってのが怪しいんだけど、 Mapping ってクラスが見つからなくて、コンパイルエラーになるんだよな。。
うーん、よくわからん。。。

このタスクは管理者特権で作成されます。の設定方法

Windows をインストールした直後、Administrator は使用不可となっています。
インストール時に作成したアカウントは、Administrators グループに属してはいるのですが、プログラムを実行するときはUACが鬱陶しいです。


開発時は Win + R で cmd やら iisreset を叩きたい。


ってことで、管理者承認モードを無効にします。


[Win + R]、「secpol.msc」と入力し実行します。
[ローカル セキュリティ ポリシー] が開くので、左のツリーで、[ローカル ポリシー]、[セキュリティ] を開きます。
[ユーザー アカウント制御 : 管理者承認モードですべての管理者を実行する]という項目があるので、これを[無効]にします。
再起動すればOK。


Win + R を開くと、「このタスクは管理者特権で作成されます。」と表示され、管理者権限で実行できます。

NPOI 2.0 と ClosedXML 0.67 の比較

先日 NPOI 2.0 のα版がリリースされました。
NPOIは現在 1.X系が Stable ですが、*.xls のみの対応で *.xlsx は未対応だったのでこれまで採用できませんでした。
しかし、NPOI 2.0 では *.xlsx の対応も出来るようなったとのことで試してみました。


結論から言うと、現時点の僕の知識では ClosedXML の方が扱いやすいです。
旧形式(*.xls)の扱いがないのであれば、 ClosedXML の方がオススメ。
知名度は断然 NPOI なんですけどね。


以下、サンプルコードにて説明します。
VB.NET で書いてます。NPOI も ClosedXML もサンプルは C# なので本当はそっちで書きたいのですが。。


今回は罫線やグラフ等は扱わず、あるEXCELファイル(*.xls or *.xlsx)を開き、中身を読み込んでそれを別の新規EXCELファイルとCSVに書き出すというもの。
読み込むEXCELの中身は以下のような形になっています。
行の途中と最後にわざと空セルを用意しています


Book1.xlsx

番号 氏名 情報 誕生日 備考
000001 名前1 2012/08/01
000002 名前2 2012/08/02
000003 名前3 2012/08/03


NPOIのコードがコレ。

Imports System.IO
Imports NPOI.HSSF.UserModel
Imports NPOI.XSSF.UserModel
Imports NPOI.SS.UserModel

Module Module1

    Sub Main()

        Dim xlsPath = "C:\TEST\Book1.xls"
        Dim xlsxPath = "C:\TEST\Book1.xlsx"
        Dim newXlsPath = "C:\TEST\NPOI.xls"
        Dim newXlsxPath = "C:\TEST\NPOI.xlsx"
        Dim csvPath = "C:\TEST\NPOI.csv"

        Dim xlsdata = readNPOI(xlsPath)
        writeNPOI(newXlsPath, xlsdata)

        Dim xlsxdata = readNPOI(xlsxPath)
        writeNPOI(newXlsxPath, xlsxdata)

        '*.csv の書き込み
        Using sw As New StreamWriter(csvPath)
            For Each _data In xlsxdata
                sw.WriteLine(_data)
            Next
        End Using

    End Sub

    Private Function readNPOI(filePath As String) As List(Of String)

        Dim book As IWorkbook = createFactory(filePath)
        Dim sheet = book.GetSheetAt(0)
        Dim listOfStr As New List(Of String)

        For rowCnt = 0 To sheet.LastRowNum
            Dim row = sheet.GetRow(rowCnt)
            Dim sb = New List(Of String)
            For colCnt = 0 To row.LastCellNum - 1
                If row.GetCell(colCnt) IsNot Nothing Then
                    sb.Add(row.GetCell(colCnt).ToString)
                Else
                    sb.Add("")
                End If
            Next
            listOfStr.Add(String.Join(",", sb.ToArray()))
        Next
        Return listOfStr
    End Function

    Private Sub writeNPOI(filePath As String, datas As List(Of String))

        FileDelete(filePath)
        Dim book As IWorkbook = createFactory(filePath)
        Dim sheet = book.CreateSheet("Sheet1")

        For rowCnt = 0 To datas.Count - 1
            Dim ary = datas(rowCnt).Split(",")
            Dim row = sheet.CreateRow(rowCnt)
            For colCnt = 0 To ary.Length - 1
                row.CreateCell(colCnt).SetCellValue(ary(colCnt))
            Next
        Next

        Using fs As New FileStream(filePath, FileMode.Create)
            book.Write(fs)
        End Using
    End Sub

    Private Function createFactory(filePath As String) As IWorkbook

        If File.Exists(filePath) Then
            '既存のファイルを開く
            Using fs As New FileStream(filePath, FileMode.Open)
                If filePath.EndsWith(".xls") Then
                    Return New HSSFWorkbook(fs)
                Else
                    Return New XSSFWorkbook(fs)
                End If
            End Using
        Else
            '存在しなければ新規作成()
            If filePath.EndsWith(".xls") Then
                Return New HSSFWorkbook
            Else
                Return New XSSFWorkbook
            End If
        End If
    End Function

    Private Sub FileDelete(filePath As String)
        If File.Exists(filePath) Then
            File.Delete(filePath)
        End If
    End Sub
End Module

ClosedXMLのコードがコレ。

Imports System.IO
Imports ClosedXML.Excel

Module Module1

    Sub Main()

        Dim xlsxPath = "C:\TEST\Book1.xlsx"
        Dim newXlsxPath = "C:\TEST\closedXML.xlsx"
        Dim csvPath = "C:\TEST\closedXML.csv"

        Dim xlsxdata = readClosedXML(xlsxPath)
        writeClosedXML(newXlsxPath, xlsxdata)

        '*.csv の書き込み
        Using sw As New StreamWriter(csvPath)
            For Each _data In xlsxdata
                sw.WriteLine(_data)
            Next
        End Using

    End Sub

    Private Function readClosedXML(filePath As String) As List(Of String)

        Using wb = New XLWorkbook(filePath)
            Dim ws = wb.Worksheet(1)
            Dim listOfStr As New List(Of String)

            For rowNo = 1 To ws.RangeUsed.RangeAddress.LastAddress.RowNumber
                Dim sb = New List(Of String)
                For colNo = 1 To ws.RangeUsed.RangeAddress.LastAddress.ColumnNumber
                    Dim cell = ws.Cell(rowNo, colNo)
                    sb.Add(cell.Value.ToString)
                Next
                listOfStr.Add(String.Join(",", sb.ToArray()))
            Next
            Return listOfStr
        End Using
    End Function

    Private Sub writeClosedXML(filePath As String, datas As List(Of String))

        FileDelete(filePath)
        Using wb = New XLWorkbook()
            Using ws = wb.Worksheets.Add("Sheet1")
                Dim listOfAry As New List(Of String())
                For Each _data In datas
                    listOfAry.Add(_data.Split(","c))
                Next
                ws.Cell(1, 1).Value = listOfAry
                wb.SaveAs(filePath)
            End Using
        End Using
    End Sub

    Private Sub FileDelete(filePath As String)
        If File.Exists(filePath) Then
            File.Delete(filePath)
        End If
    End Sub
End Module


NPOI は新旧両方の EXCEL 形式に対応しなければいけないので、createFactory メソッドの分コードが多いですが、それ以外の処理も ClosedXML の方がスマートです。


以下詳細を見ていきます。

読み込み(readNPOI、readClosedXML)について

最終列の扱い

ClosedXML はワークシートを読み込むだけで、以下の2つのプロパティで読み込むべき範囲(最終行と最終列)が分かります。

Dim ws = wb.Worksheet(1)
ws.RangeUsed.RangeAddress.LastAddress.RowNumber     '最終行
ws.RangeUsed.RangeAddress.LastAddress.ColumnNumber  '最終列


対して、NPOI はシート、行、とオブジェクトを下りていかないと最終列が分かりません。

Dim sheet = book.GetSheetAt(0)
Dim row = sheet.GetRow(rowCnt)
row.LastCellNum                 '最終列


このような作りなので、NPOI の場合は列オブジェクトを取得するたびに最終列の値が変化します。
今回読み込むEXCELの場合、1行目は LastCellNum は "6"、2行目以降は LastCellNum は "5" となります。
これをClosedXMLだと全ての行に対して、6列分処理してくれます。

NPOI 行によって処理回数が異なるので、後で出てくる CSV ファイルを作る際、カンマの数が差異となって出てきます。

空セルの扱い

上記と同様で行途中の空セルの扱いについても異なります。
ClosedXML は空セルは空文字となるのに対し、 NPOI は Nothing(Null) になります。
よって、ループでセル値を取得する際に NPOI は Nothing の判断処理が入っています。

書き込み(writeNPOI、writeClosedXML)について

読み込みの時と同様、 NPOI ではシート、行、セルと作っていき、値をセットします。
対して ClosedXML は VBA チックにセルの列番号と行番号を指定して値をセットすることも出来ますが、今回のサンプルでは基点となるセルに配列を渡して、自動展開で値をセットしています。

ws.Cell(1, 1).Value = listOfAry


個人的にはこれは便利でした。
動的解析・デバッグ時に変数の中身を展開し、どのようにシートに値がセットされるかイメージしやすかったです。


他にも ClosedXML は VBA の書き方に近いので、添え字の考え方などもスマートな印象でした。
NPOI のコードでは

For rowCnt = 0 To datas.Count - 1

みたいに、「0から始まって配列数 -1 まで」みたいなコードがありますが、ClosedXML では出てこないです。


以上が現時点では NPOI より ClosedXML 思った理由でした。
NPOI はまだα版ですし今後の発展も楽しみですね。

Windows Server 2012 の Server Core とフルインストール

Windows Server 2012 RC でお試し。
2012RCはインストールすると Server Core が「推奨」となっており、フルインストールがオプションの扱い。
Windows Server 2008 R2 では逆で Server Core がオプションだったと思う。


推奨なんだからそのままセットアップしていくと、起動後にはコマンドプロンプト1つあがっているだけの状態。
ctrl + shift + esc でタスクマネージャー開くと利用メモリは250MBほど。
軽くていいね。


最初に戻って、インストール形態としては、Server Core とフルインストールのようだけど、厳密には以下の4つに分かれるらしい。
実際は、フルインストールで環境を整えてから Server Core に移るのかな。

  • Server Core
  • 最小サーバー
  • フルインストール
  • フルインストール + エクスペリエンス
Server Core 最小サーバー フルインストール フルインストール + エクスペリエンス
コマンド プロンプト
Windows PowerShell / Windows .NET
サーバー マネージャー ×
Microsoft 管理コンソール ×
コントロール パネル × ×
コントロール パネル アプレット × ×
エクスプローラー × ×
タスク バー × ×
通知領域 × ×
Internet Explorer × ×
組み込みのヘルプ システム × ×
テーマ × × ×
Metro スタイルのスタート画面 × × ×
Metro スタイル アプリ × × ×
Windows Media Player × × ×

Server Core から フルインストールに移る場合

※Dドライブにインストールに使ったISOがマウントされている状態。

Microsoft Windows [Version 6.2.8400]
(c) 2012 Microsoft Corporation. All rights reserved.

::Windows イメージ ファイル (WIM) をマウントするフォルダーを作成
C:\>mkdir C:\mountdir

::どのパッケージをマウント対象にするか確認
C:\>Dism /get-wiminfo /wimfile:D:\sources\install.wim

展開イメージのサービスと管理ツール
バージョン: 6.2.8400.0

イメージの詳細: D:\sources\install.wim

インデックス: 1
名前: Windows Server 8 Beta SERVERSTANDARDCORE
説明: Windows Server 8 Beta SERVERSTANDARDCORE
サイズ: 7,259,493,836 バイト

インデックス: 2
名前: Windows Server 8 Beta SERVERSTANDARD
説明: Windows Server 8 Beta SERVERSTANDARD
サイズ: 12,039,421,772 バイト

インデックス: 3
名前: Windows Server 8 Beta SERVERDATACENTERCORE
説明: Windows Server 8 Beta SERVERDATACENTERCORE
サイズ: 7,251,396,783 バイト

インデックス: 4
名前: Windows Server 8 Beta SERVERDATACENTER
説明: Windows Server 8 Beta SERVERDATACENTER
サイズ: 12,034,891,404 バイト

操作は正常に完了しました。

::今回は SERVERSTANDARD を対象としたいので、index に 2 をセット
D:\>dism /mount-wim /wimfile:D:\sources\install.wim /index:2 /mountdir:C:\mountdir /readonly

展開イメージのサービスと管理ツール
バージョン: 6.2.8400.0

イメージをマウントしています
[==========================100.0%==========================]
操作は正常に完了しました。

::PowerShellを起動して先程のソースから WindowsFeature をインストールし再起動
C:\>powershell
Windows PowerShell
Copyright (C) 2012 Microsoft Corporation. All rights reserved.

PS C:\> Install-WindowsFeature Server-Gui-Mgmt-Infra,Server-Gui-Shell –Restart –Source C:\mountdir\windows\winsxs

フルインストールから Server Core に移る場合

D:\>powershell
Windows PowerShell
Copyright (C) 2012 Microsoft Corporation. All rights reserved.

PS D:\> Uninstall-WindowsFeature Server-Gui-Mgmt-Infra -restart


最初にフルインストールした場合は、Uninstall-WindowsFeature しても必要なファイルはディスクに残っているので次に Install-WindowsFeature するときにソースを指定しなくてもいいとのこと。


よほど空き容量が厳しくない限りは、最初にフルインストールしておいた方が何かと便利そうですね。


この内容はWindows Server インストール オプションを参考にしました。

.NET Framework 4.5 のインストールプレビュー

MSDN で Windows8 や VisualStudio2012 をダウンロードしている間、.NET 4.5を WindowsServer2008R2 にインストールしてみた。


WEB版はココ、オフライン版はココ
Microsoft .NET 4.5 リリース ノートはココ

.NET 4.5 のシステム要件

とのことで、WindowsXPは切られるみたいですな。


インストール形態としては

.NET Framework 4.5 is a highly compatible, in-place update to .NET Framework 4.

とあるので、.NET 4 を上書きする形でインストールされるみたい。


実際にインストールしてみたところ、確かにフォルダ構成などは何も変わっていない。
アプリケーションプールの .NET バージョン とかも特にリストボックスが増えたわけでもない。
これじゃあ .NET 4.5 がインストールされているかどうかの判断に困るな。。


実行ファイル群を見るとバージョンが上がっているのは分かる。
例えば、 aspnet_compiler.exe や ngen.exe のプロパティでファイルバージョンを見ると
以前は「4.0.30319.1」だったのが「4.0.30319.17929」になっている。
頭が「4.5」ではないのか。


ちなみに期待していたパフォーマンス向上だけど、今のところ特に恩恵は感じていません。
.NET 4 と .NET 4.5 の aspnet_compiler.exe で大量の aspx & vb をプリコンパイルしてみたが、かかる時間はほぼ一緒でした。


これならまだ無理して導入しなくてもいいかなー。
非同期プログラミングするわけでもないし、そもそも社内にはWindowsXPがまだごろごろと。。。

サーバーサイドでEXCELを読み込む(ClosedXML)

前々回「サーバーサイドでEXCELを読み込む(NPOI、EPPlus)」と、前回「サーバーサイドでEXCELを読み込む(NPOI、EPPlus、Koogra)」の続き。


EPPlusが開発も活発で良さげだったんだけど、ライセンスLGPLかー。
ググってたら、ClosedXMLというものを発見。
MITライセンスです。

名称 OpenXML バージョン リリース日 ライセンス
NPOI × 1.2.5 2012/5/4 Apache License 2.0
EPPlus 3.0.0.2 2012/1/31 LGPL
Koogra 3.1.5 2010/3/24 MIT License
ClosedXML 0.66.1 2012/7/28 MIT License


バージョン1にも満たないこれからのプロジェクトみたいだけど、筋は良さそう。
OpenXML を簡単にする ClosedXML

ClosedXML.dllとDocumentFormat.OpenXml.dllを参照設定してあげてください。

Using wb = New XLWorkbook(filePath)
    Dim ws = wb.Worksheet(1)
    For rowNo = 1 To ws.RangeUsed.RangeAddress.LastAddress.RowNumber
        For colNo = 1 To ws.RangeUsed.RangeAddress.LastAddress.ColumnNumber
            Dim cell = ws.Cell(rowNo, colNo)
            If Not IsNull(cell.Style.NumberFormat.Format) Then
                'ユーザー書式が設定されていた場合は、書式変換を行う
                Console.WriteLine(String.Format("{0:" & cell.Style.NumberFormat.Format & "}", cell.Value))
            Else
                Console.WriteLine(cell.Value.ToString)
            End If
        Next
    Next
End Using

VBAチックでいい感じ。

Documentationをよく読みましょう。
Where to use the using keywordを見るまで、using使っておらず危なかった。。