Winapi создать ярлык не удалось - PullRequest
0 голосов
/ 28 августа 2018

Я хочу создать ярлык файла. Я нашел эту страницу Microsoft , в которой описано, как ее написать, и скопировал ее в свой код для использования. Но у меня есть некоторые проблемы, сначала у него была следующая ошибка: « CoInitialize не был вызван. » Я добавляю это CoInitialize(nullptr);, чтобы устранить ошибку, но у меня еще есть ошибка.

когда я отлаживаю его, он имеет «Информация недоступна, символы не загружены для windows.storage.dll» Ошибка в этой строке:

hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl);

и после выполнения, когда я вижу путь назначения, он создает ярлык с именем, но я не могу его открыть, и в нем нет содержимого.

Что не так с этим?

Ошибка вызывает эту проблему?

Я использую VS 2012.

Код отредактирован:

// #include "stdafx.h"
#include "windows.h"
#include "shobjidl.h"
#include <iostream>
#include <shlwapi.h>
#include "objbase.h"
#include "objidl.h"
#include "shlguid.h"

HRESULT CreateLink(LPCWSTR, LPCWSTR, LPCWSTR);

void wmain(int argc, wchar_t* argv[ ], wchar_t* envp[ ])
{

    WCHAR lpwSource[MAX_PATH] = {0};
    lstrcpyW(lpwSource, (LPCWSTR)argv[1]);

    WCHAR lpwDest[MAX_PATH] = {0};
    lstrcpyW(lpwDest, (LPCWSTR)argv[2]);

    HRESULT hResult = 0;
    hResult = CreateLink(lpwSource, lpwDest, NULL);

    if (hResult == S_OK) {

        printf("Shortcut was created successfully.\n");

    } else {

        printf("Shortcut creation failed.\n");

    }

    getchar();
}

HRESULT CreateLink(LPCWSTR lpszPathObj, LPCWSTR lpszPathLink, LPCWSTR lpszDesc)
{
    HRESULT hres = 0;
    IShellLink* psl;

    HRESULT hCoInit = 0;
    hCoInit = CoInitialize(nullptr);

    // 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(lpszPathObj);
        psl->SetDescription(lpszDesc);

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

        if (SUCCEEDED(hres)) {
            // Save the link by calling IPersistFile::Save. 
            hres = ppf->Save(lpszPathLink, TRUE);
            ppf->Release();
        }
        psl->Release();
    }
    return hres;
}

1 Ответ

0 голосов
/ 29 августа 2018

Как я указал в своем комментарии, я собрал код (предыдущая версия ( Вопрос @ VERSION # 2. ) из того, который был во время ответа - который BTW содержал некоторые строковые преобразования, которые, скорее всего, не сработали бы в неанглийских локалях) с VStudio 2013 и запускал его на моем Win 10 (английском) компьютере. Он создал действительный ярлык.

Итак, в коде не было ничего плохого (в том смысле, что он не будет работать).
Проблема заключалась в том, что выходной файл также имел расширение .png , и при его открытии Win будет пытаться использовать средство просмотра / редактора изображений по умолчанию, которое будет обрабатывать файл как PNG (в зависимости от его расширения).
Это, очевидно, неправильно, поскольку файлы .lnk имеют свой собственный формат (как я кратко объяснил в [SO]: какова внутренняя структура ярлыка Windows? (Ответ @ CristiFati) ).

Решением было правильно назвать ярлык (пусть он имеет расширение .lnk ).

Некоторые дополнительные (некритические) примечания о коде (текущее состояние):

  • Нет необходимости в C ++ (11) функциях (nullptr (также проверьте следующий пункт)):

    HRESULT hCoInit = CoInitialize(NULL);
    
  • Реорганизовать #include s. Используйте следующий список:

    #include <windows.h>
    #include <shobjidl.h>
    #include <shlguid.h>
    #include <stdio.h>
    
...