Microsoft Store版 iTunes 入れたら、iPod Touchが同期できなくなったので同期できるようにしてみた

すでにあるのをアンインストールするのは構わないけどさ、ドライバファイルまで消しちゃうとか、鬼畜w

Microsoft Store で iTunes が発表されたので、はしゃいで入れてみたんだわ。アプリケーション版iTunes がすでにPCに入ってたんだけど、Store版入れると自動的にアンインストールするんだねー、すごいねー、なんて思ってたら

Store版iTunes起動したら、iPodTouchを認識してない!

うそーんと思って、まずは「ヘルプ」>「診断を実行」ってやってみたら

画像に含まれている可能性があるもの:テキスト

ガチだったorz

デバイスドライバないんですけど(遠い目)

最初はAppleさんとこのヘルプ見に行ったんだけれど、

image

ねーよ!! そんなパスがそもそもないわ! エクスプローラで探したけど見つからんわ!

そしてふと気づく「アプリケーション版アンインストールしたよな? 勝手に」

ドライバファイル消した?!

これはやられたw

ってことで、デバイスマネージャーで、再度ドライバ入れ直し。

デバイスマネージャーから

image

Apple iPod 探して「ドライバーの更新」

まぁさすがに「オンライン検索」でよさげなのを勝手に入れてくれるので、

image

こうなってくれたら後はOK。

image

認識したっぽい。

おー、同期もできた。

あー、肝冷えた。

キーボードのNumLock状態をタスクトレイで確認できるようにした

えー、フツーでしょ、My.Computerクラスとか、え? 使えないの? インスタンス取るの? メンドクセー!!! が第一声w

新しい作業用PC、画面大きいし、テンキーあるし、メモリあるし、今のところ不満――あるんだな、これが。

NumLockキーのインジケーターが存在しないw

つまり、NumLockキーON/OFFが目視できないんだわ、いや、あるの当たり前だと思ってたんだけどさ、なかったんだわ、このPC。

なので、タスクトレイにインジケータつけておけばよくね?という発想に至る。

まぁ、あれだ、VBだと、さくっと一行で解決するんだわ。

https://msdn.microsoft.com/ja-jp/library/microsoft.visualbasic.devices.keyboard(v=vs.110).aspx

My.Computer.Keyboardにずばり、NumLock のBooleanいるしね。さくっと書いて終わり。

んじゃ面白くないから、勉強かねてC#でやろうとしたらさ、そしたらさ、My.Computer がない。My空間そのものがない。

まじかーorz

しょうがないから、Microsoft.VisualBasic.Devices 参照追加して、自分で書くorz

んでもって、作ったのがこちら。長いよw

/// <summary>
/// タスクトレイ専用アイコン制御するフォームクラス
/// </summary>
internal class MainForm : Form
{
    //動的変更するのでコンテナ化しとく
    private IContainer components = null;

    //アイコンも固定で持つ
    private NotifyIcon icon;

    //終わるよメニューは固定でもつ
    private ContextMenuStrip menu;

    private ToolStripMenuItem menuItem;

    //VBer必須のMy.Computerクラス
    private Computer myComputer;

    //タイマー
    private Timer timer;

    public MainForm()
    {
        //一回だけ処理
        ShowInTaskbar = false;
        initialize();
    }

    private void Close_Click(object sender, EventArgs e)
    {
        // 終わるよイベント 
        timer.Stop();
        timer.Dispose();
        Application.Exit();
    }

    private void initialize()
    {
        //初期化処理
        myComputer = new Computer();
        components = new System.ComponentModel.Container();
        icon = new NotifyIcon(components);

        //メニュー構成
        setMenu();

        //通知アイコン設定
        setNotifyIcon();

        //タイマー初期化
        timer = new Timer();
        timer.Interval = 1000;
        timer.Tick += new EventHandler(intervalCheck);
        timer.Start();
    }

    private void intervalCheck(object sender, EventArgs e)
    {
        // タイマーイベント 
        timer.Stop();
        setNotifyIcon();
        Refresh();
        timer.Start();
    }

    private void setMenu()
    {
        //メニュー作成
        menu = new ContextMenuStrip();
        menuItem = new ToolStripMenuItem();

        // 簡単な単語の場合、リソース提供のテキストにしておくと、
        // あとでGlobal化するとき困らないw
        menuItem.Text = Properties.Resources.M0001;
        //イベントハンドラ登録
        menuItem.Click += new EventHandler(Close_Click);

        menu.Items.Add(menuItem);
    }

    private void setNotifyIcon()
    {
        //VBerなら当たり前のことをC#でもさせてみるw
        //まさか、自分でクラスインスタンスとらないと
        //My.Computer使えないとかびっくりしたよ
        if (myComputer.Keyboard.NumLock)
        {
            icon.Icon = Properties.Resources.On;
            icon.Text = "NumLock ON";
        }
        else
        {
            icon.Icon = Properties.Resources.Off;
            icon.Text = "NumLock OFF";
        }
        icon.ContextMenuStrip = menu;
        icon.Visible = true;
    }
}

/// <summary>
/// NumLockすぐにわかるよインジケータ
/// </summary>
internal class MainWindow
{
    private static void Main()
    {
        MainForm rm = new MainForm();
        Application.Run();
    }
}

実行結果がこちら

image

あとはスタートアップに突っ込んでしばらく使っていろいろとチューニングしてくw

NUnit 3.x で Private メソッドをテストできるようにした

PrivateObjectクラスってすげー。MSTestって地味に頑張ってるんだなぁと思った。

やりたかったこと。とあるクラスのPrivateメソッドをテストしたかった。

