質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

2回答

14449閲覧

C++でコマンドプロンプトの操作を行いたい

退会済みユーザー

退会済みユーザー

総合スコア0

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/03/03 02:13

編集2020/03/03 02:18

前提・実現したいこと

C++でコマンドプロンプトのcopyを複数回使用したいと思っています。
system関数ではコピーのたびにコンソール画面が表示されるため、CreateProcess関数を使いコンソール画面を非表示にしたいのですが、処理が行われません。
解決方法を教えていただけないでしょうか。

発生している問題・エラーメッセージ

CreateProcess()がfalseになる

該当のソースコード

C++

1// srcPath: コピー元のフルパス 2// dstPath: コピー先のフルパス 3bool copy(CString srcPath, CString dstPath) 4{ 5 CString cmd; 6 cmd.Format(_T("copy \"%s\" \"%s\""), srcPath, dstPath); 7 8 STARTUPINFO si = {}; 9 PROCESS_INFORMATION pi = {}; 10 GetStartupInfo(&si); 11 12 ZeroMemory(&si, sizeof(STARTUPINFO)); 13 si.cb = sizeof(STARTUPINFO); 14 si.dwFlags = STARTF_USESHOWWINDOW; 15 si.wShowWindow = SW_HIDE; 16 17 bool res = CreateProcess( 18 NULL, // 実行可能モジュールの名前 19 cmd.GetBuffer(0), //コマンドライン文字列 20 NULL, // セキュリティ記述子 21 NULL, // セキュリティ記述子 22 FALSE, // ハンドルの継承オプション 23 0, // 作成のフラグ 24 NULL, // 新しい環境ブロック 25 NULL, // カレントディレクトリの名前 26 &si, // スタートアップ情報 27 &pi // プロセス情報 28 ); 29 30 if(!res) return false; 31}

試したこと

下記ではコピーが行われるたびにコンソール画面が立ち上がってしまい挙動が遅い。

C++

1std::string dq("\""); 2std::string srcCmd = "copy " + dq + src_path + dq + " " + dq + dst_path + dq; 3const char* cmd = srcCmd.c_str(); 4int ret = system(cmd);

補足情報(FW/ツールのバージョンなど)

windows10
visual studio 2017
文字セット:Unicode文字セットを使用する

Win32APIのCopyFile関数、C++17のfilesystem::copy_file関数はウイルスバスターの挙動監視に引っかかってしまい使用できませんでした。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2020/03/03 02:19

「コマンドプロンプトのcopy」で行う必然性はありますでしょうか?
退会済みユーザー

退会済みユーザー

2020/03/03 02:21

さきほど補足情報に文言を追加させていただきましたが、CopyFile関数やfilesystemクラスを使用するとウイルスバスターの挙動監視にひっかかり、アプリケーションが落とされてしまいます。
maisumakun

2020/03/03 02:25 編集

それはウイルスバスターが悪いです(一般的なパソコンで実行ファイルを作ることはまず行いませんので、自分のマシンでコンパイルを行うと誤認識が多発します)。
退会済みユーザー

退会済みユーザー

2020/03/03 02:30 編集

Releaseビルドを行い、exeから起動しても同じ現象が発生します。他の方法が思いつかず頓挫しています。 ウイルスバスターは会社のセキュリティ上、設定をいじれないためウイルスバスターをどうこうするは認められませんでした。
maisumakun

2020/03/03 02:39

C++以外の言語を使う、という選択肢はありますか?
退会済みユーザー

退会済みユーザー

2020/03/03 03:00

Visual C++ 6.0の移植という形でやっていますので、C++以外は色々と問題が発生しそうですね。。。
cateye

2020/03/03 03:19 編集

.batファイルじゃダメなんですか? →https://www.atmarkit.co.jp/ait/articles/1506/26/news026.html
otn

2020/03/03 03:29

> コンソール画面が立ち上がってしまい挙動が遅い 遅い原因が、コンソール画面の表示だと、どういう根拠で判断しましたか? 外部コマンドを起動する(プロセス生成する)から遅いのでは?
SHOMI

2020/03/03 03:40

CopyFileが引っかかるならSHFileOperationも駄目かな…?
退会済みユーザー

退会済みユーザー

2020/03/03 04:20

>>cateye様 GUIアプリと作成しているためbatファイルは問題が発生してしまいます。
退会済みユーザー

退会済みユーザー

