
C言語で自分自身がどのディレクトリに存在しているか
知りたいのです。
簡単に例を挙げて説明します。
UNIX C言語で cmd1 という実行ファイルを作成しました。
環境変数は以下のように定義されていたとします。
PATH=/bin:/usr/bin
/binにcmd1を配置してカレントディレクトリ/homeにおいて
cmd1を実行、cmd1プログラム内で"/bin/cmd1" を取得したいのです。
続けて、/bin/cmd1を/usr/bin/cmd1移動して、cmd1を実行すれば、
プログラム内で"/usr/bin/cmd1"を取得できるコーディングをしたいのです。
typeコマンドのような事をC言語で行いたいのですが。
お分かりの方いらっしゃいましたら教えてください。
よろしくお願いします。
No.7ベストアンサー
- 回答日時:
>C:\WINDOWS\COMMAND\CMD1.EXE
>と表示されます。
>この違いはなんだろう?
C:\windows\commandってフォルダに突っ込んでる時点でOSがぜんぜん違いますよね。
Win9xとNT系じゃ。
9x系はフルパスが、NT系は起動時の実行コマンドargv[0]には格納されています。
UNIXでは実行モジュールのフルパスを取得する一般的な方法は無いみたいです。
Windowsでは#4の方の書かれているとおり、GetModuleFileName()です。
「UNIXでは実行モジュールのフルパスを取得する一般的な方法は無いみたいです」
そうですか。
こちらに質問を書き込む前に私なりに調べてみました。
もしかして出来ないのかなぁ?と少し思いつつ、
そんなはずはないだろう。。。と思い質問した次第です。
回答ありがとうございました。
No.8
- 回答日時:
うろ覚えの記憶で申し訳ありませんが、TclのAPIであるTcl_FindExecutable関数がプログラムのフルパスを取得できます。
Tclを使えるのであれば、そのまま使っても構いませんし、Tcl_FindExecutable関数を真似て、自作してもよいかと思います。
大まかに言って、次のような方法で実現されていたはずです。
gccでは、コマンドラインで入力されたプログラム名が、そのままargv[0]に格納されます。argv[0]に絶対パスまたは相対パスが指定されていれば(要するに'/'が含まれている場合)、そのディレクトリを元にフルパスを生成します。ファイル名のみ指定されていれば、環境変数PATHに指定されているディレクトリを順に検索して、該当するプログラムが存在するかどうかを調べます。
プログラム起動後に、ファイルが削除されたり、移動されたり、改名される可能性もあるので、100%確実な方法とは言えないでしょうが、普通は問題ないかと思います。高いセキュリティが要求される場合は、やめた方がよいかも知れませんが...
やはり行き着く先はPATHのディレクトリ探索になりますか。
おしゃられるように起動後のファイル移動等に注意が必要ですね。
回答ありがとうございました。
No.6
- 回答日時:
#4です。
この掲示板では討論のような個人的なやりとりは禁止されているので書き込むのは悩むところですが、質問者さんが誤解するといけないので...
繰り返しになりますがargやWindowsAPIのGetCommandLineで取得できるのは実行時の「コマンド」になります。そのため実行ファイルに対するフルパスではありません。
しかしargを調べて見ると実行時にフルパスが取得できていることがあります。それは実行時にフルパスを指定して起動した場合です。また実行するときにフルパスを指定していないにもかかわらずフルパスが返ることもあります。これはWindowsAPIのCreateProcessが勝手にフルパスに変換することがあるためです。
具体的にはWindows9x系ではフルパスが返ることが多いようです。WindowsNT4.0/2000/XPの場合はフルパスにならないことが多いです。
また質問は
>C言語で自分自身がどのディレクトリに存在しているか
ということです。自分自身がどのディレクトリに存在しているかを知るためには自分自身ファイルへのフルパス(例c:\a.exe)を取得して、そこからファイルの部分を除去してディレクトリ(例c:\)に変換します。
しかしargなどで取得できるのは"実行ファイル"のみです。例えば自分自身がDLLファイルなどで実行されていた場合にはDLLをロードしているExeのフルパスが返るだけであり、自分自身へのフルパスを取得することができません。
そのためWindowsでは自分自身のフルパスを取得するにはGetModuleFileNameのようなAPIを利用します。
EXEであれば
#include "windows.h"
TCHARpszPath[MAX_PATH];
GetModuleFileName(NULL,pszPath,MAX_PATH);
のように利用します。DLLの場合は第一引数をモジュールへのハンドルにします。
UNIXでは。。。すみません。知識がなく分かりません。
argを見てフルパスならそれを利用、そうでなければカレントフォルダを参照する、のような方法が考えられますが、「./aaa/bbb/cmd.exe」のような相対的なパスを示すargが返ってくることも考えられるので気をつける必要があると思います。
回答ありがとうございます。
「Windows9x系ではフルパスが返ることが多いようです。WindowsNT4.0/2000/XPの場合はフルパスにならないことが多いです」
そうなんだ。と驚いています。
GetModuleFileNameについても丁寧に書いていただきありがとうございます。
No.5
- 回答日時:
>#4殿
話をドリフトさせるのはやめてください。
>Windowsで自分自身のファイルを取得したい場合はGetModuleFileNameを使います。
そんな要求はしていません。
>コマンドプロンプトなどで実行した場合はフルパスになりません。
試したんですか?
こちらは書いたとおりのことを試してみて、書き込んでるんですよ。c:\windows\commandに実際にcmd1.exeをコピーし、コマンドプロンプトからc:\へ移動してcmd1とタイプしてごらんなさい。
C:\WINDOWS\COMMAND\CMD1.EXE
と表示されますよ。
回答ありがとうございます。
確かにGetModuleFileNameは期待している回答では
ありません。
ですが、UNIXでという質問の意図とは異なりはしますが、
WindowsでもOS違いでargv[0]の値は異なるみたい。
というのは驚きと面白い発見でした。
No.4
- 回答日時:
argやGetCommandLineは実行時に渡された「コマンド」が返ります。
VC++などでは実行時にフルパスで実行するためargでフルパスが返りますが、コマンドプロンプトなどで実行した場合はフルパスになりません。プラットフォームが何なのかにもよりますが、Windowsで自分自身のファイルを取得したい場合はGetModuleFileNameを使います。回答ありがとうございます。
VC++で実行した場合とコマンドプロンプトから
実行、さらにプラットフォームの違いによっても
argv[0]の値が異なる可能性があるということですね。
勉強になります。
No.3
- 回答日時:
こちらも実際に試してみました。
VC++6.0で、console applicationを作って、cmd1.exeを作成し、c:\windows\commandに入れました。
c:\上から、cmd1とタイプすると、
C:\WINDOWS\COMMAND\CMD1.EXE
と表示されます。
この違いはなんだろう?
ていうか、argv[0]にフルパスが含まれるのは大分昔からの仕様だと思ってたんだけど・・・。
No.2
- 回答日時:
今unixの環境が手元に無いんだけど、MS-DOSで実行すると
argv[0]はフルパスを返します。
"c:\windows\デスクトップ\cmd1.exe"のように。
unixでは"/usr/bin/cmd1"を返さないのでしょうか?
"cmd1"のみ?
この回答への補足
回答ありがとうございます。
MS-DOSはあまり経験がないのですが今やってみました。
Windows2000です。
cmd1.exeを作成して、PATHの通った場所にコピーしました。
具体的にはC:\WINNT\system32に入れました。
そしてカレントをC:\に移動して実行しました。
C:\>cmd1.exe
cmd1.exe
cmd1.exeとしか表示されませんでした。
私の説明がまだ不足しているような気がします。
C:\WINNT\system32\cmd1.exe
というパスを何らかの方法で簡単に取得できないかと
苦慮しています。
よろしくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- UNIX・Linux cronの@rebootでのdateコマンドの実行につきまして 2 2023/06/11 16:23
- その他(プログラミング・Web制作) ラズパイ上の、pythonのエラーについて 1 2023/04/12 23:27
- UNIX・Linux cronでシェルスクリプト実行時のkubactlコマンドが機能しない対処法。 2 2022/08/03 18:58
- UNIX・Linux postfix smtpサーバーリレーがTLSハンドシェーク失敗 1 2022/08/15 15:45
- Visual Basic(VBA) エクセル VBA 条件付き書式 簡略化したい 2 2022/06/02 17:46
- Excel(エクセル) Excelにの以下の設定方法について教えてください! C列にデータ入力の設定をしています。(出、入を 3 2022/06/22 01:33
- Visual Basic(VBA) 【VBA】先月分の取得ができない理由が分かりません。 2 2022/04/24 11:16
- 数学 数1 この問題の(3)で少なくとも一方が実数解をもつ。のとき①②の式をそれぞれD1,D2とした時D1 5 2023/08/01 01:46
- その他(Microsoft Office) IF関数について教えてください 2 2022/05/10 13:31
- CGI htmlからパラメータで、cgiに渡したい。 1 2023/02/06 16:15
このQ&Aを見た人はこんなQ&Aも見ています
-
<unistd.h>をVisualStudioでつかえるようにする
C言語・C++・C#
-
絶対パスの取得について
C言語・C++・C#
-
実行プログラム名の取得
C言語・C++・C#
-
-
4
CStringからchar*への型変換について教えてください。
C言語・C++・C#
-
5
Enterキーを押されたら次の処理に移るという事をしたい。
C言語・C++・C#
-
6
C言語でファイル名を取得
C言語・C++・C#
-
7
ファイルやディレクトリの存在確認を行う方法
C言語・C++・C#
-
8
【gcc・cygwin】multiple definitionエラーの解決法
C言語・C++・C#
-
9
他の実行ファイルを実行するプログラム
C言語・C++・C#
-
10
ファイル出力の場所を指定
C言語・C++・C#
-
11
コマンド(例えばls)の出力結果を文字列で取得するプログラムの作成方法
C言語・C++・C#
-
12
C言語初心者の質問失礼します。
C言語・C++・C#
-
13
関数から配列を返すには?
C言語・C++・C#
-
14
Cの関数で自分自身のパス取得
C言語・C++・C#
-
15
fopenで別ディレクトリにファイルをオープンしたい
C言語・C++・C#
-
16
DWORDの実際の型は何でしょうか
C言語・C++・C#
-
17
WaitForSingleObjectの使い方について
C言語・C++・C#
-
18
エディットボックスの入力制限について
C言語・C++・C#
-
19
相対パスを絶対パスに変換したい
C言語・C++・C#
-
20
【MFC】Version情報の取得
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルvbaでdocuworksprinter...
-
エクセルVBAで一つ上の階層...
-
実行ファイルのパスを取得したい
-
【VBA】複数のtxtファイルから...
-
Excel 相対パス
-
xcopyコマンドの進行状況を表示...
-
VBA★PDFをPDFアプリで印刷し...
-
C#でのProcess.Startと変数path
-
コマンドプロンプトのコピー関...
-
開いているファイルを削除し、...
-
パスワード保護されたExcelファ...
-
ExcelVBAの使い方 ¥の使い方...
-
初心者powershellのPS1ファイル...
-
EXCEL(VBA)で指定フォルダ内の...
-
ExcelのVBAで上書き保存を確...
-
【VB.NET】App.configにファイ...
-
Pythonのバージョンに関する質...
-
アクセス 自身のデータベース...
-
リストボックスにファイル名の...
-
OleDbDataAdapterのエラー
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルvbaでdocuworksprinter...
-
エクセルVBAで一つ上の階層...
-
xcopyコマンドの進行状況を表示...
-
Excel 相対パス
-
【VB.NET】App.configにファイ...
-
【VBA】ExcelマクロでCSVファイ...
-
エクセルのマクロで特定フォル...
-
実行ファイルのパスを取得したい
-
コマンドプロンプトのコピー関...
-
VBA★PDFをPDFアプリで印刷し...
-
VBAでパワーシェルを実行したい...
-
ExcelVBAの使い方 ¥の使い方...
-
C#でのProcess.Startと変数path
-
ExcelのVBAで上書き保存を確...
-
開いているファイルを削除し、...
-
アプリケーションのインストー...
-
【VBA】複数のtxtファイルから...
-
EXCEL(VBA)で指定フォルダ内の...
-
fopenでのパス指定
-
パスワード保護されたExcelファ...
おすすめ情報