MSTestの場合、PrivateObjectという大変使える?クラスがいたので、それを使ってテスト対象クラスインスタンスからInvokeすれば解決してたんだよね。

https://msdn.microsoft.com/ja-jp/library/microsoft.visualstudio.testtools.unittesting.privateobject.aspx

まぁ、これに同等の機能クラスが実はNUnit3.xに存在しないってことを知ってしまったわけだ。

なので、作ったw

internal static class CommonModule
{
  static public Object PrivateMethodInvoke(Object testClass, String methodName, Object[] parameters)
  {
    if (string.IsNullOrWhiteSpace(methodName))
        Assert.Fail("No Name");

    MethodInfo method = testClass.GetType().GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance);

    if (method == null)
        Assert.Fail(string.Format("{0} is not found", methodName));

    try
    {
        return method.Invoke(testClass, parameters);
    }
    catch (TargetInvocationException ex)
    {
        throw ex.InnerException;
    }
  }
}

例外についても今まで通りの形でテストしたかったんで、ちょいテク。Try-Catch でInvoke例外とってその原因の例外を実行時例外に代替。ILコスト? まーいいんじゃない? テストコードだし、実行じゃないしw

で、テスト用にサンプルクラス作る。Privateメソッドでパラメータの文字列を数字にして「倍返し」。

public class ForPrivate
{
  private int TwoTimeString(String BaseNum)
  {
    if (string.IsNullOrWhiteSpace(BaseNum))
        throw new InvalidCastException();

    int ret = int.MinValue;

    if (int.TryParse(BaseNum, out ret))
    {
        return ret * 2;
    }

    throw new InvalidCastException();
  }
}

そして、テストコードを書いてみる。正常ケースと例外ケースを。

public class ForPrivateTest
{
  [Test, Sequential]
  public void TwoTimeStringTest([Values("1", "4", "88", "-4", "0")] String prm1,
                                [Values(2, 8, 176, -8, 0)] int Exp1)
  {
    ForPrivate forPrivate = new ForPrivate();
    Assert.NotNull(forPrivate);

    int act = (int)CommonModule.PrivateMethodInvoke(forPrivate, "TwoTimeString", new object[] { prm1 });
    Assert.AreEqual(Exp1, act);
  }

  [Test, Sequential]
  public void TwoTimeStringExceptionTest([Values("", " ", "0.00004", null)] String prm1)
  {
    ForPrivate forPrivate = new ForPrivate();
    Assert.Throws<InvalidCastException>(() => CommonModule.PrivateMethodInvoke(forPrivate, "TwoTimeString", new object[] { prm1 }));
  }
}

実行してみた。

image

グリーンだよv

C#でEnum型用の拡張メソッドを作ってみた

JavaだとEnumの中にかけるから、基底Enum作って継承すれば良いんだけどさ。不便よね、もうw

C#やVBでのEnum型って所詮は Int だらけの構造体w<やめい

なので、汎用的にごにょりたいときは拡張メソッド使うw

使うEnum型はこういうの。

public enum ColorDefine
{
    [Description("不明")]
    None = 0,

    [Description("緑")]
    Green = 1,

    [Description("赤")]
    Red = 2,

    [Description("青")]
    Blue = 3,

    [Description("黄")]
    Yellow = 4
}

このEnumに日本語名称をつけて、これを拡張メソッドで取れるようにする。

public static string GetProperName<T>(this T Value) 
{
    if (!(typeof(T).IsEnum))
    {
        throw new InvalidEnumArgumentException();
    }

    FieldInfo fieldInfo = Value.GetType().GetField(Value.ToString());
    if (fieldInfo == null) return null;

    var attr = (DescriptionAttribute)fieldInfo.GetCustomAttribute(typeof(DescriptionAttribute));
    if (attr == null) return "";
    return attr.Description;
}

といいつつ、この拡張メソッドはすべての型に適用可能になっててインテリセンスにも出てくる。使っちゃうと例外かっとぶのでそれはそれで問題。なのでEnum型に絞ることを考えてみる。

まぁ、Whereで制約をつければ良いんだけどね。

https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters

image

じゃぁ、Enum型にはどの制約をつければいいのか、って時に、Docs大事。

https://docs.microsoft.com/ja-jp/dotnet/api/system.enum?view=netstandard-2.0

image

この記載をみれば、Where定義に何を書けばいいのかが判る。

ちな、ValueTypeはWhere定義では叱られるけど、ここは値型のstructでOK。だって所詮はInt型の(ry。というわけでリファクタリング。

public static string GetProperName<T>(this T Value) 
    where T : struct, IComparable, IConvertible, IFormattable
{
    if (!(typeof(T).IsEnum))
    {
        throw new InvalidEnumArgumentException();
    }

    FieldInfo fieldInfo = Value.GetType().GetField(Value.ToString());
    if (fieldInfo == null) return null;

    var attr = (DescriptionAttribute)fieldInfo.GetCustomAttribute(typeof(DescriptionAttribute));
    if (attr == null) return "";
    return attr.Description;
}

制約入れたのに、まだEnum型かどうかのチェックをしているのは、Enum型が所詮は Int の列挙型にすぎないので、この制約でもInt型変数に対してメソッドが使用可能となるから。なのでそれもあわせてテストに書いて

[Test, Sequential]
public void GetProperNameColorDefine([Values]ColorDefine prm1,
                          [Values("不明", "緑", "赤","青","黄")] string exp1)
{
    var act = Extenstions.GetProperName(prm1);
    Assert.AreEqual( exp1, act);
}
[Test]
public void GetProperNameColorDefineException()
{
    int Err = 200;
    Assert.Throws<InvalidEnumArgumentException>(() => Err.GetProperName());
}

実行したら

image

グリーンだよv