【问题标题】:Winapi ShellExecuteEx does not opening the fileWinapi ShellExecuteEx 不打开文件
【发布时间】:2017-10-26 15:08:22
【问题描述】:

我是 WinApi 的新手,我想在我的 D: 驱动器中打开文本文件,但这段代码不起作用。当我运行该应用程序时,出现错误:“Windows 找不到文件 'lobalizarion\Sorting\sortdefaults.nls'”。在控制台中我有消息:“找不到文件”,但我已经打开了我的驱动器。

在我的代码中,我使用来自 How to get hWnd of window opened by ShellExecuteEx.. hProcess? 的 sn-p 来获取已创建 HINSTANCE 的 HWND。

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

std::wstring stringToLPCTSTR(const std::string& s)
{
    int len;
    int slength = (int)s.length() + 1;
    len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
    wchar_t* buf = new wchar_t[len];
    MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
    std::wstring r(buf);
    delete[] buf;
    return r;
}

struct ProcessWindowsInfo
{
    DWORD ProcessID;
    std::vector<HWND> Windows;

    ProcessWindowsInfo(DWORD const AProcessID) : ProcessID(AProcessID) {}
};

BOOL __stdcall EnumProcessWindowsProc(HWND hwnd, LPARAM lParam)
{
    ProcessWindowsInfo *Info = reinterpret_cast<ProcessWindowsInfo*>(lParam);
    DWORD WindowProcessID;

    GetWindowThreadProcessId(hwnd, &WindowProcessID);

    if (WindowProcessID == Info->ProcessID)
        Info->Windows.push_back(hwnd);

    return true;
}

int main()
{
    SHELLEXECUTEINFOW sei;

    sei.cbSize = sizeof(SHELLEXECUTEINFO);
    sei.fMask = SEE_MASK_NOCLOSEPROCESS;
    sei.hwnd = NULL;
    sei.lpVerb = stringToLPCTSTR("open").c_str();
    sei.lpFile = stringToLPCTSTR("D:\\file.txt").c_str();
    sei.lpParameters = NULL;
    sei.lpDirectory = stringToLPCTSTR("D:\\").c_str();;
    sei.nShow = SW_SHOWNORMAL;
    sei.hInstApp = NULL;

    auto retval = ShellExecuteEx(&sei);

    if (retval == 0) //check errors
    {
        if ((int)sei.hInstApp == SE_ERR_FNF) 
            std::cerr << "File was not found\n";
        else 
            std::cerr << "Unexpected error occured\n";
    }
    else
    {
        WaitForInputIdle(sei.hProcess, INFINITE);

        ProcessWindowsInfo info(GetProcessId(sei.hProcess));

        EnumWindows((WNDENUMPROC)EnumProcessWindowsProc, reinterpret_cast<LPARAM>(&info));
    }

    std::cin.get();

    return 0;
}

【问题讨论】:

  • 来自ShellExecuteEx“因为 ShellExecuteEx 可以将执行委托给使用组件对象模型 (COM) 激活的 Shell 扩展 [...],因此应在调用 ShellExecuteEx 之前初始化 COM。 "

标签: c++ winapi


【解决方案1】:

stringToLPCTSTR() 返回的std::wstring 是临时变量,用于分配结构SHELLEXECUTEINFOWLPCTSTR 成员。这意味着对c_str() 的各个调用返回的指针在您调用ShellExecuteEx() 时可能不再有效。您需要为此找到不同的解决方案,例如通过使用std::wstring 的局部变量,但只要你只使用字符串文字,你就可以这样做

sei.lpVerb = L"open";
sei.lpFile = L"D:\\file.txt";
sei.lpDirectory = L"D:\\";

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-26
    • 2023-04-06
    • 2017-05-21
    • 2019-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多