C++實現重定向命令以及管道命令
阿新 • • 發佈:2019-02-09
// >命令 char* Get_Char(char **command,int count) { int len = Get_Count(command[count - 1]); char *wth = new char[len + 1]; for (int i = 0; i < len; i++) { wth[i] = command[count - 1][i]; } wth[len] = '\0'; return wth; } DWORD Get_Actuall(char *p) { //獲得緩衝區資料實際的大小 int i = 0; while (p[i] != '\0') { i++; } return i; } wchar_t *char2LPCTSTR(char **command, int count) { int len = Get_Count(command[count - 1]); wchar_t *wth = new wchar_t[len + 1]; for (int i = 0; i < len; i++) { wth[i] = command[count - 1][i]; } wth[len] = '\0'; return wth; } wchar_t *char2LPCTSTR(char *p) { //將char *轉換為wchar_t int len = Get_Count(p); wchar_t *wth = new wchar_t[len + 1]; for (int i = 0; i < len; i++) { wth[i] = p[i]; } wth[len] = '\0'; return wth; } TCHAR *char2TCHAR(char **command, int count) { int len = Get_Count(command[count - 1]); TCHAR *wth = new TCHAR[len + 1]; for (int i = 0; i < len; i++) { wth[i] = command[count - 1][i]; } wth[len] = '\0'; return wth; } // > void Redirection_1(char **&command,int count) { wchar_t *path = char2LPCTSTR(command,count); LPCTSTR outputFile = path; SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, TRUE }; HANDLE hFile = CreateFile( outputFile, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { //int err = GetLastError(); return; } STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION pi = { 0 }; si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; si.wShowWindow = SW_HIDE; //不顯示建立的程序的視窗 si.hStdOutput = hFile;//重定向輸出控制代碼為之前建立的檔案控制代碼 TCHAR *cmdline = char2TCHAR(command,1); //SetFilePointer(hFile, 0, NULL, FILE_END); if (CreateProcess(NULL, cmdline, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi)) { //等待開啟的程序結束並關閉相關控制代碼 WaitForSingleObject(pi.hProcess, INFINITE); ::CloseHandle(pi.hThread); ::CloseHandle(pi.hProcess); } else { int err = GetLastError(); } //關閉檔案控制代碼 CloseHandle(hFile); } // >>命令 void Redirection_2(char **&command, int count) { wchar_t *path = char2LPCTSTR(command, count); LPCTSTR outputFile = path; SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, TRUE }; HANDLE hFile = CreateFile( outputFile, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, OPEN_ALWAYS /*| TRUNCATE_EXISTING*/, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { //int err = GetLastError(); return; } STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION pi = { 0 }; si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; si.wShowWindow = SW_HIDE; //不顯示建立的程序的視窗 si.hStdOutput = hFile;//重定向輸出控制代碼為之前建立的檔案控制代碼 TCHAR *cmdline = char2TCHAR(command, 1); SetFilePointer(hFile, 0, NULL, FILE_END); //定位到檔案尾部 if (CreateProcess(NULL, cmdline, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi)) { //等待開啟的程序結束並關閉相關控制代碼 WaitForSingleObject(pi.hProcess, INFINITE); ::CloseHandle(pi.hThread); ::CloseHandle(pi.hProcess); } else { int err = GetLastError(); } //關閉檔案控制代碼 CloseHandle(hFile); } // <命令 void Redirection_3(char **&command, int count) { wchar_t *path = char2LPCTSTR(command, count); LPCTSTR inputFile = path; SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, TRUE }; HANDLE hFile = CreateFile( inputFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, OPEN_ALWAYS /*| TRUNCATE_EXISTING*/, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { //int err = GetLastError(); return; } //以下是為了驗證讀取的正確性 char *p = "temp.txt"; wchar_t *path1 = char2LPCTSTR(p); LPCTSTR outputFile = path1; HANDLE hOutput = CreateFile( outputFile, GENERIC_WRITE, 0, &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hOutput == INVALID_HANDLE_VALUE) { return; } //以上是為了驗證讀取的正確性 STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION pi = { 0 }; si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;; si.wShowWindow = SW_HIDE; //不顯示建立的程序的視窗 si.hStdInput = hFile;//重定向輸入控制代碼為之前建立的檔案控制代碼 si.hStdOutput = hOutput; //重定向輸出控制代碼為之前建立的檔案控制代碼 TCHAR *cmdline = char2TCHAR(command, 1); if (CreateProcess(NULL, cmdline, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi)) { //等待開啟的程序結束並關閉相關控制代碼 WaitForSingleObject(pi.hProcess, INFINITE); ::CloseHandle(pi.hThread); ::CloseHandle(pi.hProcess); } else { int err = GetLastError(); } //關閉檔案控制代碼 CloseHandle(hFile); CloseHandle(hOutput); } // <<命令 void Redirection_4(char **&command, int count) { HANDLE hRead = NULL; HANDLE hWrite = NULL; SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, TRUE }; // 新建立的程序繼承管道讀寫控制代碼 if (FALSE == CreatePipe(&hRead, &hWrite, &sa, 0)) { return; } if (NULL == hRead || NULL == hWrite) { return; } char *buf = Get_Char(command,count); DWORD dwWrite; WriteFile(hWrite, buf, Get_Actuall(buf), &dwWrite, NULL); //將資料寫入管道的輸入端 CloseHandle(hWrite); //建立程序,從管道輸出端讀取資料 //以下是為了驗證讀取的正確性 char *p = "temp.txt"; wchar_t *path1 = char2LPCTSTR(p); LPCTSTR outputFile = path1; HANDLE hOutput = CreateFile( outputFile, GENERIC_WRITE, 0, &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hOutput == INVALID_HANDLE_VALUE) { return; } //以下是為了驗證讀取的正確性 STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION pi = { 0 }; si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;; si.wShowWindow = SW_HIDE; //不顯示建立的程序的視窗 si.hStdInput = hRead;//重定向輸入控制代碼為之前建立的管道讀出控制代碼 si.hStdOutput = hOutput; //重定向輸出控制代碼為之前建立的檔案控制代碼 TCHAR *cmdline = char2TCHAR(command, 1); if (CreateProcess(NULL, cmdline, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi)) { //等待開啟的程序結束並關閉相關控制代碼 WaitForSingleObject(pi.hProcess, INFINITE); ::CloseHandle(pi.hThread); ::CloseHandle(pi.hProcess); } else { int err = GetLastError(); } //關閉管道讀寫控制代碼 CloseHandle(hRead); CloseHandle(hOutput); } // |命令 void Redirection_5(char **&command, int count) { //這裡利用檔案讀寫 //const char *path1 = Get_Char(command, count); //const char *path2 = Get_Char(command, 1); HANDLE hRead = NULL; HANDLE hWrite = NULL; SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, TRUE }; // 新建立的程序繼承管道讀寫控制代碼 if (FALSE == CreatePipe(&hRead, &hWrite, &sa, 0)) { return; } if (NULL == hRead || NULL == hWrite) { return; } //建立程序,從管道輸出端讀取資料 //以下是為了驗證讀取的正確性 char *p = "temp.txt"; wchar_t *path1 = char2LPCTSTR(p); LPCTSTR outputFile = path1; HANDLE hOutput = CreateFile( outputFile, GENERIC_WRITE, 0, &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hOutput == INVALID_HANDLE_VALUE) { return; } //以上是為了驗證讀取的正確性 //輸出程序,輸出定位到管道的輸入端 STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION pi = { 0 }; si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; si.wShowWindow = SW_HIDE; //不顯示建立的程序的視窗 //si.hStdInput = hRead;//重定向輸入控制代碼為之前建立的管道讀出控制代碼 si.hStdOutput = hWrite; //重定向輸出控制代碼為之前建立的管道輸入控制代碼 TCHAR *cmdline = char2TCHAR(command, 1); if (CreateProcess(NULL, cmdline, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi)) { //等待開啟的程序結束並關閉相關控制代碼 WaitForSingleObject(pi.hProcess, INFINITE); ::CloseHandle(pi.hThread); ::CloseHandle(pi.hProcess); } else { int err = GetLastError(); } CloseHandle(hWrite); //關閉管道輸入控制代碼 //輸入程序,輸入定位到管道的輸出端 STARTUPINFO si1 = { sizeof(si1) }; PROCESS_INFORMATION pi1 = { 0 }; si1.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; si1.wShowWindow = SW_HIDE; //不顯示建立的程序的視窗 si1.hStdInput = hRead;//重定向輸入控制代碼為之前建立的管道讀出控制代碼 si1.hStdOutput = hOutput; //重定向輸出控制代碼為之前建立的管道輸入控制代碼 TCHAR *cmdline1 = char2TCHAR(command, count); if (CreateProcess(NULL, cmdline1, NULL, NULL, TRUE, NULL, NULL, NULL, &si1, &pi1)) { //等待開啟的程序結束並關閉相關控制代碼 WaitForSingleObject(pi1.hProcess, INFINITE); ::CloseHandle(pi1.hThread); ::CloseHandle(pi1.hProcess); } else { int err = GetLastError(); } //關閉管道讀控制代碼 CloseHandle(hRead); CloseHandle(hOutput); //關閉檔案控制代碼 }