ぷろじぇくと、みすじら。

LINQPadのコードにファイルをドラッグアンドドロップで渡したい

Created at: | Tag: CSharp LINQPad

LINQPadでちょっとしたツールやバッチスクリプト的なものを作ったときに処理対象のとしてファイルを取ることはよくあるのですが、大抵はコードにパスを直接書いていることがほとんどではないでしょうか。

ただ便利なものは往々にして対象ファイルを変えたりしたいとか誰かに渡したいこともあり、そんな時処理対象のファイルをドラッグアンドドロップでコードに渡せれば…と思ったりすることもあります。残念ながらLINQPadに標準で備わっているユーザー入力と言えば Console.ReadLineHyperlinq ぐらいでドロップを受け付けるユーティリティは備わっていません。

その時点で普通のWindowsアプリケーションとして作りましょうという気もするのですがそうはいってもめんどくさいですよね。というわけでなんとか渡せるようにする方法です。

解決策

LINQPadは通常出力をHTMLベースで行っていますが、自力でHTML以外のカスタム出力結果パネルを出すこともできます。カスタムな出力結果パネルはWindows FormsやWPFのコントロールをホストできるというものなので、それを利用して通常のWindowsのアプリケーションと同様にドラッグアンドドロップを受け付けるという形でドロップターゲット機能を実現できます。

というわけで以下のようなメソッドを用意することでドロップ用のパネルを表示し、ドロップしたファイルのパスを返せます。

// PresentationFramework.dll と PresentationCore.dll を References に追加しておきます
Task<string[]> WaitForFileDrop()
{
    var tcs = new TaskCompletionSource<string[]>();
    var running = Util.KeepRunning();
    var button = new System.Windows.Controls.Button
    {
        Content = "Drop Here",
        AllowDrop = true,
    };
    var outputPanel = PanelManager.DisplayWpfElement(button, "File Drop");
    button.DragEnter += (sender, e) =>
    {
        e.Effects = System.Windows.DragDropEffects.Copy;
    };
    button.Drop += (sender, e) =>
    {
        var dropPaths = e.Data.GetData(System.Windows.DataFormats.FileDrop) as string[];

        running.Dispose();
        outputPanel.Close();

        tcs.SetResult(dropPaths);
    };

    return tcs.Task;
}

やっていることは単純でドロップを受け付けるボタンを作り、出力パネルとして表示し、ドロップされたらパスを取り出して TaskCompilationSource<T> を通して呼びもとに返すだけです。

使い方はこんな感じです。必要に応じてMyExtensionsなどに収めておくと使い勝手がいいでしょう。

async Task Main()
{
    // ドロップを待ち受け
    var paths = await WaitForFileDrop();

    // ドロップされたファイルのパスを出力
    paths.Dump();

    // ドロップされたファイルを画像として表示
    paths.Select(x => Util.Image(x)).Dump();
}

これで人に渡したりバッチ的に使うときにちょっと便利に使えるようになるかもしれません。どうぞご利用ください。

