C++ C# windows封装adb命令源码
更多细节:一、共享内存管 道(Pipe)实际是用于进程间通信的一段共享内存。把管道想想成共享内存比较好理解。示例:把DOS进程上的内容通过管道技术输出到一个MFC应用程序的CEdit控件中。//创建pipe内核对象,设置好hRead,hWrite.管道2:cmd进程输入重定向到hReadChild从这里读,把MFC命令dir写到hWriteParent里,cmd进程会执行这个命令。管道1:cmd进
·
方法一:管道技术


最终需要的函数
//cmd命令后面一定要加\n
int pipe(char *cmd, char *out)
{
logger.INFO_F(cmd);
HANDLE hParentRead, hChildWrite; //创建2个句柄 父(当前应用)读子(cmd)写
//1.创建一个安全属性描述符,设置句柄可继承
SECURITY_ATTRIBUTES sa = { 0 }; //安全属性描述符
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE; //设置句柄可继承
//2.创建两个管道.父读->子写 子读->父写的
BOOL bRet = CreatePipe(&hParentRead, &hChildWrite, &sa, 0); //创建管道1. 父进程读 -> 子进程写入
if (!bRet) { logger.ERROR_F("CreatePipe error:"+to_string(GetLastError())); return GetLastError(); }
//bRet = CreatePipe(&hChildRead, &hParentWrite, &sa, 0);//创建管道2. 子进程读->父进程写.
//if (!bRet) { printf("error:%d", GetLastError()); return bRet; }
PROCESS_INFORMATION pi = { 0 }; //进程信息结构体
STARTUPINFO si = { 0 }; //启动信息结构体
si.cb = sizeof(si);
//3.重定向输出, 将子进程的读 以及子进程的写重定向.
//si.hStdInput = hChildRead; //将子进程读取重定向到stdinput中
si.hStdOutput = hChildWrite; //将子进程写重定向到 stdout中.
si.hStdError = hChildWrite; //将子进程写重定向到 stdout中.
si.dwFlags = STARTF_USESTDHANDLES; //设置窗口隐藏启动
//4.创建子进程
bRet = CreateProcess(NULL, cmd, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi);//创建cmd进程.默认寻找cmd进程.
if (!bRet) { logger.ERROR_F("CreateProcess error:"+to_string( GetLastError())); return GetLastError(); }
//Sleep(1000);
//DWORD dwFileSize = GetFileSize(hParentRead, NULL); //可以把头长度去掉
//char szBuffer[] = "ver\n";
//5.写入命令数据给子进程.
//DWORD dwWrite = 0; //实际写入字节数
//bRet = WriteFile(hParentWrite, szBuffer, strlen(szBuffer), &dwWrite, 0);//使用writeFile操作管道,给cmd发送数据命令.
//if (!bRet) { printf("error:%d", GetLastError()); return bRet; }
CloseHandle(pi.hThread); //关闭句柄
CloseHandle(hChildWrite);//关闭write ReadFile才不会阻塞
DWORD dwExitCode;
do {
GetExitCodeProcess(pi.hProcess, &dwExitCode);
//Sleep(1000);
//printf("GetExitCodeProcess:%d\n", dwExitCode);
char psBuffer[128] = {0};
DWORD outLength=0;
if (NULL == ReadFile(hParentRead, psBuffer, sizeof(psBuffer) - 1, &outLength, NULL)) { logger.INFO_F(FUN_LINE"NULL "+to_string(GetLastError())); } //读cmd显示内容
if (outLength > 0) {
psBuffer[outLength] = 0;
printf(psBuffer);
if (strlen(out) > MAX_LENGTH / 2){ memset(out, 0, sizeof(MAX_LENGTH)); }
strcat(out, psBuffer);
}
} while (dwExitCode == STILL_ACTIVE);//等待子进程退出
//6.读出响应
//DWORD outLength;
//if (NULL == ReadFile(hParentRead, out, MAX_LENGTH - 1, &outLength, NULL)) { /*break;*/ } //读cmd显示内容
//if (outLength > 0) { out[outLength] = 0; logger.INFO_F(out); }
//7.退出子进程 退出cmd
//char *exit="exit\n";
//WriteFile(hParentWrite, exit, strlen(exit), NULL, 0);//使用writeFile操作管道,给cmd发送数据命令.
//if (!bRet) { printf("error:%d", GetLastError()); return bRet; }
TerminateProcess(pi.hProcess, 0); //退出子进程
//CloseHandle(hParentWrite); //关闭写入句柄
CloseHandle(hParentRead);
CloseHandle(pi.hProcess);
//CloseHandle(hChildRead);
//CloseHandle(pi.hProcess);
//printf("end\n");
return dwExitCode;
}
示例
CString filePath = filePathArray.GetAt(i);
CString out;
int ret=pipe(CString("adb install -r \"" + filePath + "\"").GetBuffer(),out.GetBuffer(MAX_LENGTH));
if (g_bResult=(ret==0 &&out.Find("") != -1)) { pWnd->ShowInfo("Install App" + CString(to_string(i + 1).c_str()) +"("+ filePath + ") Success"); }
else { out.ReleaseBuffer(); pWnd->ShowInfo(out + "Failed to install app("+ filePath + "), possible reasons:\r\n1. Application not signed\r\n2. Application as test package\r\n3. Insufficient space\r\n4. Insufficient authority"); goto END; }
#include <stdio.h>
#include <Windows.h>
//cmd命令后面一定要加\n
DWORD pipe2(char* szBuffer,char *out, DWORD outLength)
{
HANDLE hParentRead, hChildWrite; //创建2个句柄 父(当前应用)读子(cmd)写
//1.创建一个安全属性描述符,设置句柄可继承
SECURITY_ATTRIBUTES sa = { 0 }; //安全属性描述符
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE; //设置句柄可继承
//2.创建两个管道.父读->子写 子读->父写的
BOOL bRet = CreatePipe(&hParentRead, &hChildWrite, &sa, 0); //创建管道1. 父进程读 -> 子进程写入
if (!bRet) { printf("CreatePipe error:%d", GetLastError()); return GetLastError(); }
//bRet = CreatePipe(&hChildRead, &hParentWrite, &sa, 0);//创建管道2. 子进程读->父进程写.
//if (!bRet) { printf("error:%d", GetLastError()); return bRet; }
PROCESS_INFORMATION pi = { 0 }; //进程信息结构体
STARTUPINFO si = { 0 }; //启动信息结构体
si.cb = sizeof(si);
//3.重定向输出, 将子进程的读 以及子进程的写重定向.
//si.hStdInput = hChildRead; //将子进程读取重定向到stdinput中
si.hStdOutput = hChildWrite; //将子进程写重定向到 stdout中.
si.hStdError = hChildWrite; //将子进程写重定向到 stdout中.
si.dwFlags = STARTF_USESTDHANDLES; //设置窗口隐藏启动
//4.创建子进程
bRet = CreateProcess(NULL, szBuffer, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi);//创建cmd进程.默认寻找cmd进程.
if (!bRet) { printf("CreateProcess error:%d", GetLastError()); return GetLastError(); }
//Sleep(1000);
//DWORD dwFileSize = GetFileSize(hParentRead, NULL); //可以把头长度去掉
//char szBuffer[] = "ver\n";
//5.写入命令数据给子进程.
//DWORD dwWrite = 0; //实际写入字节数
//bRet = WriteFile(hParentWrite, szBuffer, strlen(szBuffer), &dwWrite, 0);//使用writeFile操作管道,给cmd发送数据命令.
//if (!bRet) { printf("error:%d", GetLastError()); return bRet; }
CloseHandle(pi.hThread); //关闭句柄
CloseHandle(hChildWrite);//关闭write ReadFile才不会阻塞
DWORD dwExitCode;
do {
GetExitCodeProcess(pi.hProcess, &dwExitCode);
//printf("GetExitCodeProcess:%d\n", dwExitCode);
} while (dwExitCode==STILL_ACTIVE);//等待子进程退出
//6.读出响应
//char pReadBuf[5000] = { 0 };
//DWORD dataLength = sizeof(pReadBuf);
//DWORD dwBytesRead;
if (NULL == ReadFile(hParentRead, out, outLength-1, &outLength, NULL)) { /*break;*/ } //读cmd显示内容
if (outLength > 0) { printf(out); }
//7.退出子进程 退出cmd
//char *exit="exit\n";
//WriteFile(hParentWrite, exit, strlen(exit), NULL, 0);//使用writeFile操作管道,给cmd发送数据命令.
//if (!bRet) { printf("error:%d", GetLastError()); return bRet; }
TerminateProcess(pi.hProcess, 0); //退出子进程
//CloseHandle(hParentWrite); //关闭写入句柄
CloseHandle(hParentRead);
CloseHandle(pi.hProcess);
//CloseHandle(hChildRead);
//CloseHandle(pi.hProcess);
//printf("end\n");
return dwExitCode;
}
int main()
{
char out[5000] = { 0 };
pipe2("cmd.exe /c \"adb devices\"", out,sizeof(out));
//pipe_system("ver\n");
//pipe_system("ipconfig\n");
printf("end\n");
getchar();
return 0;
}
方法二:_POPEN等简单
但是下面没法获取console提示的错误
// crt_popen.c
/* This program uses _popen and _pclose to receive a
* stream of text from a system process.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main(void)
{
char psBuffer[128];
FILE *pPipe;
/* Run DIR so that it writes its output to a pipe. Open this
* pipe with read text attribute so that we can read it
* like a text file.
*/
if ((pPipe = _popen("adb install -r \"D:\\test2\\ErrorTest.apk\"", "rt")) == NULL)
exit(1);
/* Read pipe until end of file, or an error occurs. */
while (fgets(psBuffer, 128, pPipe))
{
printf(psBuffer);
}
/* Close pipe and print return value of pPipe. */
if (feof(pPipe))
{
printf("\nProcess returned %d\n", _pclose(pPipe));
}
else
{
printf("Error: Failed to read the pipe to the end.\n");
}
getchar();
}
更多推荐
https://blog.csdn.net/chenhao0568/article/details/122689444?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167592604816782429711993%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=167592604816782429711993&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-10-122689444-null-null.blog_rank_default&utm_term=adb&spm=1018.2226.3001.4450

所有评论(0)