我正在编写32位服务应用程序,我希望能够为登录用户启动开始菜单项。我还是设法通过模拟用户使用启动CreateProcessAsUser使用命令行选择的.lnk文件来完成这项任务:%windir%\system32\cmd /c " start /b /i "" "<path-to-lnk-file>" "
。它适用于除了一堆系统的快捷键几乎每一个快捷键,配件文件夹(如粘Notes.lnk,剪断Tool.lnk)。在此次推出的截图工具的我与这个错误CMD接收到消息框:某些系统默认的.lnk文件在模拟用户下启动的问题
Windows无法找到“C:\ ProgramData \微软\的Windows \开始菜单\程序\附件\剪断Tool.lnk ”。确保你输入了正确的名字,然后再试一次。
但.lnk文件存在于这个目录中!
摘要:
- 服务是32位
- 的Windows 8专业版64位
- 启动快捷方式由用户模拟和CreateProcessAsUser使用命令行
%windir%\system32\cmd /c " start /b /i "" "<path-to-lnk-file>" "
- 方法适用于几乎所有的快捷方式在开始菜单除了一些在开始/附件文件夹中(不是所有的人,如Paint.lnk打开罚款)
示例代码:
int launchAppForCurrentLoggedUser() { HANDLE userToken = WTSApiHelper::currentLoggedUserToken(); if (userToken == INVALID_HANDLE_VALUE) { return -1; } //Duplicating token with access TOKEN_DUPLICATE | TOKEN_ALL_ACCESS, //impersonation level SecurityImpersonation and token type TokenPrimary. //Also closing original userToken HANDLE dup = WTSApiHelper::duplicateToken(userToken); if (dup == INVALID_HANDLE_VALUE) { return -1; } int res = -1; uint8 *env = NULL; BOOL succeeded = CreateEnvironmentBlock((LPVOID *)&env, dup, FALSE); if (!succeeded) { Log("failed to get environment variables for user (error 0x%x).", GetLastError()); } PROCESS_INFORMATION pi; memset(&pi, 0, sizeof(PROCESS_INFORMATION)); STARTUPINFOW si; memset(&si, 0, sizeof(STARTUPINFOW)); si.cb = sizeof(STARTUPINFOW); si.lpDesktop = L"winsta0\\Default"; WCHAR params[] = L"/c \" start /b /i \"\" \"C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Accessories\\Snipping Tool.lnk\" \" "; WCHAR cmd[] = L"C:\\Windows\\system32\\cmd.exe"; DWORD flags = env ? CREATE_UNICODE_ENVIRONMENT : 0; succeeded = CreateProcessAsUserW(dup, cmd, params, NULL, NULL, FALSE, flags | CREATE_NO_WINDOW, env, NULL, &si, &pi); if (!succeeded) { Log("cannot launch process for user with error 0x%x.", GetLastError()); } else { nres = 0; } DestroyEnvironmentBlock(env); CloseHandle(dup); return nres; }
我怎么会错过吗?
[CreateProcessAsUser](https://msdn.microsoft.com/en-us/library/windows/desktop/ms682429.aspx):*“lpCommandLine:此函数的Unicode版本,** CreateProcessAsUserW **,可以修改该字符串的内容,因此该参数不能是指向只读内存的指针(如const变量或**文字字符串**),如果该参数是一个常量字符串,则该函数可能会导致访问违反。“* – IInspectable
@IInspectable,我知道,指定的代码有点简化。 –
简化和引入错误是有区别的。简化版本将使用'WCHAR params [] = L“/ c [...]”;'。同样简单,但正确。 – IInspectable