SharePoint Online/OneDrive for Businessでファイル名に特殊記号(%, #)を使えるようにする

Created at: | Tag: Office365

今までSharePoint OnlineとOneDrive for Businessではファイル名やフォルダ名に " # % * : < > ? / \ | といった文字を利用できませんでした。そもそも大なり小なりやスラッシュ、バックスラッシュといったものはWindows上でファイル名として扱えないので困らないのですが#や%を扱えないのはかなり不便です。

例えばC#という単語が含まれているファイルをアップロードしようとするとエラーになる、と言うだけで充分すぎるといってもいいほど不便なのが理解いただけると思います。

そんな不便も随分と前からUser Voiceで上がっていて、去年にはステータスがイマヤッテルヨー(working on it)となっていたのですが、ついに今月ロールアウトされました。ヤッタネー!

# と % のサポートが有効かどうか

既存のテナントは# and % support is not enabled by defaultとあるようにデフォルトでは有効ではありません。有効にするには後述するPowerShellコマンドで設定をオプトインする必要があります。

ただし6月以降に作成された新しいテナントではenabled by defaultつまりデフォルトで有効となります

それとは別に既存のテナントも2017年の9月までに有効にするかどうかの設定をオプトインする必要があります。特に何もしなかった場合2017年度後半(つまり来年1月以降)にデフォルト有効になります。(September 2017までにオプトインしてH2 2017以降enabled by defaultなので多分H2は会計年度)。

# と % のサポートを有効にする

というわけで明示的に有効にする必要があることが分かったので有効にしてみます。具体的にはPowerShellによる管理コマンドで設定を変えるということを行います。サイトの方からは変更できないので注意が必要です。

PowerShellで管理するにはSharePoint Online Management Shell の16.0.6323.1200以降が必要なのでインストールされていない場合や古い場合には新しくインストールします。

モジュールをインストールできたら、まず初めにSharePoint Onlineに接続します。

Import-Module Microsoft.Online.SharePoint.PowerShell
Connect-SPOService -Url https://<TenantId>-admin.sharepoint.com -Credential <UserName>@<TenantId>.onmicrosoft.com

接続ができたら、現在のテナントの設定を取得します。設定を取得するにはGet-SPOTenantコマンドを利用します。

Get-SPOTenant

このコマンドを実行した結果にSpecialCharactersStateInFileFolderNames: NoPreferenceという項目があればそのテナントは設定可能となっているということです。もしかするとまだ機能が展開中でそのテナントに導入されていない場合には出てこないかもしれません。

項目があることを確認したらSet-SPOTenantコマンドで設定します。

SpecialCharactersStateInFileFolderNamesにはAllowed(許可)またはNotAllowed(不許可)のどちらかを指定できます。NoPreference(未設定)は設定できないので注意が必要です。

Set-SPOTenant -SpecialCharactersStateInFileFolderNames Allowed

これで再度Get-SPOTenant設定できたことを確認できれば完了です。

注意

設定後、すぐに利用できるわけではないようでしばらく待つ必要があります。どのぐらいの時間がかかるのかはわかりませんが気長に待つとよいと思います。手元では半日ぐらい待って使えましたが、もっと短いかもしれないし長いかもしれません。

また、既存のアプリケーションがこの挙動(今まで含まれるはずではなかった文字が含まれること)を理解していないと壊れることがあるというような感じの話が上記リンクにありますので自社やサードパーティーの何かを使っている場合には気を付けてください。

有効になったら

#% が含まれるファイル名やフォルダ名を作成したりアップロードできるようになります。

True Destiny/Chain the world (東山奈央)

Created at: | Tag:

今期のお気に入り曲。

サーバルちゃん

Created at: | Tag: Photo

サーバル

Dockerが利用するWindows ContainerとLinux Containerを切り替える

Created at: | Tag: Docker Windows

Windows Containerを使う場合に、Docker for WindowsのインストーラをDockerのサイトからダウンロードしてきてインストールするとデフォルトではLinux Containerを使うようにセットアップされます。

その状態でWindows Containerのセットアップ手順に沿ってサービスを起動しようとすると以下のようなエラーが発生することがあります。

start-service : Failed to start service 'Docker Engine (docker)'.

アプリケーションのイベントログには以下のようなログが残ります。

fatal: open //./pipe/docker_engine: Access is denied.

これはLinux Container向けのエンジンと通信しようとするために発生しているようです。

PS C:\WINDOWS\system32> docker version
Client:
 Version:      17.03.0-ce
 API version:  1.26
 Go version:   go1.7.5
 Git commit:   60ccb22
 Built:        Thu Feb 23 10:40:59 2017
 OS/Arch:      windows/amd64

Server:
 Version:      17.03.0-ce
 API version:  1.26 (minimum version 1.12)
 Go version:   go1.7.5
 Git commit:   3a232c8
 Built:        Tue Feb 28 07:52:04 2017
 OS/Arch:      linux/amd64
 Experimental: true

解決方法

タスクトレイのアイコンのメニューから "Switch to Windows containers..."を選択することでWindows Containersを使うように変更できます。

PS C:\WINDOWS\system32> docker version
Client:
 Version:      17.03.0-ce
 API version:  1.26
 Go version:   go1.7.5
 Git commit:   60ccb22
 Built:        Thu Feb 23 10:40:59 2017
 OS/Arch:      windows/amd64

Server:
 Version:      17.03.0-ce
 API version:  1.26 (minimum version 1.24)
 Go version:   go1.7.5
 Git commit:   60ccb22
 Built:        Thu Feb 23 10:40:59 2017
 OS/Arch:      windows/amd64
 Experimental: true