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

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

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

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

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

Q&A

解決済

2回答

15938閲覧

win32apiのGetCommandLine()でコマンドライン引数がうけとれない

geitsu

総合スコア14

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

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

0グッド

1クリップ

投稿2017/05/05 09:37

###発生している問題・エラーメッセージ
win32apiのGetCommandLine()でコマンドライン引数をうけとると

"C:Users\ユーザー名\documents\visual studio
2015\Projects\Win32Project3\Debug\Win32Project3.exe"
\Users\ユーザー名\Desktop\test.txt

とコマンドライン引数だけでなく実行ファイルのパスも受け取ってしまって
下記のソースコードのCreateFile()が失敗します
GetComanndLine()を使わない方法でもいいのでコマンドライン引数をうけとってCreateFile()を実行する方法を教えてください

コマンドライン引数はソリューションエクスプローラー>プロパティ>デバッグ>コマンド引数から設定しました
###該当のソースコード

c++

1#include <windows.h> 2 3int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR lpCmdLine,int nCmdShow) 4{ 5 HANDLE hFile; 6 7 hFile = CreateFile(GetCommandLine(), GENERIC_READ, 0, NULL,CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); 8 if (hFile == INVALID_HANDLE_VALUE) 9 { 10 MessageBox(NULL, GetCommandLine(),TEXT("エラー"), MB_OK); 11 return 1; 12 } 13 14 CloseHandle(hFile); 15 16 return 0; 17}

###試したこと
WinMainのlpCmdLine引数はPSTRからLPCWSTRへの型変換ができないのでCreateFile()の引数にできなかったです
CommandLinetoArgvW()はLPWSTRからLPCWSTRの型変換ができないのでCreateFile()の引数にできなかったです

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

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

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

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

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

guest

回答2

0

ベストアンサー

__argv__argcというグローバル変数が定義されているのでそれを使う(正規の方法ではない)

EternalWindows

CommandLineToArgvWで受け取った文字列をWideCharToMultiByteで変換してから渡す。

Win32アプリのコマンドライン引数を解析するラッパー関数を書く

ANSI版からUnicode対応に置き換える
Visual Studioでプロジェクトを作ったらデフォルトでこの設定のはず。

WinMain → wWinMain
CreateFile → CreateFileW


追記:

CommandLineToArgvWの使い方を知りたいみたいだったので追記。
Unicode対応だとわかりやすいようにWが付いた方のAPIを指定してます。

C++

1#include <windows.h> 2 3int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR lpCmdLine, int) 4{ 5 int Argc; // コマンドライン引数の個数 6 LPWSTR *Argv; // コマンドライン引数のリスト 7 HANDLE hFile = nullptr; 8 9 // GetCommandLine()を使用した場合は、Argv[0]に実行時のパスが入り、 10 // Argv[1]以降にコマンドライン引数が入る 11 // lpCmdLineを指定した場合は、Argv[0]に1番目のコマンドライン引数が入る 12 Argv = CommandLineToArgvW(GetCommandLineW(), &Argc); 13 // Argv = CommandLineToArgvW(lpCmdLine, &Argc); 14 15 hFile = CreateFileW(Argv[1], GENERIC_READ, 0, nullptr, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, nullptr); 16 if (hFile == INVALID_HANDLE_VALUE) { 17 MessageBoxW(nullptr, L"ファイルのオープンに失敗しました", L"エラー", MB_OK); 18 return 1; 19 } 20 21 CloseHandle(hFile); 22 23 return 0; 24}

これで>test.exe text1.txt text2.txt text3.txtのような感じで、スペースで区切って複数のオプションを指定した場合、

Argv[0]にtest.exe
Argv[1]にtext1.txt
Argv[2]にtext2.txt ... というようにコマンドライン引数が格納され、

CreateFileにArgv[1]を指定しているので、text1.txtが作成され他は無視されるというわけです。

投稿2017/05/05 10:05

編集2017/05/05 15:31
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

geitsu

2017/05/05 10:55

WinMainをwWinMainに変えたらlpCmdLine引数をCreateFile()の引数にできました ありがとうございました
退会済みユーザー

退会済みユーザー

2017/05/05 11:29

何を参考にしているかはわかりませんが、 Unicode対応で書くとなると TCHARとかLPCTSTR、LPTSTRって何??? http://www.usefullcode.net/2006/11/tcharlpctstrlptstr.html 紛らわしいぞ!LPCTSTR、LPTSTR、LPSTR、LPCSTRは全部意味が違う! http://www.usefullcode.net/2006/11/lpctstrlptstrlpstrlpcstr.html あたりを読んでマルチバイト文字とワイド文字の違いは理解したほうが良いと思います。 古いサンプルはマルチバイト文字が前提になっていると思うので。
geitsu

2017/05/05 15:42 編集

ありがとうございます 理解できました
guest

0

GetCommandLine() が実行ファイル名を含むのは仕様です。

WinMain

lpCmdLine

アプリケーションのコマンドラインが格納された NULL で終わる文字列へのポインタが入ります。プログラム名は含まれません。コマンドライン全体を取り出すには、GetCommandLine 関数を使ってください。

ANSI アプリケーションは、WinMain 関数の lpCmdLine パラメータによりコマンドライン文字列にアクセスすることができます。ただし、この文字列にはプログラム名は含まれません。WinMain 関数が Unicode 文字列を返せないのは、lpCmdLine パラメータがデータ型として LPTSTR ではなく LPSTR を使っているためです。GetCommandLineW 関数を使えば Unicode のコマンドライン文字列を取得できます。

GetCommandLine で取得し、CommandLineToArgvW を使って解析してください。

投稿2017/05/05 09:53

Zuishin

総合スコア28656

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

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

geitsu

2017/05/05 10:55

CommandLinetoArgvW()はLPWSTRからLPCWSTRの型変換ができないのでCreateFile()の引数にできなかったです
Zuishin

2017/05/05 10:58

他の方法で解決されたので蛇足になりますが、 まあいいや。
geitsu

2017/05/05 13:11

教えて
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問