gpt4 book ai didi

C++ 运行 SHELLEXECUTEINFO 并附加功能名称

转载 作者:行者123 更新时间:2023-11-27 23:53:36 25 4
gpt4 key购买 nike

我不懂 C++,我在尝试将字符串名称附加到 SHELLEXECUTEINFO 的 lpFile 时遇到问题。我从 Installshield 得到一个分号分隔的字符串,然后将它拆分并循环遍历它。然后,我试图附加从字符串中拆分出来的每个“功能”,并通过 shell 执行将其发送到 dism.exe。

它在 swprintf_s(buf, _T("Dism.exe/Online/Enable-Feature/FeatureName:%s"), sizeof(buf), wc); 处失败然后它至少会触发 dll 并抛出 dism.exe 错误,所以我知道调用工作正常。

template<typename Out>
void split(const std::string &s, char delim, Out result) {
std::stringstream ss;
ss.str(s);
std::string item;
while (std::getline(ss, item, delim)) {
*(result++) = item;
}
}


HRESULT __stdcall SplitString(IDispatch *pAction) {
// Create a pointer to the IsSuiteExtension COM interface
CComQIPtr<ISuiteExtension2> spSuiteExtension2 = pAction;

// Turn on notifications for both the progress bar(epfProgressValid) and the ui message(epfMessageValid).
EnumProgressFlags pf = EnumProgressFlags(EnumProgressFlags::epfMessageValid | EnumProgressFlags::epfProgressValid);

BSTR bstrFeatureList(_T("ENABLE_FEATURES")); // Property name to get. This should be a semi-colon delimeted list of features to enable for windows.
BSTR FeatureList = ::SysAllocStringLen(NULL, 2 * 38); // Where to store the property value
HRESULT hRet = spSuiteExtension2->get_Property(bstrFeatureList, &FeatureList); // Get the property value and store it in the 'FeatureList' variable

CW2A pszConverted(FeatureList);

using namespace std;
string strConverted(pszConverted);
vector<string> tokens;
split(strConverted, ';', back_inserter(tokens));
int numTokens = tokens.size();
for (int i = 0; i < numTokens; i++)
{
string t = tokens.at(i);
TCHAR buf[1024];

SHELLEXECUTEINFO ShExecInfo = { 0 };
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = NULL;
// Convert ANSI to Unicode
ATL::CA2W wc(tokens.at(i).c_str());
swprintf_s(buf, _T("Dism.exe /Online /Enable-Feature /FeatureName:%s"), sizeof(buf), wc); // HAVING ISSUES HERE. NEED TO APPEND tokens.at(i) AT %S
ShExecInfo.lpFile = buf;
ShExecInfo.lpParameters = _T("");
ShExecInfo.lpDirectory = _T("C:\\Windows\\SysNative");
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
WaitForSingleObject(ShExecInfo.hProcess, INFINITE);

}

//MessageBoxA(NULL, strConverted.c_str(), "testx", MB_OK);

return ERROR_SUCCESS;
}

最佳答案

由于您的代码使用了 TCHAR字符串,你应该使用 _stprintf_s()而不是 swprintf_s() .正如 Adrian McCarthy 所说,您以错误的顺序传递了它的参数,因此您的代码甚至不应该从一开始就编译。

但更重要的是,无需涉及ANSI或TCHAR根本。你有 Unicode 输入,STL 和 ShellExecuteEx()两者都支持 Unicode,因此只需将所有内容都保留为 Unicode。

您还泄露了 BSTR你分配给 FeatureList ,以及过程HANDLEShellExecuteEx()返回。

尝试更像这样的东西:

template <typename Out>
void split(const std::wstring &s, wchar_t delim, Out result) {
std::wistringstream iss(s);
std::wstring item;
while (std::getline(iss, item, delim)) {
*(result++) = item;
}
}

HRESULT __stdcall SplitString(IDispatch *pAction) {
// Create a pointer to the IsSuiteExtension COM interface
CComQIPtr<ISuiteExtension2> spSuiteExtension2 = pAction;

// Turn on notifications for both the progress bar(epfProgressValid) and the ui message(epfMessageValid).
EnumProgressFlags pf = EnumProgressFlags(EnumProgressFlags::epfMessageValid | EnumProgressFlags::epfProgressValid);

CComBSTR FeatureList;
HRESULT hRet = spSuiteExtension2->get_Property(CComBSTR(L"ENABLE_FEATURES"), &FeatureList); // Get the property value and store it in the 'FeatureList' variable

std::vector<std::wstring> tokens;
split(static_cast<BSTR>(FeatureList), L';', std::back_inserter(tokens));

int numTokens = tokens.size();
for (int i = 0; i < numTokens; i++)
{
std::wstring params = L"/Online /Enable-Feature /FeatureName:" + tokens.at(i);

SHELLEXECUTEINFOW ShExecInfo = { 0 };
ShExecInfo.cbSize = sizeof(ShExecInfo);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.lpFile = L"Dism.exe";
ShExecInfo.lpParameters = params.c_str();
ShExecInfo.lpDirectory = L"C:\\Windows\\SysNative";
ShExecInfo.nShow = SW_SHOW;

if (ShellExecuteExW(&ShExecInfo))
{
WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
CloseHandle(ShExecInfo.hProcess);
}
}

//MessageBoxW(NULL, FeatureList, L"testx", MB_OK);

return ERROR_SUCCESS;
}

也就是说,启动 EXE 时,您应该使用 CreateProcess()直接代替 ShellExecuteEx() :

for (int i = 0; i < numTokens; i++)
{
std::wstring cmd = L"Dism.exe /Online /Enable-Feature /FeatureName:" + tokens.at(i);

STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};

si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOW;

if (CreateProcessW(NULL, &cmd[0], NULL, NULL, FALSE, 0, NULL, L"C:\\Windows\\SysNative", &si, &pi))
{
CloseHandle(pi.hThread);
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
}
}

关于C++ 运行 SHELLEXECUTEINFO 并附加功能名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44316457/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com