Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在不使用新控制台的情况下,使用CreateProcessWithLogonW()执行CMD.EXE_C++_C_Winapi - Fatal编程技术网

C++ 在不使用新控制台的情况下,使用CreateProcessWithLogonW()执行CMD.EXE

C++ 在不使用新控制台的情况下,使用CreateProcessWithLogonW()执行CMD.EXE,c++,c,winapi,C++,C,Winapi,我必须使用CreateProcessWithLogonW()运行cmd.exe,但是在我的程序上下文中,没有创建另一个控制台,但是MSDN说默认情况下设置了CREATE\u NEW\u console标志。如何取消设置此标志,使此API不会为我的子进程创建新窗口 下面的代码显示了如何在我的程序中使用此API。我不希望新程序在新的控制台中运行,但我找不到解决方案 BOOL status = FALSE; DWORD process_flags = 0 | arg_process_flags; DW

我必须使用
CreateProcessWithLogonW()
运行
cmd.exe
,但是在我的程序上下文中,没有创建另一个控制台,但是MSDN说默认情况下设置了
CREATE\u NEW\u console
标志。如何取消设置此标志,使此API不会为我的子进程创建新窗口

下面的代码显示了如何在我的程序中使用此API。我不希望新程序在新的控制台中运行,但我找不到解决方案

BOOL status = FALSE;
DWORD process_flags = 0 | arg_process_flags;
DWORD logon_flags = 0 | arg_logon_flags;
PTSTR duplicate_command_Line;
PPROCESS_INFORMATION ptr_process_info;
STARTUPINFO startup_info;
RtlZeroMemory(&startup_info, sizeof(STARTUPINFO));
startup_info.cb = sizeof(STARTUPINFO);

if (ptr_process_info = arg_process_infos ? arg_process_infos : (PPROCESS_INFORMATION)LocalAlloc(LPTR, sizeof(PROCESS_INFORMATION)))
{
    if (duplicate_command_Line = _wcsdup(arg_command_Line))
    {
        switch (arg_type)
        {
            case KULL_M_PROCESS_CREATE_NORMAL:
                status = CreateProcess(NULL, duplicate_command_Line, NULL, NULL, FALSE, process_flags, NULL, NULL, &startup_info, ptr_process_info);
                break;

            case KULL_M_PROCESS_CREATE_USER:
                status = CreateProcessAsUser(arg_user_token, NULL, duplicate_command_Line, NULL, NULL, FALSE, process_flags, NULL, NULL, &startup_info, ptr_process_info);
                break;

            case KULL_M_PROCESS_CREATE_LOGON:
                status = CreateProcessWithLogonW(arg_user, arg_domain, arg_password, logon_flags, NULL, duplicate_command_Line, process_flags, NULL, NULL, &startup_info, ptr_process_info);
                break;
        }

        if (status && (arg_auto_close_handle || !arg_process_infos))
        {
            CloseHandle(ptr_process_info->hThread);
            CloseHandle(ptr_process_info->hProcess);
        }

        if (!arg_process_infos)
            LocalFree(ptr_process_info);

        free(duplicate_command_Line);
    }
}

您的意思是不想创建新窗口吗?
尝试
startup\u info.dwFlags=STARTF\u USESHOWWINDOW;startup_info.wShowWindow=SW_HIDE则不会创建窗口。

这已经有一段时间了,但是传递
分离的\u进程应该可以工作

如果没有,您可以调用
CreateProcessWithLogonNW
传递您提供的win32二进制文件(可能是您自己提供的带有不同选项的文件),然后调用
CreateProcess
打开
cmd.exe
,而不传递
CREATE\u NEW\u控制台

除非你已经是管理员,否则在同一个控制台中创建是完全不可能的,如果你是管理员,最好不要使用这种神秘的技术。

你可以

这是我的测试程序(删除错误检查)

家长:

#include <windows.h>
#include <iostream>
#define BUFSIZE 4096 
void main()
{
    printf("in Parent \n");
    HANDLE R_In, R_Out, R_err, W_In, W_Out, W_err;
    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
    SECURITY_ATTRIBUTES saAttr;
    BOOL bSuccess;
    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
    saAttr.bInheritHandle = TRUE;
    saAttr.lpSecurityDescriptor = NULL;

    CreatePipe(&R_In, &W_In, &saAttr, 0);
    CreatePipe(&R_Out, &W_Out, &saAttr, 0);
    CreatePipe(&R_err, &W_err, &saAttr, 0);
    PROCESS_INFORMATION process_info;
    STARTUPINFO startup_info;
    RtlZeroMemory(&startup_info, sizeof(STARTUPINFO));
    startup_info.cb = sizeof(STARTUPINFO);
    startup_info.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    startup_info.wShowWindow = SW_HIDE;
    startup_info.hStdInput = R_In;
    startup_info.hStdOutput = W_Out;
    startup_info.hStdError = W_err;

    BOOL ret = CreateProcessWithLogonW(L"username",L"domain",L"password", 0,L"ChildProcess.exe",NULL, CREATE_NO_WINDOW,NULL,NULL,&startup_info,&process_info);
    CloseHandle(R_In);
    CloseHandle(W_Out);
    CloseHandle(W_err);
    CHAR chBuf[BUFSIZE];
    DWORD dwRead, dwWritten;
    bSuccess = ReadFile(hStdin, chBuf, BUFSIZE, &dwRead, NULL);
    bSuccess = WriteFile(W_In, chBuf, dwRead, &dwWritten, NULL);
    while (1)
    {
        bSuccess = ReadFile(R_Out, chBuf, BUFSIZE, &dwRead, NULL);
        if (bSuccess == 0 & GetLastError() == ERROR_BROKEN_PIPE) // child process exit.
            break;
        bSuccess = WriteFile(hStdout, chBuf, dwRead, &dwWritten, NULL);
    }
    WaitForSingleObject(process_info.hProcess, INFINITE);
    printf("Parent exit\n");
}
#包括
#包括
#定义BUFSIZE 4096
void main()
{
printf(“在父项中”);
处理R_In,R_Out,R_err,W_In,W_Out,W_err;
句柄hStdout=GetStdHandle(标准输出句柄);
句柄hStdin=GetStdHandle(标准输入句柄);
安全属性saAttr;
成功;
saAttr.nLength=sizeof(安全属性);
saAttr.bInheritHandle=TRUE;
saAttr.lpSecurityDescriptor=NULL;
CreatePipe(&R_-In,&W_-In,&saAttr,0);
CreatePipe(&R_Out,&W_Out,&saAttr,0);
CreatePipe(&R_err,&W_err,&saAttr,0);
过程信息过程信息;
STARTUPINFO启动信息;
RtlZeroMemory(&startup_info,sizeof(STARTUPINFO));
startup_info.cb=sizeof(STARTUPINFO);
startup_info.dwFlags=STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
startup_info.wShowWindow=SW_HIDE;
启动信息hStdInput=R\u In;
startup\u info.hStdOutput=W\u Out;
startup_info.hStdError=W_err;
BOOL ret=CreateProcessWithLogonW(L“用户名”、L“域”、L“密码”、0、L“ChildProcess.exe”、NULL、创建否窗口、NULL、NULL、启动信息和进程信息);
闭合手柄(R_In);
关闭手柄(W_Out);
关闭手柄(W_err);
CHAR chBuf[BUFSIZE];
德沃德·德雷德,德沃德·书面;
bSuccess=ReadFile(hStdin、chBuf、BUFSIZE和dwRead,NULL);
bSuccess=WriteFile(W_In,chBuf,dwRead,&dwwrited,NULL);
而(1)
{
bSuccess=ReadFile(R_Out,chBuf,BUFSIZE,&dwRead,NULL);
if(bSuccess==0&GetLastError()==ERROR\u breaked\u PIPE)//子进程退出。
打破
bSuccess=WriteFile(hStdout、chBuf、dwRead和dwwrited,NULL);
}
WaitForSingleObject(process_info.hpprocess,无限);
printf(“父出口”);
}
儿童:

#include <windows.h>
#include <iostream>
#define BUFSIZE 4096 
#pragma warning(disable : 4996)
void main()
{
    CHAR chBuf[BUFSIZE];
    scanf("%s", chBuf);
    printf("in Child %s\n", chBuf);
    printf("Child exit\n");
    return;
}
#包括
#包括
#定义BUFSIZE 4096
#杂注警告(禁用:4996)
void main()
{
CHAR chBuf[BUFSIZE];
scanf(“%s”,chBuf);
printf(“在子项%s\n中”,chBuf);
printf(“子出口”);
回来
}
结果:


在旁注中,您可以在错误的位置调用
LocalFree(ptr\u process\u info)
。如果
arg\u process\u infos
为null且
\u wcsdup()
返回null,则泄漏
ptr\u process\u info
LocalFree()
需要在
if(ptr\u process\u info…
块内调用,而不是在
if(duplicate\u command\u Line…
块内调用。当您通过
CreateProcessWithLogonW
启动进程时,它将在另一个登录会话中运行,即使您使用的用户名与当前运行的用户名相同。从另一端系统执行/使用与控制台应用程序相同的登录会话中的conhost.exe。因此,新进程无法使用您的控制台(conhost.exe)。因此,即使您没有设置
CREATE_NEW_CONSOLE
,系统也会像设置了一样运行。我希望新进程能够在父环境中执行,而不是创建另一个控制台。啊,对不起,我没有正确理解。@klighting-如果您使用CreateProcessWithLogonW-子进程将在新登录会话中执行。它不能在父环境中执行“传递分离的_进程应该工作”-否。-在这种情况下,我们得到了错误invaid参数。使用第二个变体,我们可以在根本不使用控制台的情况下运行进程。但不要使用与相同的控制台parent@RbMm:OP想从问题中得到与家长相同的控制台,这一点并不十分明显,但如果他想得到,他需要重新考虑他想做什么。那么,当控制台程序提示输入密码或要求逐字符输入时,会发生什么情况?