2020/03/03 04:21

>>otn様 数値などを計測したわけではありませんので、単純にフォルダを目視してて体感で遅いと思っただけです。
退会済みユーザー

退会済みユーザー

2020/03/03 04:23

>SHOMI様 ご回答ありがとうございます。SHFileOperationも試してみましたが同じくだめでした。 いまのところコマンドプロンプトのcopyのみウイルスバスターにひっかからず行えるようです。
otn

2020/03/03 04:26

> コンソール画面が立ち上がってしまい挙動が遅い に根拠がなく、system("copy~”)で出来るなら、それで良いのでは?
退会済みユーザー

退会済みユーザー

2020/03/03 05:46

直接CTRL+C, CTRL+Vでコピーを行う処理と比較すると3倍ほど時間がかかっていました。また、コンソール画面がコピーのたびに立ち上がり、そちらに触れるとアプリケーションが終了してしまいますので仕様してはよろしくないのであまりやりたくないというのが本音です。
cateye

2020/03/03 06:41

>3倍ほど時間がかかって・・・コマンドを立ち上げて、コピーするのですから当然と思いますが?
t_obara

2020/03/03 07:14

batファイル中にcopy処理を記述し、そのbatファイルを呼び出すようにすれば、一度のコンソール画面表示のみで対応できるかと。
guest

回答2

0

コピー方法としては、
方針1:外部プロセスを起動する
方針2:外部プロセスを起動しない
の2つの方針があります。

方針1が、Explorerのコピペより3倍遅いというのは、もしかしてたくさんの小さいファイルをループの中で個別にコピーしているのでしょうか?それであれば、プロセス起動のオーバーヘッドで遅いので、方針1であれば、system("copy~")であろうが、CreateProcessxcopy等を呼ぶのであろうが同じでしょう。

(copycmd.exeの内部コマンドなので、CreateProcessで呼び出すなら、cmd /c copy ~とする必要があり、これはsystem("copy ~")と同じです。CreateProcessxcopy.exeを呼ぶのは可能ですが、これもコンソールアプリなので、コンソール画面が出るでしょう)

方針2については、いくつかの方法が提案されていますが、自分で作ったEXEであればファイルに書けず、Windows標準のcmd.exe /c copyなら書けるのであれば、ファイル書き込み可能なEXEファイルがホワイトリストで登録されているのですかね?

Windows標準のwscript.exeを使うVBScriptで書けばファイル書き込みできるかもしれません。
FileSystemObjectオブジェクトのCopyFileメソッドを使います)
繰り返しがあるなら、VBScriptの中でループして、C++からのプロセス起動を1回にします。
そもそも、C++を使わず、全部VBScriptで書けるなら書けば簡単です。

投稿2020/03/03 11:38

otn

総合スコア84499

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

CreateProcessは文字通り「プロセスを実行するもの」です
いわゆるexeファイルを起動するもので、copyはexeファイルではないので起動できません

ファイルのコピーなら、WIN32APIのCopyFileか
boostのfilesystem::copy_file()を使えばいいと思います

投稿2020/03/03 02:23

izmktr

総合スコア2856

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/03/03 02:25

補足情報に記載させていただいてますが、CopyFile, filesystemではウイルスバスターの挙動監視に引っかかってしまい使用できません。他の方法はご教示いただけないでしょうか。
maisumakun

2020/03/03 02:28

> ウイルスバスターの挙動監視に引っかかってしまい使用できません。 他人のマシンで実行してもそうなるなら問題ですが、そうではなくて自分のマシンで作っている途中だけの問題だったら「ウイルスバスターをそのフォルダだけ除外する」ような対策が適当かと思います。
izmktr

2020/03/03 02:31

fread/fwrite を使えばいいんじゃないでしょうか?
退会済みユーザー

退会済みユーザー

2020/03/03 02:34

"ネットワークドライブのファイルをコピーする"実行ファイルですので他のマシンでも挙動は変わりませんでした。後出し情報で申し訳ありません。
退会済みユーザー

退会済みユーザー

2020/03/03 02:55

>>izmktr様 ご回答ありがとうございます。こちらを試してみましたが、やはりウイルスバスターの"不正な挙動の検出"にひっかかりアプリケーションを落とされてしまいました。
izmktr

2020/03/03 03:07

なら諦めるしかないですね 私としても、最初からウィルスバスターと戦う質問ならスルーしてたでしょう
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問