WPF学習中「コマンドライン引数を受け取る」

C# コンピュータ
C#

作成したアプリをエクスプローラーの送るに登録し使いたいので、コマンドライン引数を受け取る方法を試してみます。
受け取る方法はいくつかあるようですが、Environment.GetCommandLineArgs()で引数を取り出します。

プロジェクトの作成

mkdir プロジェクト名
cd プロジェクト名
dotnet new wpf
dotnet add package Microsoft.Xaml.Behaviors.Wpf
dotnet add package ReactiveProperty.WPF
code .

ソースコード

ファイル名:MainWindow.xaml

<Window
  x:Class="Sample56Args.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:i="clr-namespace:Microsoft.Xaml.Behaviors;assembly=Microsoft.Xaml.Behaviors"
  xmlns:interactivity="clr-namespace:Reactive.Bindings.Interactivity;assembly=ReactiveProperty.WPF"
  xmlns:local="clr-namespace:Sample56Args"
  mc:Ignorable="d"
  Title="{Binding Title.Value}" Height="450" Width="800">
  <Window.DataContext>
    <local:MainWindowViewModel />
  </Window.DataContext>
  <i:Interaction.Behaviors>
    <local:ViewModelCleanupBehavior />
  </i:Interaction.Behaviors>
  <Grid>
    <StackPanel>
      <i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">
            <interactivity:EventToReactiveCommand Command="{Binding LoadCommand}" />
        </i:EventTrigger>
      </i:Interaction.Triggers>
      <Image>
      </Image>
    </StackPanel>
  </Grid>
</Window>

ファイル名:MainWindowViewModel.cs

using System.Diagnostics;
using System;
using System.ComponentModel;
using Reactive.Bindings;
using Reactive.Bindings.Extensions;
using System.Reactive.Disposables;

using System.Collections.Generic;
using System.Linq;

namespace Sample56Args
{
    public class MainWindowViewModel : INotifyPropertyChanged, IDisposable
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private CompositeDisposable Disposable { get; } = new CompositeDisposable();
        public ReactiveProperty Title { get; private set; }

        public ReactiveCommand LoadCommand { get; }
        public MainWindowViewModel()
        {
            Title = new ReactiveProperty("Title").AddTo(Disposable);

            LoadCommand = new ReactiveCommand()
                .WithSubscribe(e=>{
                    string[] args = Environment.GetCommandLineArgs();

                    string buf = "";
                    for(var i=0; i < args.Length; i++)
                    {
                        if (i == 0) continue;
                        buf = buf + args[i] + " ";
                    }

                    Title.Value = buf;
                })
                .AddTo(Disposable);
        }
        public void Dispose()
        {
            Debug.WriteLine("Dispose()");
            Disposable.Dispose();
        }
    }
}

ファイル名:WindowCloseBehavior.cs

using System.Xml;
using System.Xml.Schema;

using Microsoft.Xaml.Behaviors;
using System;
using System.Windows;
using System.ComponentModel;

namespace Sample56Args
{
    public class ViewModelCleanupBehavior : Behavior
    {
        protected override void OnAttached()
        {
            base.OnAttached();
            this.AssociatedObject.Closed += this.WindowClosed;
        }

        private void WindowClosed(object sender, EventArgs e)
        {
            (this.AssociatedObject.DataContext as IDisposable)?.Dispose();
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();
            this.AssociatedObject.Closed -= this.WindowClosed;
        }
    }
}

他のソースファイルに変更なし。

使い方

エクスプローラーの送るに登録するので、リリース版の実行ファイルをビルドします。
ビルドコマンド

dotnet build --configuration Release

送るに登録
[Win]+[R]
shell:sendtoエンター
ビルドしたexeファイルのショートカットを貼り付け

エクスプローラーでファイルを選択し左クリックでメニュー→送るにショートカットが登録されます。

試しに"a.txt" "b.txt" "c.txt"という3つのファイルを送るとタイトルにファイル名が表示されました。

コメント