У меня есть рабочий код (C#, но это не важно), который добавляет плитку на начальный экран Windows 8 путем создания файла ярлыка [.lnk
] в специальных каталогах. как %APPDATA%\Microsoft\Windows\Start Menu\Programs
и %LOCALAPPDATA%\Microsoft\Windows\Application Shortcuts
. Я искал и нашел несколько полезных инструментов, таких как lnk-parser
и OblyTile, которые помогли прояснить некоторые аспекты связанных с этим странностей. Я также нашел много статей и вопросов, связанных с этой темой, но ни одна из них не отвечает моим конкретным потребностям.
Я использую IShellLink
(COM interop) для создания ярлыка и IPropertyStore
a> (тот же экземпляр объекта), чтобы добавить некоторые необходимые свойства в файл ссылок. Моя конкретная проблема и вопрос таковы:
Созданная плитка работает так, как ожидалось, почти во всех аспектах. Он запускает нужную команду, имеет заданные цвета фона и переднего плана и отображает связанный с ним значок (.png
изображение 144x144). Проблема в том, что, несмотря на то, что в файл ссылки [System.ItemTypeText
] встроена пользовательская строка метки, она просто отображает имя физического файла без расширения. Это не так ужасно, но я бы предпочел, чтобы Windows учитывала встроенное свойство, а не имя файла.
Что может отсутствовать в файле ссылок, что вызывает такое поведение, а не желаемое?
Бонус
Используя IPropertyStore
, я столкнулся с несколькими так называемыми наборами свойств, которые представляют собой просто свойства, сгруппированные по их GUID
а>. Меня особенно интересуют наборы {b725f130-47ef-101a-a5f1-02608c9eebac}
{86d40b4d-9069-443c-819a-2a54090dccec}
и {9f4c2855-9f79-4b39-a8d0-e1d42de1d5f3}
(последний содержит вездесущий System.AppUserModel.ID
).
Дополнительный вопрос: не могли бы вы указать какой-либо ресурс, который документирует любой (или оба) из этих двух наборов свойств? Я имею в виду, что означает каждое свойство и как они интерпретируются Windows. Это может быть даже полезнее, чем основной вопрос. Неважно, официальный он или неофициальный.
Примечание
Использование OblyTile
путем вызова его из командной строки не является вариантом в соответствии с требованиями. Согласно тому, что я заметил, мне может потребоваться добавить пользовательский файл resources.pri
в родительский каталог целевого файла ссылки. Хотелось бы избежать этого, если это вообще возможно, потому что формат не документирован.
Образец кода
Класс ShellLink
— это старая добрая и скучная оболочка для интерфейсов IShellLink
и IPropertyStore
COM. Он работает просто отлично, я полностью уверен, что проблема не в нем.
using System;
using System.IO;
namespace Shell32NET
{
public static class Win8Tiles
{
#region Fields
/// <summary>
/// b725f130-47ef-101a-a5f102608c9eebac
/// </summary>
static readonly Guid ItemTypeGroup = new Guid(
0xb725f130, 0x47ef, 0x101a, 0xa5, 0xf1, 0x02, 0x60, 0x8c, 0x9e, 0xeb, 0xac
);
/// <summary>
/// b725f130-47ef-101a-a5f102608c9eebac, 4
/// </summary>
static readonly PropertyKey SystemItemTypeText = new PropertyKey(ItemTypeGroup, 4);
/// <summary>
/// 86d40b4d-9069-443c-819a2a54090dccec
/// </summary>
static readonly Guid TilePropertiesGroup = new Guid(
0x86d40b4d, 0x9069, 0x443c, 0x81, 0x9a, 0x2a, 0x54, 0x09, 0x0d, 0xcc, 0xec
);
/// <summary>
/// 86d40b4d-9069-443c-819a2a54090dccec, 2
/// </summary>
static readonly PropertyKey TileSmallImageLocation = new PropertyKey(TilePropertiesGroup, 2);
/// <summary>
/// 86d40b4d-9069-443c-819a2a54090dccec, 4
/// </summary>
static readonly PropertyKey TileBackgroundColor = new PropertyKey(TilePropertiesGroup, 4);
/// <summary>
/// 86d40b4d-9069-443c-819a2a54090dccec, 5
/// </summary>
static readonly PropertyKey TileForegroundColor = new PropertyKey(TilePropertiesGroup, 5);
/// <summary>
/// 86d40b4d-9069-443c-819a2a54090dccec, 11
/// </summary>
static readonly PropertyKey TileDisplayName = new PropertyKey(TilePropertiesGroup, 11);
/// <summary>
/// 86d40b4d-9069-443c-819a2a54090dccec, 12
/// </summary>
static readonly PropertyKey TileImageLocation = new PropertyKey(TilePropertiesGroup, 12);
/// <summary>
/// 86d40b4d-9069-443c-819a2a54090dccec, 14
/// </summary>
static readonly PropertyKey TileUnknownFlags = new PropertyKey(TilePropertiesGroup, 14);
/// <summary>
/// 9f4c2855-9f79-4b39-a8d0e1d42de1d5f3
/// </summary>
public static readonly Guid MetadataGroup = new Guid(
0x9f4c2855, 0x9f79, 0x4b39, 0xa8, 0xd0, 0xe1, 0xd4, 0x2d, 0xe1, 0xd5, 0xf3
);
/// <summary>
/// 9f4c2855-9f79-4b39-a8d0e1d42de1d5f3, 5
/// </summary>
public static readonly PropertyKey AppUserModelID = new PropertyKey(MetadataGroup, 5);
/// <summary>
/// b6578b39-11f9-449b-8438cb5cf03b7d9c
/// </summary>
static readonly Guid UnknownGroup1 = new Guid(
0xb6578b39, 0x11f9, 0x449b, 0x84, 0x38, 0xcb, 0x5c, 0xf0, 0x3b, 0x7d, 0x9c
);
#endregion
/// <summary>
/// Creates a tile in the Windows 8 start screen.
/// </summary>
/// <param name="target">The file to be executed when the tile is clicked.</param>
/// <param name="appId">The registering application's ID.</param>
/// <param name="title">The caption text for the tile.</param>
/// <param name="imageFilename">The image to be shown in the tile.</param>
/// <param name="background">Background color for the tile.<para>
/// Must be in the hex ARGB form: 0xAARRGGBB.
/// Where AA is the alpha channel value, RR is for red, GG for green and BB for blue.
/// </para></param>
/// <param name="foreground">Foregreound color for the tile, in the
/// same format as <paramref name="background"/>.</param>
public static void CreateTile(
string target,
string appId,
string title,
string imageFilename,
uint background,
uint foreground
)
{
string appdata = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
if (appdata == null)
throw new NotSupportedException("The user's roaming application data directory does not exist.");
using (var link = new ShellLink())
{
link.TargetPath = target;
// The .lnk icon location and index (not quite important). Just using some defaults.
link.SetIconLocation(@"%SystemRoot%\System32\SHELL32.DLL", 135);
link.SetProperty(AppUserModelID, appId);
// Apparently required properties (AS-IS).
link.SetProperty(new PropertyKey(MetadataGroup, 11), true);
link.SetProperty(new PropertyKey(MetadataGroup, 19), "Microsoft.InternetExplorer.Default");
link.SetProperty(
new PropertyKey(MetadataGroup, 20),
"-contentTile -formatVersion 0x00000002 -securityFlags 0x00000000 -url 0x00000057"
);
/**
* These are not really working at the moment; the tile just shows the name of the .lnk file.
*/
link.SetProperty(SystemItemTypeText, title);
link.SetProperty(TileDisplayName, title);
// Background and foreground.
link.SetProperty(TileBackgroundColor, background);
link.SetProperty(TileForegroundColor, foreground);
// Small and normal tile icon. Set your own.
string fileUri = new Uri(imageFilename).AbsoluteUri;
link.SetProperty(TileImageLocation, fileUri);
link.SetProperty(TileSmallImageLocation, fileUri);
// Apparently required, not the tiniest clue of why.
link.SetProperty(TileUnknownFlags, 0x41u);
link.SetProperty(new PropertyKey(UnknownGroup1, 4), 0x41u);
// The file should be saved to %LOCALAPPDATA%\Microsoft\Windows\Application Shortcuts
string filename = Path.Combine(appdata, @"Microsoft\Windows\Application Shortcuts");
filename = Path.Combine(filename, "Win8Tiles-Test");
Directory.CreateDirectory(filename);
filename = Path.Combine(filename, title + ".lnk");
link.Save(filename);
}
}
}
}
propkey.h
, хотя я заметил существенные различия между тем, на который вы указываете, и файлом из SDK на моем локальном диске. Я ошибся с первым GUID; Я обновляю вопрос. Я не могу найти нигде на Земле (в Интернете) что-либо об этих двух наборах, явно связанных с плитками Windows 8. Постараюсь поделиться репродукцией. - person Leandro   schedule 05.06.2014PropertyKey
— это простая структура, содержащаяGUID
и целочисленный индекс, проходящий через конструктор, как видно из кода.ShellLink
просто упаковывает вызовы вышеупомянутых интерфейсов COM. Там простой простой код. Я абсолютно уверен, что проблема не в этом резервном коде, а в чем-то, что отсутствует в свойствах, устанавливаемых в общем методеCreateTile(...)
. - person Leandro   schedule 24.06.2014{B725F130-47EF-101A-A5F1-02608C9EEBAC}
,10
]. Каноническое имя:System.ItemNameDisplay
. Это свойство я должен был использовать вместоSystem.ItemTypeText
. Не знаю, откуда я это взял. В любом случае, большое спасибо. Из любопытства: как был сгенерирован этот файл журнала? Откуда берутся эти канонические имена? - person Leandro   schedule 24.06.2014