布団が俺を呼んでいる

丘山大一のぶろぐ

Windows Server に Git環境を構築 (GitBucket導入)

空いているパソコンサーバ(使わなくなったデスクトップPCにサーバOSを突っ込んだヤツ)があったので、
そこにGitBucketを入れてみました。
一応運用実績のあるサーバ=色々環境が入っているサーバ
ですので、下記手順で足りない・多いものがあってもご容赦ください。
OSはWIndows Server 2012 です。
また、ローカルイントラネットでの運用を想定しているのでセキュリティなどはとくに考慮していません(ホントはダメだよ!)

GitBucket のインストール

Javaで動作しているので、JREが必要です。
あたりで落としてきます。
WIndows Server でブラウザを開いて作業するのが面倒な場合は、先にクライアントマシンでファイル落としてからコピーするのが楽です。

つづいて、GitBucket本体です。
からwarファイルを落としてきます。
これを実行する形になるので、今後のことも考えそこそこの階層に配置することにします。
C:\GitBucket\gitbucket.war

配置はこれだけで完了。起動するコマンドは
java -jar C:\GitBucket\gitbucket.war
となります。適当なスクリプトを組んでおけば便利。
バッチファイルで実行した場合、DOS画面を閉じるとGitBucket自体も終了してしまうので、終了しないように。

この後、外部からアクセスできるようにするため、ポート8080を開けておきます。
ファイアウォールの受信の規則で、ポート指定で「8080」を開放します。

アクセス

インストールしたサーバ自身から参照するとき:「http://localhost:8080/」
外部クライアントマシンから参照するとき:「http://<IPアドレス>:8080/
初期ユーザは、root 
初期パスワードも root
のようです。

ユーザの追加

rootだけで運用するわけにはいかないので、ユーザを作ります。
ログイン後、画面右上のアイコンから「System administration」を選択。
画面左側から「User management」を選択。
ここでユーザとグループの追加・管理ができます。
使いそうな人はとりあえず登録してしまいましょう。

リポジトリの追加とこれ以後

リポジトリの追加は画面右上のアイコンの「New Repository」から。
サクッとカンタンにできます。
リポジトリの実態ですが、デフォルトでは
C:\Users\<ユーザ名>\.gitbucket
にできるようです。
保存先のドライブを変更する場合は、早めにやっておいた方がよさそうです。


独習Git

新品価格
¥3,542から
(2016/6/11 20:25時点)

開発者向けWindows 10仮想マシンを覗いてみた

ツールやら何やら色々入っているヤツだそうで。

起動するまで

とりあえずダウンロード。
20ギガくらいあるのでのんびり待ちます。
終わって解凍するにも長いので、さらにのんびり待ちます。
解凍できたら、適当なところにほうりこんでHyper-Vでインポート。
……しようと思ったのですが、エラーが出たのでインポートは中止。
新規に仮想マシンを作成し、中のVHDファイルに直結させます。
起動させると、突然接続が切れる現象に見舞われる。
どうやら拡張セッションだとブツブツ切れちゃうようなので、通常の(拡張でない)接続に切り替え。

入っているもの

主にこんな感じ
OS:Windows 10 Enterprise Evaluation(英語)
VS2015
VS2012 ツール類(おそらくWindows Phone 8.1用)
Microsoft IoT 関連
ODBC Driver 関連
WIndows Phone SDK
Git (!)

IoT 関係が入っているのが非常に気になりますが、知識がないのでどういうものなのかサッパリ。
利用期限が60日間限定みたいなので、フルに使いこなすのは厳しいと思いますが、開発環境の感触をつかむには十分そうですね。

……しかし、なんで拡張セッション切れちゃうんだろう?
他の人も一緒なのかな?




クライアントHyper-V徹底入門Windowsの上でLinuxもUNIXも全部動かそう!

新品価格
¥3,024から
(2016/6/7 22:44時点)

XAML 多角形の中に文字を表示したい

多角形作って、中にTextBlock突っ込めばオッケー、簡単ですね。
あれ?

多角形(Polygon)の中にTextBlockは突っ込めないみたい

な、なんだってー。

というわけで

正解はTextBlock の裏に多角形を仕込むことみたいです。

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        xmlns:exshape="clr-namespace:Microsoft.Expression.Shapes;assembly=Microsoft.Expression.Drawing"
        xmlns:exctrl="clr-namespace:Microsoft.Expression.Controls;assembly=Microsoft.Expression.Drawing"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TextBlock Text="12" FontSize="24"
           Width="50"
           Height="50"
           Padding="10,10,0,0">
            <TextBlock.Background>
                <VisualBrush>
                    <VisualBrush.Visual>
                        <exshape:RegularPolygon Width="50" Height="50" Stroke="Black" PointCount="5"  Opacity="0.25" />
                    </VisualBrush.Visual>
                </VisualBrush>
            </TextBlock.Background>
        </TextBlock>
    </Grid>
