連休で時間はあるので、ちょっとだけ変更を続ける。
せっかくC言語で作っているのだから、コマンドラインオプションぐらいは設定出来るようにする。
これまで、ローカル変数(TmpPath)のスコープを間違えていて、exec_cmdに渡す時には無効になっていました。実動作であれば、すぐにはその領域が書き換えられる事は無いでしょうが。
オプション解析に変数iをインデックスに使っている。変数名は変えるべき。
#define NumOptions 6 // TeraCopyのオプションの種類数を上限にする typedef struct { _TCHAR *cmd; _TCHAR *src; _TCHAR *trg; _TCHAR *CommandOption[NumOptions]; } stArgument; void teracopy(int argc, _TCHAR* argv[]) { _TCHAR TmpPath[UMAX_PATH]; stArgument starg; int CommandOption_index = 0; int i; // コマンド解釈部 // オプションとターゲットフォルダを設定 for (i = argc - 1; i > ARGC_CMD; i--) { if (argv[i][0] == _T('/')) { if (CommandOption_index < NumOptions) { starg.CommandOption[CommandOption_index] = argv[i]; CommandOption_index++; } else { usage(); } } else { // ターゲートフォルダまでの設定が完了したのでループを抜ける starg.trg = argv[i]; i--; break; } } // ソースファイルを設定する if (i == ARGC_CMD + 1) { // 1ファイル/ディレクトリに対する処理なのでtmpファイルを作らない starg.cmd = argv[ARGC_CMD]; starg.src = argv[ARGC_CMD + 1]; } else { _TCHAR TmpFilePath[UMAX_PATH] = {NULL}; FILE *fp; errno_t err; getTmpFilePath(TmpFilePath); // \\?\から始まるパス名 拡張機能 _stprintf_s(TmpPath, sizeof(TCHAR) * UMAX_PATH, _T("\\\\?\\%s"), TmpFilePath); err = _tfopen_s(&fp, TmpPath, _T("w")); if (err != 0) { MessageBox(NULL, _T("teracopy_wrap:can not open tmpfile."), NULL, MB_OK); exit(-1); } for (int j = ARGC_CMD + 1; j <= i; j++) { _ftprintf_s(fp, _T("%s\n"), argv[j]); } fclose(fp); _stprintf_s(TmpPath, sizeof(TCHAR) * UMAX_PATH, _T("*%s"), TmpFilePath); starg.cmd = argv[ARGC_CMD]; starg.src = TmpPath; } exec_cmd(&starg); return; }
あわせて、コマンド実行部も変更した。
// コマンド実行部 void exec_cmd(stArgument *pstarg) { BOOL result; _TCHAR CmdStr[UMAX_PATH]; PROCESS_INFORMATION pinfo = {NULL}; STARTUPINFO sinfo = {NULL}; _stprintf_s(CmdStr, sizeof(_TCHAR) * UMAX_PATH, _T("\"C:\\Program Files\\TeraCopy\\TeraCopy.exe\" %s \"%s\" \"%s\""), pstarg->cmd, pstarg->src, pstarg->trg); // オプションをつなげる for (int i = 0; pstarg->CommandOption[i] != NULL && i < NumOptions; i++) { _tcscat_s(CmdStr, sizeof(_TCHAR) * UMAX_PATH, _T(" ")); // 空白を入れたい _tcscat_s(CmdStr, sizeof(_TCHAR) * UMAX_PATH, pstarg->CommandOption[i]); } GetStartupInfo(&sinfo); result = CreateProcess(NULL, CmdStr, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &sinfo, &pinfo); if (result == FALSE) { // 失敗 usage(); } CloseHandle(pinfo.hThread); // WaitForSingleObject(pinfo.hProcess, INFINITE); CloseHandle(pinfo.hThread); }