重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

こちら【http://www.kab-studio.biz/Programing/Codian/Shel …】のサイトを参考にしてショートカットからアプリ実行ファイルのフルパスを取得しようとしています。開発環境はMicrosoft Visual Studio 2010です。
以下のソースで特にエラーなく実行はできるのですが、アプリによっては取得できないものがあります。
デスクトップにあるショートカットアイコンですべて動作テストを行っています。
Janetter.lnk、Microsoft Visual Studio 2010.lnk、MetasequoiaLER3.0.lnk、Microsoft Office Word 2007.lnk
の四つを試しました。
JanetterとVisualStudioはフルパスが問題なく取得でき、アドレスをたどってアイコンをダブルクリックしてみるとアプリが起動できます。
Metasequoiaは全く取得できず、wordはC:\windows\Installer\{90120000-0011-0000-0000000FF1CE}}\wordicon.exeを取得しました。
アドレスをたどり、wordicon.exeをダブルクリックして起動しようとしてもwordを起動することはできませんでした。

アプリによって取得できるものとできないものの差は何なのでしょうか?
どうすればすべての実行ファイルのフルパスを取得できるでしょうか、アドバイスを頂けると助かります。

#include <windows.h>
#include <shlobj.h>
#include <iostream>
#include <string>

IShellLink *pShellLink; //IShellLinkへのポインタ
IPersistFile *pPersistFile; //IPersistFileへのポインタ

bool getLnk(){
HRESULT hRes;//結果

//メンバの初期化
pShellLink = NULL;
pPersistFile = NULL;

//OLE【 Object Linking and Embedding 】アプリケーションソフト間でデータを転送・共有するための仕組み
//OLEを使うために初期化
hRes = ::CoInitialize(NULL);

//エラー対処
if(hRes == E_OUTOFMEMORY) return false;
if(hRes == E_INVALIDARG) return false;
if(hRes == E_UNEXPECTED) return false;

// 空のインターフェイスを用意
// ファイル情報の格納場所の確保
hRes = ::CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink,(LPVOID *)&pShellLink);

//エラー対処
if(hRes == CLASS_E_NOAGGREGATION) return false;
if(hRes == REGDB_E_CLASSNOTREG) return false;

//IPersistFileへのポインタを取得 IShellLinkの操作に必要
hRes = pShellLink->QueryInterface(IID_IPersistFile,(LPVOID*)&pPersistFile);

//エラー対処
if(hRes != S_OK) return false;

return true;
}

bool UngetLnk(){

//IPersistFileへのポインタの破棄
if(pPersistFile != NULL) pPersistFile->Release();

//IShellLinkへのポインタの破棄
if(pShellLink != NULL) pShellLink->Release();

::CoUninitialize();

return true;

}

bool LinkLoad(LPCTSTR lnkpass){

HRESULT hRes; // 結果
OLECHAR ochLinkFile[MAX_PATH];

//ユニコードに変換
::MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,lnkpass,-1,ochLinkFile,MAX_PATH);

//ショートカットファイルの読み込み
hRes = pPersistFile->Load(ochLinkFile,STGM_READ);
if(hRes != S_OK) return false;

//リンクの決定 ショートカットの読み込み
hRes = pShellLink->Resolve(NULL,SLR_UPDATE);
if(hRes != NOERROR) return false;

return true;
}


int main(){

LPCTSTR lnkpath="C:\\Users\\Momo\\Desktop\\Microsoft Office Word 2007.lnk";
LPSTR fullpath;
char x[100];
fullpath = x;

if(getLnk()){
LinkLoad(lnkpath);
pShellLink->GetPath(fullpath, _MAX_PATH, NULL, 0);
UngetLnk();
std::cout << fullpath << std::endl;
}else std::cout << "false" << std::endl;


return 0;
}

A 回答 (1件)

回答がないようなので、字面だけ見た印象を。


ただし、非専門家で、MS Windows も C++ もほとんど、触れたことがありません。

- 関数 LinkLoad() の引数の lnkpass は lnkpath のミススペルか。
-- 別に、ミススペルでも、関数内で整合してるので、問題ないと思います。

- 関数 main() の fullpath は 100 じゃなく MAX_PATH の領域を確保しないとダメなのでは。
-- コンパイラが文句言わないなら、問題ないのかもしれません。

- main() 中のメソッド呼び出し GetPath() の _MAX_PATH は MAX_PATH のミススペルか。
-- こっちのミススペルはダメだと思います。

- 関数 UngetLnk() は getLnk() と対(つい)で、main() の else 側でも必要なのでは。
-- つまり、if 文の下に移動したほうが良いかと思います。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!