|
Can you tell me what kind of shortcuts you are trying to resolve, i.e. MS Word document shortcut or MS Word exe shortcut?
Yes, I used shortcuts of MSOffice (Word, Excel, Access) in the main menu of programs (or copy on Desktop).
I'll try to look into it, though can not promise anything (unfortunately I do not have much free time right now - too much going on at work).
I understand you. I have the same problems .
Thanks for your participation and your goodwill. (Sorry for my bad English.)
The solution of my problem looks as follows.
<br />
#include <ShlObj.h><br />
#include <AtlBase.h><br />
#include <ShlWApi.h><br />
#define _WIN32_MSI 110<br />
#include <Msi.h><br />
<br />
#pragma comment(lib, "ShlWApi")<br />
#pragma comment(lib, "msi")<br />
<br />
#define RFLAGS (SLR_INVOKE_MSI | SLR_NOLINKINFO | SLR_NO_UI | SLR_NOUPDATE | SLR_NOTRACK)<br />
<br />
BOOL _stdcall GetShortcutTarget(IN CONST LPCTSTR ptszLinkPathSpec, <br />
OUT LPTSTR ptszTargetPathSpec, IN CONST UINT cch)<br />
{<br />
BOOL bRet = FALSE;<br />
if (ptszLinkPathSpec && ptszTargetPathSpec && cch &&<br />
!IsBadStringPtr(ptszLinkPathSpec, MAX_PATH) &&<br />
!IsBadWritePtr(ptszTargetPathSpec, cch) &&<br />
PathFileExists(ptszLinkPathSpec))<br />
{<br />
TCHAR tszComponentCode[MAX_FEATURE_CHARS+1];<br />
TCHAR tszProductCode[MAX_FEATURE_CHARS+1];<br />
ptszTargetPathSpec[0] = _T('\0');<br />
tszComponentCode[0] = _T('\0');<br />
tszProductCode[0] = _T('\0');<br />
<br />
if (ERROR_SUCCESS == MsiGetShortcutTarget(ptszLinkPathSpec, tszProductCode, NULL,<br />
tszComponentCode))<br />
{<br />
DWORD dw = cch;<br />
bRet = (INSTALLSTATE_LOCAL == MsiGetComponentPath(tszProductCode, tszComponentCode,<br />
ptszTargetPathSpec, &dw));<br />
}<br />
else<br />
{<br />
if (SUCCEEDED(CoInitialize(NULL)))<br />
{<br />
CComPtr<IShellLink>piLink;<br />
if (SUCCEEDED(piLink.CoCreateInstance(CLSID_ShellLink)))<br />
{<br />
CComQIPtr<IPersistFile>piFile(piLink);<br />
if (piFile)<br />
{<br />
CComBSTR bstrPath = ptszLinkPathSpec;<br />
if (SUCCEEDED(piFile->Load(bstrPath, 0)))<br />
{<br />
if (SUCCEEDED(piLink->Resolve(NULL, RFLAGS)))<br />
{<br />
bRet = (SUCCEEDED(piLink->GetPath(ptszTargetPathSpec, cch, NULL,<br />
SLGP_SHORTPATH)));<br />
}<br />
}<br />
}<br />
}<br />
CoUninitialize();<br />
}<br />
}<br />
bRet = (bRet && PathFileExists(ptszTargetPathSpec));<br />
}<br />
return bRet;<br />
} <br />
Best regards,
Sergey
|
|
|
|
|
I did... I get the same thing he does. For the link...
+ lpstrLnkFile 0x003a4270 "C:\Documents and Settings\All Users\Start Menu\Open Office Document.lnk"
I get...
+ buffer 0x0013e3c8 "C:\WINDOWS\Installer\{90110409-6000-11D3-8CFE-0150048383C9}\misc.exe" wchar_t [261]
back from your fuction... when I send it with the args and working directory to ShellExec() I don't get the same response as I do when I click on the shortcut.
Shaun Harrington
shaun@planetharrington.com
www.planetharrington.com
|
|
|
|
|
So then I added the second attempt... the GetShortcutTarget() function and it works on MSI style links... but I have a link it doesn't work on... the "Program Compatibility Wizard" found under the "Accessories" sub menu. Any ideas?
Shaun Harrington
shaun@planetharrington.com
www.planetharrington.com
-- modified at 21:15 Wednesday 28th June, 2006
|
|
|
|
|
|
|
|
Shaun,
check this article[^] out. Could be useful.
|
|
|
|
|
Thanks for the lead... still no luck though.
I am focused on the IShellLinkDataList interface right now... seems like it is the right interface to get more data from but so far I have not been able to get any data blocks from it! I use ->GetFlags() and that works but when I call CopyDataBlock the pointer is always null no matter what SIG I use.
Shaun Harrington
shaun@planetharrington.com
www.planetharrington.com
|
|
|
|
|
I can see a problem to but I get "C:\WINDOWS\Installer\{27B3563C-561C-4924-8C0E-EA102264873F}\DHCPMgr.Ico"
There is an article that tells what to do but I couldn't get it to work either:
http://www.eggheadcafe.com/ng/microsoft.public.win32.programmer.ole/post313974.asp
BillJam11
|
|
|
|
|
I get exactly the same info for Office 2003 .lnk's
and also for Windows Live Messenger:
C:\WINDOWS\Installer\{7A837109-E671-470D-B489-F1EBE471D220}\MsblIco.Exe
|
|
|
|
|
Does anyone know how to programmatically create a Desktop
icon (.lnk) to an app. in MSVC 2.0. I have searched everywhere: MSDN, the internet, all my lit. I can't believe
there's so little info on the most basic feature of Windows.
I would think there would be plenty of examples for MSVC 1.0
on up.
|
|
|
|
|
Hello,
I'm just trying to find a way to do the same process of functions above, but now in C. However, I have found no resources at internet nor even in the microsoft documentation. Does anyone know how to make it?
__________
Chulips
|
|
|
|
|
I do not understand. Why can't you use these functions in C?
|
|
|
|
|
Well, until know I don't know how to map the COM classes and templates in C. Have you any idea?
Thanks!
__________
Chulips
|
|
|
|
|
I will not lie, I have never done it in C, I just do not understand why it can not be done. Link with the necessary dlls - that's all, right? I could be wrong, though.
May be you should ask this question in C++ forum.
With respect,
Igor.
|
|
|
|
|
Hello,
Here is code to create a Desktop link using C.
In contray with C++ you have to use a pointer to the
Vtable in order to get to the IShellLink object.
Hope this helps.
I have a problem to use when I want to give a parameter
to the link object eg. I want to create a shortcut like
"C:\\MyPath\\AppName\\AppName.exe -Settings".
If you find out resolve please post....
<font face="Courier New">
HRESULT CreateLink(LPCSTR lpszPathObj,
LPSTR lpszPathLink, LPSTR lpszDesc)
{
HRESULT hres;
IShellLink* psl;
TCHAR lpBuffer[1024] = {""};
TCHAR szAppName[256] = {""};
strcpy(szAppName, lpszDesc);
if (strlen(lpszPathLink) == 0) {
GetWindowsDirectory(lpBuffer, 256);
wsprintf(lpBuffer, "%s%s%s%s", lpBuffer, "\\Desktop\\", szAppName, ".lnk\0");
lpszPathLink = lpBuffer;
}
CoInitialize(NULL);
hres = CoCreateInstance(&CLSID_ShellLink, NULL,
CLSCTX_INPROC_SERVER, &IID_IShellLink, &psl);
if (SUCCEEDED(hres)) {
IPersistFile* ppf;
hres = psl->lpVtbl->SetPath(psl, lpszPathObj);
if (! SUCCEEDED (hres))
MessageBox(NULL, "SetPath storing failed", szAppName, MB_OK);
hres = psl->lpVtbl->SetIconLocation(psl, lpszPathObj, 0);
if (! SUCCEEDED (hres))
MessageBox(NULL, "SetIconLocation failed", szAppName, MB_OK);
hres = psl->lpVtbl->SetDescription(psl, lpszDesc);
if (! SUCCEEDED (hres))
MessageBox(NULL, "SetDescription failed", szAppName, MB_OK);
hres = psl->lpVtbl->QueryInterface(psl, &IID_IPersistFile,
&ppf);
if (! SUCCEEDED (hres))
MessageBox(NULL, "QueryInterface failed", szAppName, MB_OK);
if (SUCCEEDED(hres)) {
WORD wsz[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1,
wsz, MAX_PATH);
hres = ppf->lpVtbl->Save(ppf, wsz, TRUE);
if (! SUCCEEDED (hres))
MessageBox(NULL, "Save failed", szAppName, MB_OK);
ppf->lpVtbl->Release(ppf);
}
psl->lpVtbl->Release(psl);
}
CoUninitialize( );
return hres;
}
|
|
|
|
|
Hello,
Here is code to create a Desktop link using C.
In contray with C++ you have to use a pointer to the
Vtable in order to get to the IShellLink object.
Hope this helps.
I have a problem to use when I want to give a parameter
to the link object eg. I want to create a shortcut like
"C:\\MyPath\\AppName\\AppName.exe -Settings".
If you find out resolve please post....
<font face="Courier New">
HRESULT CreateLink(LPCSTR lpszPathObj,
LPSTR lpszPathLink, LPSTR lpszDesc)
{
HRESULT hres;
IShellLink* psl;
TCHAR lpBuffer[1024] = {""};
TCHAR szAppName[256] = {""};
strcpy(szAppName, lpszDesc);
if (strlen(lpszPathLink) == 0) {
GetWindowsDirectory(lpBuffer, 256);
wsprintf(lpBuffer, "%s%s%s%s", lpBuffer, "\\Desktop\\", szAppName, ".lnk\0");
lpszPathLink = lpBuffer;
}
CoInitialize(NULL);
hres = CoCreateInstance(&CLSID_ShellLink, NULL,
CLSCTX_INPROC_SERVER, &IID_IShellLink, &psl);
if (SUCCEEDED(hres)) {
IPersistFile* ppf;
hres = psl->lpVtbl->SetPath(psl, lpszPathObj);
if (! SUCCEEDED (hres))
MessageBox(NULL, "SetPath storing failed", szAppName, MB_OK);
hres = psl->lpVtbl->SetIconLocation(psl, lpszPathObj, 0);
if (! SUCCEEDED (hres))
MessageBox(NULL, "SetIconLocation failed", szAppName, MB_OK);
hres = psl->lpVtbl->SetDescription(psl, lpszDesc);
if (! SUCCEEDED (hres))
MessageBox(NULL, "SetDescription failed", szAppName, MB_OK);
hres = psl->lpVtbl->QueryInterface(psl, &IID_IPersistFile,
&ppf);
if (! SUCCEEDED (hres))
MessageBox(NULL, "QueryInterface failed", szAppName, MB_OK);
if (SUCCEEDED(hres)) {
WORD wsz[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1,
wsz, MAX_PATH);
hres = ppf->lpVtbl->Save(ppf, wsz, TRUE);
if (! SUCCEEDED (hres))
MessageBox(NULL, "Save failed", szAppName, MB_OK);
ppf->lpVtbl->Release(ppf);
}
psl->lpVtbl->Release(psl);
}
CoUninitialize( );
return hres;
}
|
|
|
|
|
John T wrote:
I have a problem to use when I want to give a parameter
to the link object eg. I want to create a shortcut like
"C:\\MyPath\\AppName\\AppName.exe -Settings".
If you find out resolve please post....
I haven't tried it personally, but it looks like adding a call to SetArguments on the ShellLink object should work to add the "-Settings" argument.
psl->lpVtbl->SetArguments(psl, "-Settings");
Mike
|
|
|
|
|
Hi,
How can I create a shortcut to network connection, the broadband connection ?
Assume, use "rasphone.exe -a" to create a "broadband connection" in Network
Connections in WinXP.
Since network connection does not have file name, and it only has
CLSID.
simon
|
|
|
|
|
I do not know yet, but will try to figure it out.
Igor.
|
|
|
|
|
You can always use "rasphone -d connection" to dial the connection.
|
|
|
|
|
You should use IShellLink::SetIDList() method, providing a pointer to an ID List (list of shell object's item identifier).
Codeprject has a number of articles on how to obtain a pidl.
Good luck,
Igor.
|
|
|
|
|
Hi,
I tried using the pidl, but when I try to execute the shortcut I get "Cannot be found".
I get the same by running the Resolve(...) method on the IShellLink object.
|
|
|
|
|
I send a pidl that represents a network connection.
This is my code:
HRESULT CreateLink(LPCITEMIDLIST pidl, LPCSTR lpszPathLink)
{
HRESULT hres;
IShellLink* psl;
// Get a pointer to the IShellLink interface.
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->SetIDList(pidl);
// Query IShellLink for the IPersistFile interface for saving the
// shortcut in persistent storage.
hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf);
hres = psl->Resolve(NULL, SLR_UPDATE);
if (SUCCEEDED(hres))
{
WCHAR wsz[MAX_PATH];
// Ensure that the string is Unicode.
MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1, wsz, MAX_PATH);
// TODO: Check return value from MultiByteWideChar to ensure success.
// Save the link by calling IPersistFile::Save.
hres = ppf->Save(wsz, TRUE);
ppf->Release();
}
psl->Release();
}
return hres;
}
|
|
|
|
|
I never did it myself, but it looks like something is not right with a pidl. Please, make sure that you are getting the correct one.
Igor.
|
|
|
|
|