简体   繁体   English

C ++ ShellExecute专门不打开LNK文件

[英]C++ ShellExecute specifically not opening LNK files

-Windows 7 64-bit -Windows 7 64位
-Visual Studio 2013 (v120) -Visual Studio 2013(v120)
-Unicode Enabled -启用Unicode
-Target Build- Debug 32-bit -目标构建-调试32位

I would like to build a launcher (for personal use) however I can't get ShellExecute to work with all file types or paths, specifically shortcuts (LNK). 我想构建一个启动器(供个人使用),但是我无法让ShellExecute处理所有文件类型或路径,特别是快捷方式(LNK)。 I've researched and tried the following in many combinations... 我已经研究并尝试了多种组合的以下方法...
-I'm using escape sequences -我正在使用转义序列
-I'm adding the file extension (and tried without) -我正在添加文件扩展名(并且尝试不使用)
-I've included Windows.h -我包含了Windows.h
-Printed directory FindFirstFile / FindNextFile to explicitly ensure the path has no typos -打印目录FindFirstFile / FindNextFile,以明确确保路径没有错别字
-Tried using both a literal and variable as file path argument -尝试使用文字和变量作为文件路径参数
-Tried running VS with admin privileges -尝试以管理员权限运行VS
-Tried ShellExecute, ShellExecuteA, ShellExecuteEx, and System (with appropriate character sets) -尝试了ShellExecute,ShellExecuteA,ShellExecuteEx和System(带有适当的字符集)
-Tried NULL, "runas" and, "open" for the verb -动词尝试NULL,“ runas”和“ open”
-Launches fine from Command Line or explorer using same path -从命令行或资源管理器使用相同的路径启动
-Tried using %USERPROFILE% macro instead of user name (returns 2) -尝试使用%USERPROFILE%宏代替用户名(返回2)
-Seems to work with EXE and URLs -似乎可以使用EXE和URL
-Does not seem to work with any LNK across any path including C:\\ directly -似乎无法直接在任何路径上使用任何LNK,包括C:\\

Suspected issue 疑似问题
-32bit/64bit discrepancy -32bit / 64bit差异
-UAC / Privelages -UAC /启示
-Character set -字符集
-File extension -文件扩展名
-Anti virus interference (though AV isn't alerting me of any issues) and I've tested while silencing my AV -防病毒干扰(尽管AV不会向我发出任何警报),并且我在沉默AV的同时进行了测试

Here is one of the simplest programs I've tried... 这是我尝试过的最简单的程序之一...

#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <atlstr.h>

int _tmain(int argc, _TCHAR* argv[])
{
    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);

    // Variables below for testing as path argument
    // Paths that end with LNK are the only ones that I can't get to launch
    CStringW link("C:\\Users\\Home\\Documents\\Art\\blender.lnk"); // Doesn't work
    CStringW target("C:\\Program Files\\Blender Foundation\\Blender\\blender.exe"); // Launches software as expected
    CStringW url("https://stackoverflow.com"); // Launches browser with URL as expected

    int error = reinterpret_cast<int>(ShellExecute(
        NULL, 
        NULL, 
        L"C:\\Users\\Home\\Documents\\Art\\blender.lnk", // Using literal with LNK extension also does not work
        NULL, 
        NULL, 
        SW_SHOWDEFAULT
        ));


    // EVEN SYSTEM CAN NOT FIND THE PATH!!!
    // system("C:\\Users\\Home\\Documents\\Art\\blender.lnk");

    std::cout << error << std::endl; // Returns 3 "The specified path was not found.".

    // Free COM
    CoUninitialize();

    return 0;
}

First, check that your .lnk file is in the path. 首先,检查您的.lnk文件是否在路径中。

Then (and the most probable cause of your problem) check that your .lnk filename is created correctly. 然后(也是造成问题的最可能原因)检查是否正确创建了.lnk文件名。 To make sure it is not like "blender.lnk.lnk"(I can reproduce your issue if I have set as this). 为了确保它不像“ blender.lnk.lnk”(如果设置为这个,我可以重现您的问题)。

You can also try to parse the path of the link file manually by yourself. 您也可以尝试自己手动分析链接文件的路径。 Here is the sample: 这是示例:

void ShortcutToRealpath(LPWSTR pszString, LPSTR pdzString)
{
    IShellLink   *pShellLink;
    HRESULT hRes;

    ::CoInitialize(NULL);
    hRes = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&pShellLink);
    if (SUCCEEDED(hRes))
    {
        IPersistFile   *ppf;
        hRes = pShellLink->QueryInterface(IID_IPersistFile, (void **)&ppf);
        if (SUCCEEDED(hRes))
        {
            hRes = ppf->Load(pszString, TRUE);
            if (SUCCEEDED(hRes))
            {
                pShellLink->GetPath(pdzString, MAX_PATH, NULL, 0);
            }
            ppf->Release();
        }
        pShellLink->Release();
    }
    ::CoUninitialize();
}

When I build as x86 Platform, the path will be parsed like: 当我将其构建为x86平台时,路径将被解析为: 在此处输入图片说明 That's the reason your program can't find the path. 这就是您的程序找不到路径的原因。

And if I select x64: 如果我选择x64: 在此处输入图片说明

Put your target file to the corresponding file. 将您的目标文件放入相应的文件。

EDIT: 编辑:

After I test it with the MS tool Procmom.exe , I have found something others, if run as 32-bit, it will show : 在使用MS工具Procmom.exe测试它之后,我发现了其他东西,如果以32位运行,它将显示: 在此处输入图片说明

The key value is C:\\Program Files (x86) and if we run it as 64-bit, the key is reference to "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ProgramFilesDir" the key value is C:\\Program Files . 密钥值为C:\\Program Files (x86) ,如果我们以64位运行,则密钥引用为“ HKLM \\ SOFTWARE \\ Microsoft \\ Windows \\ CurrentVersion \\ ProgramFilesDir”,密钥值为C:\\Program Files After I check the registry: 在检查注册表后: 在此处输入图片说明 在此处输入图片说明 It seems that C:\\Program Files is not visible by default to the 32-bit registry(I am not sure about the specific reason). 似乎C:\\Program Files默认情况下对32位注册表不可见(我不确定具体原因)。 If you change the key ProgramFilesDir to C:\\Program Files in 32-bit registry, the issue will be fixed. 如果您在32位注册表中将密钥ProgramFilesDir更改为C:\\Program Files ,此问题将得到解决。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM