TeraCopyをコマンドラインから呼び出す(その6)

連休で時間はあるので、ちょっとだけ変更を続ける。
せっかく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);
}