</Window>

ポイントは TextBlock の Padding 。
これで文字位置を微調整する必要があります。

うーん、イマイチ

多角形の中に文字列が存在する のではなく、
文字列の裏側に多角形が存在する というのは、直観に反しているのでなんかイヤ。
もっといい方法ないかなあ……。

あと、もしかして……

UWPってRegularPolygonを呼び出せない……??

Windows 10ユニバーサルアプリ開発【Windows 10 Mobile対応】 ThinkIT Books

空文字を判定する最も効率のいいやり方は? (C#i編)

というわけでC#編。

ソース(前回書かなかったな)

効率のいい書き方?作法?そんなん知らんがな(邪悪)。

    class Program
    {
        static void Main(string[] args)
        {
            using (StreamWriter sw = new StreamWriter(@"D:\test.txt", true, System.Text.Encoding.Unicode))
            {
                Console.SetOut(sw);

                string s = string.Empty;
                var result = new List<TimeSpan>();

                var tryCounter = Enumerable.Range(1, 10).ToList();
                var roopCounter = Enumerable.Range(0, 10000000).ToList();

                Console.WriteLine(@"""""での判定");
                result.Clear();
                tryCounter.ForEach(i =>
                {
                    Console.Write(i + "回目:");
                    Console.WriteLine(
                    RunText(() =>
                    {
                        roopCounter.ForEach(r =>
                        {
                            if (s == "") { };
                        });
                    }));
                });

                Console.WriteLine(@"String.Emptyでの判定");
                result.Clear();
                tryCounter.ForEach(i =>
                {
                    Console.Write(i + "回目:");
                    Console.WriteLine(
                    RunText(() =>
                    {
                        roopCounter.ForEach(r =>
                        {
                            if (s == string.Empty) { };
                        });
                    }));
                });

                Console.WriteLine(@"String.IsNullorEmptyでの判定");
                result.Clear();
                tryCounter.ForEach(i =>
                {
                    Console.Write(i + "回目:");
                    Console.WriteLine(
                    RunText(() =>
                    {
                        roopCounter.ForEach(r =>
                        {
                            if (string.IsNullOrEmpty(s)) { };
                        });
                    }));
                });

                Console.WriteLine(@"Lengthでの判定");
                result.Clear();
                tryCounter.ForEach(i =>
                {
                    Console.Write(i + "回目:");
                    Console.WriteLine(
                    RunText(() =>
                    {
                        roopCounter.ForEach(r =>
                        {
                            if (s.Length == 0) { };
                        });
                    }));
                });

                Console.WriteLine(@"""""とequlsでの判定");
                result.Clear();
                tryCounter.ForEach(i =>
                {
                    Console.Write(i + "回目:");
                    Console.WriteLine(
                    RunText(() =>
                    {
                        roopCounter.ForEach(r =>
                        {
                            if (s.Equals("")) { };
                        });
                    }));
                });

                sw.Close();
            }
        }

        static TimeSpan RunText(Action a)
        {
            var t = DateTime.Now;
            a();
            return DateTime.Now - t;
        }
    }

結果

""での判定
1回目:00:00:00.1810066
2回目:00:00:00.1560072
3回目:00:00:00.1440069
4回目:00:00:00.1290084
5回目:00:00:00.1630423
6回目:00:00:00.1779770
7回目:00:00:00.1580394
8回目:00:00:00.1800101
9回目:00:00:00.1579818
10回目:00:00:00.1810102

String.Emptyでの判定
1回目:00:00:00.1690038
2回目:00:00:00.1430068
3回目:00:00:00.1370051
4回目:00:00:00.1190062
5回目:00:00:00.1190067
6回目:00:00:00.1090028
7回目:00:00:00.1030062
8回目:00:00:00.1020050
9回目:00:00:00.0900034
10回目:00:00:00.0890046

String.IsNullorEmptyでの判定
1回目:00:00:00.0770039
2回目:00:00:00.0740020
3回目:00:00:00.0680047
4回目:00:00:00.0670034
5回目:00:00:00.0720012
6回目:00:00:00.0670210
7回目:00:00:00.0619853
8回目:00:00:00.0610202
9回目:00:00:00.0610032
10回目:00:00:00.0600027

Lengthでの判定
1回目:00:00:00.0510044
2回目:00:00:00.0469995
3回目:00:00:00.0460022
4回目:00:00:00.0460020
5回目:00:00:00.0460034
6回目:00:00:00.0460022
7回目:00:00:00.0460020
8回目:00:00:00.0460016
9回目:00:00:00.0420017
10回目:00:00:00.0420029

""とequlsでの判定
1回目:00:00:00.0640032
2回目:00:00:00.0640030
3回目:00:00:00.0630028
4回目:00:00:00.0590029
5回目:00:00:00.0590028
6回目:00:00:00.0580030
7回目:00:00:00.0590032
8回目:00:00:00.0580030
9回目:00:00:00.0560021
10回目:00:00:00.0540025

総括

おおむねこの通りでした。
とりあえず「文字列 == 空」のような書き方はアカンということが分かった。
DelphiとC#は、開発者レベルで似ている(というか同……ゲフンゲフン)ですけど、結果が大分違うのが面白いですね。

※注意!

私の開発環境での結果です。
ロジックや書き方、環境によってなんぼでも結果は変わることをお断りしておきます。


C#実践開発手法 (マイクロソフト公式解説書)

新品価格
¥5,400から
(2016/5/22 17:14時点)

Windows Phone (Windows Mobile) アップデートの再起動ににかかる時間(trinity) 201605

「電話の更新」が昨日来ていました。
すぐに更新したかったのですが、寝る直前で気が付いた => 計測のためには起きてなくてはいけない
だったので、更新を延期。
本日更新しました。

再起動を手動でかける
というわけで手動でアップデート。
画面の歯車がクルクル回るのが約4分。
プログレスバーが約5分。
合計10分弱くらいでした。
前回よりわずかですが短い印象。
アップデート終了直後、「電話の更新」を覗いてみたら更新に失敗したぜ、みたいなメッセージが出ていましたが、数分してから再試行すると問題なくなりました。ただ単に起動直後にやったのがいけなかったみたい。

バージョン

OSのビルドバージョンは 10.0.10586.318 で変わっていません。
ファームウェアリビジョンは、 1028.020.001.61 になっていました。
本日時点の各バージョンは、
  • バージョン:1511
  • OSビルド:10.0.10586.318
  • ファームウェアリビジョン番号:1028.020.001.61
  • ハードウェアリビジョン番号:1.0
  • 無線ハードウェアバージョン:1.0
  • チップSOCバージョン:8952
ファームウェアリビジョンが上がっている=trinity側の更新だろ、ということでタイトルにはtrinityをくっつけました。
違ったらどうしよう。記事をなおそう。

まあアップデートはいいとして

MSさんちの方で携帯電話事業の動きがバタバタしていて、今後がとっても不安ですw


de:code 2016 参加してきました

楽しかったけど疲れたよ。

今年の感じ

期待されていたHolo Lens 関係があまりなかったので、デバイス的な盛り上がりにはちょっと欠けていた印象。
全体的には、
DevOps、Xamarin、ロボット(ボット)、UWPてな感じ。
スマホやらクラウドやらは当たり前になりすぎて、「それは前提として」話が進むのがなんともはや。
時代の流れは速いもんだ。

これから

感覚的には、Xamarinを押さえておくべきだと思った。
あんまり手を広げると学習効率が落ちるので、当面はWUP集中だけど、アンテナは立てておこう。


Creating Mobile Apps with Xamarin.Forms Preview Edition 2 (Developer Reference)

空文字を判定する最も効率のいいやり方は? (Delphi編)

現在いるプロジェクトではDelphiなる言語を使っています。
んで、他の人のソースを読んでいると、空文字かどうかの判定の仕方には色んな書き方があるのだなあと思います。
代表的なのは、
(1) Result := s.IsEmpty;
(2) Result := s = '';
(3) Result := s.Length = 0;
(4) Result := s = EmptyStr;
等でしょうか。
ちなみに、私は基本的にIsEmptyメソッドをなるべく使う派です。
「''」と記述すると、後で読み返した時に
「これは本当に空文字で判定したいのだろうか?
 それとも実は半角スペースと比較するべきところを間違えてしまったのだろうか?」
等と疑わせてしまうこと、また本当にそのように間違える可能性が出てきてしまうためです。
 あとIsEmptyを使った方がコード上からカッコが減りやすいというのもある。IDEが貧弱なRadStudioではこれが割と重要。
 
さて、そうは言っても、「IsEmpty使おうぜ!」と主張しても使ってくれる人はなかなか増えません。
わざわざ書くのが面倒+間違いやすい「''」で書く人がほとんどです。

むう。何故だ。

と思っていると、MSDNの中で、(C#ですが)空文字判定方法について記述してある箇所を見つけました。
https://msdn.microsoft.com/ja-jp/library/ms182279.aspx?f=255&MSPPError=-2147217396
な、なるほど!
きっと速度差があるからみんな「''」を使うんだ!
理由があったんだね!

というわけで、それぞれの実行時間はどれくらいなのか。

2147483647 回ループを回してテストしてみました(適当な値をとるのが面倒だったので、Integer.MaxValue)。
以下、単位はミリ秒。
(1) IsEmpty
①37430
②37197
③37296
(2) 「''」
①36414
②36193
③36258
(3) Length
①40755
②40704
③40771
 
最速と最遅で比較すると、
(2) Result := s = '';
が最遅に比べ4578ミリ秒早いという結果になりました。
一回当たりおよそ
4578 / 2147483647 ≠
5000 / 2000000000 ≠
5 / 2000000 ≠ 0.0000025 ミリ秒早い。
ということになります。

おおー、なるほど、確かに早い。
なるほど、同じ結果が出るなら早い方を採用するのは理に適っている。
うん……正しい……
いや、たしかに正しいんだが……

全然変わんねえよ (´・ω・`)

実質0秒だよコレ。
これ以上速度を気にしなければならない要件なら、そもそもDelphi使わないわな。
それこそCとかアセンブラとか、もっと高速な言語を採用するわ。
やっぱり「''」と比較するコーディングは、昔から書いている人の単なる惰性な気がするなあ……。
一応、「早い」ということは分かったから、無暗にIsEmptyを進めるのは止めるけど……
やっぱり私はIsEmptyでいこう……。

※注意!
私の開発環境での結果+面倒だったのでデフォルト設定のDebugビルド結果です。
ロジックや書き方によってなんぼでも結果は変わることをお断りしておきます。



Delphi XE2プログラミング入門

新品価格
¥4,104から
(2016/1/18 20:58時点)

ようやくUWPアプリを一つ公開できた

クソアプリなんですけどね。

アプリ概要

Windows Store 公開。
ランダムな数値を生成する機能(だけ)
推奨はWindows Mobile。

※詳細はブログ上部の「公開アプリ」から。

目標達成

アプリを作りこむよりも、まずWIndows Storeでアプリを公開するとはどういうことなのか覚えたかった。
プログラムで何ができるか、ということも重要だけど、公開するということを考えた場合、公開先の事情も知っておかなければならない。
大家の事情を店子は知っておく必要があるのだ。
その目標は、まずは達成できた気がする。
……まあほとんどの時間はVisual StudioとかUWPアプリのエラー解決に費やされていた気がするが(汗)

今後
練習がてら、もう2~3個くらい軽いアプリを作成するつもり。


UWPアプリが、Windows Phone (Windows Mobile)  に配置できなくなった

最後に配置してから間が結構あったので、何がトリガーだったのか分かりません。
色々見ていると、
・OSのビルドバージョンが上がったから
・ストア申請用のパッケージを作成したから
あたりが原因ぽいですが、確証には至っておりません。

'Device' のブートストラップに失敗しました。デバイスが見つかりません。

最初に遭遇したエラー。
デバイスマネージャからデバイスを削除したらできた、という話があったので試してみたら突破できました。

DEP0001 : 予期しないエラー

すわ、OSのリフレッシュを試す必要があるか、と思いましたが、デバイス側(WIndows Phone側)のアプリを削除すればいけました。
同名のアプリが入っているところに、パッケージ化の設定がされたアプリを突っ込もうとしたしたから出た? ような気がします。

最近はUWPよりも ざまりん の方が盛り上がっているような気がしますが、当分はUWPでいこうかな。


Diginnos SIMフリー スマートフォン DG-W10M ( Windows10 mobile / クアッドコア / 5.0インチ / 1280*720 / デュアル SIM / LTE対応 / RAM1GB / ROM16GB )

新品価格
¥9,980から
(2016/5/14 22:56時点)

Windows Phone (Windows Mobile) Windows Update 後の再起動ににかかる時間(10.0.10586.318)

OSのビルドバージョンが10.0.10586.318に上がりました。

いつものように、更新後の再起動を手動でかけてみる

手動再起動GO!

今回はこんな感じでした

アップデートファイルのダウンロードや更新自体は完了しているので、再起動にかかる時間だけです。
手動で再起動をかけると、画面上に歯車が出てきてクルクル回り始めます。10分強。
それが終わると、ついに起動か、と思いきや、また何やらプログレスバーが出てきます。5分
大きく上記2ステップ、合計15分で更新が完了しました。
前回とあまり変わらないかな。

状況によって時間は大きく前後すると予想されますので、目安の一つとして。

更新内容や履歴はどこで確認する?

いかにもなページもあるんですが、本日時点では特に情報が記載されていないような……?

バージョン

端末はNuAns Neoです。
本日時点の各バージョンは、
  • バージョン:1511
  • OSビルド:10.0.10586.318
  • ファームウェアリビジョン番号:1028.020.001.53
  • ハードウェアリビジョン番号:1.0
  • 無線ハードウェアバージョン:1.0
  • チップSOCバージョン:8952