1

アプリケーションへのショートカットをスタートアップ フォルダに保存しようとしています。すべてコンパイルされますが、実際にはゲームを保存できません。エラーはhres = ppf->Save(wsz, TRUE);、hres が -2147024891 に設定されている で発生しているようです。それが特定の何かを意味する場合、私はまだ何を発見していません. 私のコードは MSDN からほぼそのままコピーされているため、なぜ機能しないのかかなり混乱しています。スタートアップ フォルダにショートカットを保存する権限がないのでしょうか。繰り返しになりますが、私もこれらすべてにかなり慣れていないため、基本的なエラーが発生している可能性があります。問題が発生した場合に備えて、すべての #include もコピーしています。

編集:
まず、混乱を避けるために、これは CLI ベースの C++ です。

hres のエラー チェックは、MDSN コードの一部にすぎません。これは、Web サイトの例とほぼ同じコードです。ブレークポイントを設定しました。これにより、行が実行された直後に hres が -2147024891 になることがわかりhres = ppf->Save(wsz, TRUE);ます。

これらが間違っている場合、mediaMaestroLocation は に設定され、startupDestination は に設定され"C:\Users\Keith\Documents\Visual Studio 2012\Projects\MediaMaestro\Debug\MediaMaestro.exe"ます"C:\Users\Keith\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup"。exe の場所は素晴らしいように見えますが、宛先フォルダー パスの後に \ がないことが問題なのだろうかと思います。私はすでにそれをチェックしていたでしょうが、最初にそれを行う方法を理解するのに数分かかる必要があります.

#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; 
}


関数を呼び出す UI のクリック イベントを次に示します。

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
       }
   }



足りないものはありますか?

4

2 に答える 2

3

出力フォルダーのパスに名前を付けるだけでは不十分であることがわかりました。ファイルと拡張子にも名前を付ける必要がありました。これを行っている例を他に 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 インターフェイスにフィードすると、必要に応じて保存されます。

于 2013-09-02T04:42:06.930 に答える
0

hres を 0 に初期化しただけで、それが成功したかどうかを確認しましたか? あなたはそれをどこかで宣言することは決してありません.-2147024891はおそらく変数がまだ初期化されていないことを意味します.

hres = ppf->Save(wsz, TRUE);大げさな推測では、:行に到達することさえないため、初期化されていません。

よろしくお願いします。

于 2013-09-01T01:53:33.520 に答える