コンテキストメニュー「送る」C#

私が初めてWindowsアプリを作ったのはMFCダイアログベースのファイル変換ツールでした。ファイル変換ツールなので、ファイルを入力としますが、「送る」メニューに登録することでツールが簡単に使えるようになったのを覚えています。今日はそのC#版。

sendto_example

1.ファイルを受け取るアプリ

まずファイルを受けるソフトから。これは皆様が作るアプリなのでここでは簡単にTXTファイルを受け取って中身を表示するものとして作っておきます。

text_display_form

TextDisplayForm.cs

namespace SendToSupportWinFormsApp
{
    using System;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;

    public partial class TextDisplayForm : Form
    {
        public TextDisplayForm()
        {
            InitializeComponent();
        }

        private void TextDisplayForm_Shown(object sender, EventArgs e)
        {
            var args = Environment.GetCommandLineArgs();
            if(args.Length >= 2) {
                textBoxArgs.Text = args.Skip(1).Aggregate((a, b) => a + b);
                if(args.Count() >= 2 && Path.GetExtension(args[1]).ToLower() == ".txt") {
                    textBoxFileText.Text = File.ReadAllText(args[1], Encoding.GetEncoding("Shift-JIS"));
                }
            }
        }
    }
}

[送る]を選択したときのファイルがプログラム名に次ぐ引数として渡されます。引数はEnvironment.GetCommandLineArgs()でstring配列として渡されますので1番目がパスとして扱えばokです。

 

.送るメニューへのショートカット追加

「送る」メニューに上のソフトが表示されるためには、スタートボタンから”プログラムとファイルの検索”に shell:sendto と入力すると開くフォルダにショートカットを作成すればokです。「送る」メニューへの登録/解除はインストール/アンインストールのタイミングが自然でしょうということで、VS2010でセットアッププロジェクトを作成します。

  1. セットアッププロジェクトを右クリック、「追加」->「プロジェクト出力」を選択
  2. 先ほど作ったWinFormsアプリのプロジェクトのプライマリ出力を選択してOK。
  3. 2でできたプライマリ出力をダブルクリック、ファイルシステムが開く
  4. ファイルシステムの左ペーンの”対象コンピューター上のファイルシステム”を右クリックして「特別なフォルダの追加」->「ユーザーの送るメニュー」を選択
  5. 同じくファイルシステムの左ペーンの”アプリケーションフォルダー”を選択、右ペーンに先ほど作ったWinFormsのプライマリ出力があるので右クリックしてショートカットを作成
  6. 5で作ったショートカットを4で作ったユーザーの送るメニューへドラッグアンドドロップ

shortcut_by_project

昔はよかったのですが、.NET4.0以降上記手順で作成されるのは”アドパタイズショートカット”というやつらしく、SendToフォルダへは登録されるものの「送る」メニューに登録されません、ありゃ困った。

 

3.プログラマならコードでしょう

2の問題のため、Orcaを使う方法やvbsを使う方法が紹介されています。が、私はマネージコードしか書きたくないのでC#の方法を紹介。簡単な話で、Installerクラスを使います。このInstallerクラスはセットアッププロジェクトではなくインストールするアプリケーションそのもの、今回でいうとWinFormsアプリのプロジェクトに追加します。ショートカットも作成するので以下を参照追加。

[COM] Windows Script Host Object Model
[.NET] System.Configuration.Install

前者はプロジェクトの参照設定に “IWshRuntimeRubrary” と表示されますが、このプロパティを開き [相互運用機能の埋め込み] をFalseにしておきます。

ひとてま2

コードはこちら。

AddSendToInstaller.cs

namespace SendToSupportWinFormsApp
{
    using System;
    using System.IO;
    using System.Configuration.Install;
    using System.Reflection;
    using System.ComponentModel;
    using IWshRuntimeLibrary;

    [RunInstaller(true)]
    public class AddSendToInstaller : Installer
    {
        private const string shortcutFilePathKey = "shortcutFilePath";
        public override void Install(System.Collections.IDictionary stateSaver) {
            // Debug時は以下を有効に
            // System.Diagnostics.Debugger.Launch();

            string targetPath = Assembly.GetExecutingAssembly().Location;
            string fileName = Path.GetFileNameWithoutExtension(targetPath);
            string shortcutPath = Environment.GetFolderPath(Environment.SpecialFolder.SendTo) + @"\" + fileName + ".lnk";
            IWshShell shell = new WshShellClass();
            IWshShortcut shortcut = shell.CreateShortcut(shortcutPath) as IWshShortcut;
            shortcut.TargetPath = targetPath;
            shortcut.Save();

            stateSaver[shortcutFilePathKey] = shortcutPath;
            base.Install(stateSaver);
        }

        public override void Uninstall(System.Collections.IDictionary savedState) {
            // Debug時は以下を有効に
            // System.Diagnostics.Debugger.Launch();

            if(savedState.Contains(shortcutFilePathKey)) {
                string shortcutFilePath = savedState[shortcutFilePathKey] as string;
                if(System.IO.File.Exists(shortcutFilePath)) {
                    System.IO.File.Delete(shortcutFilePath);
                }
            }
            base.Uninstall(savedState);
        }
    }
}

この上でセットアッププロジェクトを変更します(2の手順で作ったショートカットは無駄ですので削除します)。

  1. セットアッププロジェクトを右クリックし、「表示」->「カスタム動作」をクリック
  2. カスタム動作のインストールとアンインストールそれぞれについて、右クリックしてカスタム動作の追加をクリックして、アプリケーションフォルダを選択してOK。

custom_action

これをしないと上で作ったインストーラクラスが無視されるので注意。これでセットアッププロジェクトを作ってインストールすると「送る」メニューにアプリが登録されます。

tuika2

実行するとこう。めでたし。

exe

ただVS2012以降セットアッププロジェクトがプロジェクトテンプレートからなくなってしまったのでVS2010までの手法ということになります。InstallShield LimitedEditionを使う必要がありますね。