Метод IPersistFile :: Save не удается сохранить ярлык

Я пытаюсь сохранить ярлык для моего приложения в папке автозагрузки. Все это компилируется, но на самом деле не может спасти игру. Кажется, ошибка возникает в hres = ppf->Save(wsz, TRUE);где hres установлен на -2147024891. Если это означает что-то конкретное, я еще не обнаружил, что. Мой код скопирован почти дословно из MSDN, поэтому я довольно растерялся, почему он не работает. Возможно, у меня нет разрешения на сохранение ярлыка в папке автозагрузки? Опять же, я также довольно новичок во всем этом, так что это может быть какая-то основная ошибка, которую я делаю. Я копирую все мои #include, а также в случае, если это проблема.

Редактировать:

Во-первых, чтобы избежать путаницы, это C ++ на основе CLI.


Проверка hres на наличие ошибок является лишь частью кода MDSN. Это действительно почти тот же код из примера на сайте. Я поставил точки останова, вот откуда я знаю, что hres становится -2147024891 сразу после строки hres = ppf->Save(wsz, TRUE); это запустить.

В случае, если это не так, mediaMaestroLocation устанавливается в "C:\Users\Keith\Documents\Visual Studio 2012\Projects\MediaMaestro\Debug\MediaMaestro.exe" и startupDestination — это "C:\Users\Keith\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup", Хотя расположение исполняемого файла выглядит великолепно, мне интересно, имеет ли значение отсутствие \ \ после пути к папке назначения. Я бы уже проверил это, но мне нужно потратить пару минут, чтобы понять, как это сделать в первую очередь.

#include <windows.h>
#include <string>
#include <stdio.h>
#include <shobjidl.h>
#include <shlobj.h>
#include "objbase.h"#include <objidl.h>
#include <shlguid.h>
#include <winnls.h>

#using <System.dll>
#using <System.Windows.Forms.dll>

using namespace System;
using namespace System::Windows::Forms;

char startupDestination[MAX_PATH];
char mediaMaestroLocation[MAX_PATH];

DWORD nChars = 0;
BOOL yChars = 0;

HRESULT CreateLink()
{
CoInitializeEx( NULL, 0 );
HRESULT hres = 0;
IShellLink* psl;

if (SUCCEEDED(hres))
{

// Get a pointer to the IShellLink interface. It is assumed that CoInitialize
// has already been called.
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl);
if (SUCCEEDED(hres))
{
IPersistFile* ppf;

// Set the path to the shortcut target and add the description.
psl->SetPath(mediaMaestroLocation);
psl->SetDescription("Media Maestro");

// Query IShellLink for the IPersistFile interface, used for saving the
// shortcut in persistent storage.
hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf);

if (SUCCEEDED(hres))
{
WCHAR wsz[MAX_PATH];

// Ensure that the string is Unicode.
MultiByteToWideChar(CP_ACP, 0, startupDestination, -1, wsz, MAX_PATH);// Add code here to check return value from MultiByteWideChar
// for success.

// Save the link by calling IPersistFile::Save.
hres = ppf->Save(wsz, TRUE);
ppf->Release();
}
psl->Release();
}
}
CoUninitialize();
return hres;
}

Вот событие click в пользовательском интерфейсе, который вызывает функцию:

void settingsLaunchOnStart_Click( Object^ Sender, EventArgs^ e )
{

if (settingsLaunchOnStart->Checked == false)
{
HRESULT r;
nChars = GetModuleFileName( NULL, mediaMaestroLocation, sizeof(mediaMaestroLocation) );
yChars = SHGetFolderPath( NULL, CSIDL_STARTUP, NULL, SHGFP_TYPE_CURRENT, startupDestination);
r = CreateLink();
}
else if (settingsLaunchOnStart->Checked == true)
{

//code to remove the shortcut
}
}

Есть что-то, чего мне не хватает?

1

Решение

Оказалось, что было недостаточно назвать путь к выходной папке, мне пришлось также назвать файл и расширение. Мне кажется странным, учитывая, что я не думаю, что видел еще один пример, делающий это. В любом случае, вот мой обновленный рабочий код:

HRESULT CreateLink()
{
CoInitializeEx( NULL, 0 );
HRESULT hres = 0;
IShellLink* psl;

if (SUCCEEDED(hres))
{

// Get a pointer to the IShellLink interface. It is assumed that CoInitialize
// has already been called.
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_ALL, IID_IShellLink, (LPVOID*)&psl); //CLSCTX_ALL CLSCTX_INPROC_SERVER (void**)&psl (LPVOID*)&psl
if (SUCCEEDED(hres))
{
IPersistFile* ppf;

// Set the path to the shortcut target and add the description.
psl->SetPath(mediaMaestroLocation);
psl->SetDescription(L"Media Maestro");
psl->SetIconLocation(mediaMaestroLocation, 0);

// Query IShellLink for the IPersistFile interface, used for saving the
// shortcut in persistent storage.
hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf); //(void**)&psl (LPVOID*)&ppf

if (SUCCEEDED(hres))
{
WCHAR wsz[MAX_PATH];

// Save the link by calling IPersistFile::Save.

hres = _wmakepath_s( wsz, _MAX_PATH, NULL, startupDestination,
L"MediaMaestro", L"lnk" );

hres = ppf->Save(wsz, TRUE);
ppf->Release();
}
psl->Release();
}
}
CoUninitialize();
return hres;
}



Добавление _wmakepath_s позвольте мне добавить название моей программы и ее расширение в путь к файлу, который я получил от SHGetFolderPath, Как только я передаю это в интерфейс IPersistFile, он сохраняет как следует.

3

Другие решения

Вы только инициализировали hres на 0, а затем проверяете, успешно ли это? Вы никогда не объявляете это где-то, и -2147024891, вероятно, означает, что переменная еще не инициализирована.

дикое предположение, что он даже не достигает hres = ppf->Save(wsz, TRUE); line и, следовательно, он не инициализирован: попробуйте вывести несколько точек останова при отладке и, возможно, использовать некоторые часы для просмотра переменных 🙂

С наилучшими пожеланиями.

0

По вопросам рекламы [email protected]