|
How to obtain a correct path to an executed file for lnk-file of MSOffice 2002 (for example Microsoft Word.lnk in main menu or on Desktop).
I try it to make using IShellLink::GetPath.
I get a path like C:\WINDOWS\Installer\{91110419-6000-11D3-8CFE-0050048383C9}\wordicon.exe.
If to see this file in a binary mode, the file contains this information and the shortcut works correctly.
|
|
|
|
|
Did you use ResolveShortcut() function from the article?
|
|
|
|
|
Yes, I used this function. The functions offered by you worked correctly for standard shortcuts.
But this function is not universal. In addition I use interface IShellLinkDataList for getting the extra information. Using IShellLinkDataList:GetFlag I obtain a flag with enabled bit SLDF_HAS_DARWINID (The link is a special Windows ® Installer link.) and disabled bit SLDF_HAS_LINK_INFO.
How to get information from the "special Windows ® Installer link"?
(Such shortcuts create many programs and including MSOffice)
|
|
|
|
|
Interesting...
Can you tell me what kind of shortcuts you are trying to resolve, i.e. MS Word document shortcut or MS Word exe shortcut?
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).
Igor.
|
|
|
|
|
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.
|
|
|
|
|