C#のプログラムで自分自身をPin止めする(4)

C++でSystem.AppUserModel.IDを設定できるのであれば、それと同じことをC#でやればいいのです。
実際そういうアプローチで既に実践している人はいて、たとえば

なんかはC#からIShellLink I/FをCOMで操作する方法で実現しています。

ですが、今回使っているWindows7 API Code Packの中にも

  • SystemProperties.System.AppUserModel Class

とか

  • ShellProperties.PropertySystemAppUserModel Class

なんていう、いかにもそれっぽいものがあります。
これらを使えばなんとかなるんじゃないか、ということでいろいろ試行錯誤してみたところ、こんなコードにたどり着きました。

using Microsoft.WindowsAPICodePack.Shell;
using Microsoft.WindowsAPICodePack.Shell.PropertySystem;

        // ショートカットファイルにSystem.AppUserModel.IDを設定
        void SetApplicationIdForShortcut(string path, string appId)
        {
            ShellFile shellfile = ShellFile.FromFilePath(path);
            ShellProperties property = shellfile.Properties;

            using (ShellPropertyWriter writer = property.GetPropertyWriter())
            {
                writer.WriteProperty(property.System.AppUserModel.ID.PropertyKey, appId);
            }
        }

ショートカットファイルのフルパスからShellPropertiesのオブジェクトを取得するためにShellFile.FromFilePath()を使用しています。
ShellFile Class以外にShellLink Classという名前からしていかにもリンクファイル用のクラスも存在するのですが、今のWindow7 API Code PackにはフルパスからShellLinkオブジェクトを取得する方法がないように見えたので。
そしてShellPropertiesさえ取得できれば後はShellProperties.System.AppUserMode.IDに値を設定すればOK…と思ったのですが、このプロパティはgetのみでsetができません。
なので、ShellPropertyWriterオブジェクトを取得してShellPropertyWriter.WriteProperty()経由で更新する、というひと手間が必要となります。

これでC#のコードだけでショートカットファイルにAppIDを設定できるようになりました…と思ったのですが、Windows7ならこれでうまくいくものの、Windows8では依然としてアイコンが分裂する症状が残ったままです。
このプログラムで設定したWindows8のショートカットファイルを解析してもプロパティは正しく設定されているようですし、前回紹介したwin7appidはWindows8でも正常に動作するので、ますますわけがわからない状態になってます。

というわけで、現状は自分の力不足によりここまでです。
どなたかこれをWindows8でも正常動作するように修正していただけるか、あるいは何かヒントをいただければ幸いです。
情報をお持ちの方はぜひトラックバックかコメント願います。