Как создать ярлык на рабочем столе (ссылку), но с собственным расширением файла ярлыка (например, .appfolder) вместо .lnk программно на С#?

Я зарегистрировал расширение файла ярлыка с именем .appfolder в реестре: экспорт регистров

Он должен вести себя как обычный ярлык .lnk, но должен иметь окончание .appfolder (на то есть причины).

Теперь я хочу программно создать ярлык с окончанием/расширением этого файла на С#. По умолчанию для окончания .lnk он работает с:

public static void CreateShortcut(string shortcutName, string shortcutPath, string targetFileLocation)
    {
        string shortcutLocation = Path.Combine(shortcutPath, shortcutName + @".lnk");
        WshShell shell = new WshShell();
        IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(shortcutLocation);
        shortcut.Description = "My shortcut description";
        shortcut.TargetPath = targetFileLocation;                 
        shortcut.Save();
    }

//e.g:
CreateShortcut("Example (Notepad)", Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
                "notepad.exe");

Когда я пытаюсь изменить расширение файла в этой строке string shortcutLocation = Path.Combine(shortcutPath, shortcutName + @".lnk"); на .appfolder, я получаю System.Runtime.InteropServices.COMException (HRESULT: 0x80020009 (DISP_E_EXCEPTION)).

Когда я пытаюсь изменить расширение файла после создания/сохранения ярлыка с помощью File.Move(shortcutLocation, Path.ChangeExtension(shortcutLocation, ".appfolder"));, я получаю файл на рабочем столе со следующими свойствами: изображение

Как видите, Windows распознает расширение .appfolder как ярлык, но вкладка «Ярлык» отсутствует, и когда я дважды щелкаю файл для выполнения, ничего не происходит.

Итак, либо моя регистрация .appfolder не является полной, хотя она должна быть ... или как программно создать ярлык с собственным расширением файла ярлыка на С#?

Спасибо за помощь ;)

ИЗМЕНИТЬ:

Я попробовал другой способ создать ярлык программно:

void main() {
    IShellLink link = (IShellLink)new ShellLink();

    // setup shortcut information
    link.SetDescription("My Description");
    link.SetPath(@"notepad.exe");

    // save it
    IPersistFile file = (IPersistFile)link;
    string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
    file.Save(Path.Combine(desktopPath, "Notepad.appfolder"), false);
}

    [ComImport]
    [Guid("00021401-0000-0000-C000-000000000046")]
    internal class ShellLink
    {
    }

    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("000214F9-0000-0000-C000-000000000046")]
    internal interface IShellLink
    {
        void GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, out IntPtr pfd, int fFlags);
        void GetIDList(out IntPtr ppidl);
        void SetIDList(IntPtr pidl);
        void GetDescription([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName);
        void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);
        void GetWorkingDirectory([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath);
        void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);
        void GetArguments([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath);
        void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
        void GetHotkey(out short pwHotkey);
        void SetHotkey(short wHotkey);
        void GetShowCmd(out int piShowCmd);
        void SetShowCmd(int iShowCmd);
        void GetIconLocation([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, int cchIconPath, out int piIcon);
        void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);
        void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved);
        void Resolve(IntPtr hwnd, int fFlags);
        void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
    }

Он создает файл ярлыка без каких-либо ошибок (например, System.Runtime.InteropServices.COMException, см. выше), но он также не запускает файл .exe двойным щелчком.


person Blood_Working_    schedule 05.01.2020    source источник
comment
Вы пытались создать ярлык .appfolder вручную? Это работает? Вы можете зарегистрировать обработчик протокола, например http://, и использовать модификацию реестра, чтобы добавить свой собственный appfolder:// обработчик протокола. Затем вы можете создать обычный .lnk файл с пользовательской appfolder:// ссылкой.   -  person oleksa    schedule 05.01.2020
comment
@oleksa Как создать ярлык .appfolder вручную? Создание обычного .lnk и переименование в .appfolder через блокнот не работает, как и File.Move(...). Или что вы имеете в виду? Предлагаемое вами решение с URL-адресом, к сожалению, не работает для моего приложения. Это должно быть расширение .appfolder.   -  person Blood_Working_    schedule 05.01.2020
comment
ну, вам придется найти другой способ, если нет возможности создать рабочий ярлык .appfolder вручную. В таком случае это не вопрос программирования. Но пользовательский обработчик протокола — это рабочая функция (я использовал ее), которая может запускать ваше приложение со ссылкой appfolder:// в качестве параметра, например c:\app\customhandler.exe appfolder://notepad.exe%20%or%20%notepad++.exe что угодно. Вероятно, это сработает для вас   -  person oleksa    schedule 05.01.2020


Ответы (1)


Я решил это: моя регистрация .appfolder не была полностью правильной, чтобы работать точно так же, как файл ярлыка .lnk. Следуйте этой инструкции. После этого оба упомянутых выше метода в C# работают.

person Blood_Working_    schedule 09.01.2020