16

cmd.exe の現在の作業ディレクトリを取得するにはどうすればよいですか?

これは可能のようです。たとえば、ProcessExplorer を使用して、CMD.exe を選択し、右クリックして、プロパティ、[イメージ] タブ、[現在のディレクトリ] に、CD または CHDIR コマンドを使用して設定されたディレクトリが反映されます。

.NET Process および ProcessStartInfo クラス (ProcessStartInfo.WorkingDirectory は常に "" を返す) を調べましたが、これを判断する方法が見つからないようです。PInvokeにも目立ったものはありません。

たとえば、Process.GetCurrentWorkingDirectory(processID) のようにプログラムで記述できるようにしようとしています。ここで、processID は実行中の別のプロセスの Windows プロセス ID です。

解決策、WinAPI または .NET はありますか?

[アップデート]

この質問をする理由:

「コマンドプロンプトエクスプローラーバー」をしばらく使用しましたが、新しいディレクトリに「CD」した場合を除いて、現在のエクスプローラーウィンドウも変更されません。(つまり、同期は、エクスプローラーからコマンド プロンプトへの 1 方向のみです)。私はこれを2ウェイにすることを目指しています。

4

6 に答える 6

6

テストされていない、可能なアプローチ:

GetThreadStartInformation() を使用してバッファーのアドレスを検索し、GetCurrentDirectory を使用してデータを設定する DllMain を持つ DLL を作成します。これらの関数は両方とも、常に存在する kernel32 にあるため、これで問題ありません。成功/失敗を返すには、何らかの構造が必要です。

  1. cmd.exe プロセスへのハンドルを取得します。
  2. そこにメモリを割り当てます (VirtualAllocEx)
  3. DLL へのパスをメモリに入れます。(WriteProcessMemory)
  4. dll を cmd.exe アドレス空間にロードします。(LoadLibrary のエントリ ポイントを持つ CreateRemoteThread、引数は以前に割り当てたメモリです。)
  5. WaitForSingleObject の後に GetExitCodeThread() を実行すると、cmd.exe プロセスで DLL の HMODULE が得られます。
  6. ReadProcessMemory を使用して現在のディレクトリを取得します。
  7. cmd.exe アドレス空間から dll をアンロードします。FreeLibrary のエントリ ポイントを持つ CreateRemote Thread。引数は HMODULE です。
  8. DLL がアンロードされるまで待機する WaitForSingleObject。

大まかなスケッチ: 詳細は練習問題として残しておきます! リスク: cmd.exe アドレス空間にメモリを割り当て、その状態を変更します。DllMain で呼び出される関数には注意が必要です。

于 2008-10-20T10:55:37.437 に答える
5

バッチファイルの %CD% 変数のことですか?

このような:

set OLDDIR=%CD%
.. do stuff ..
chdir /d %OLDDIR% &rem restore current directory

コマンド プロンプトでecho %CD%を試してください。:)

これが必要なので、これを行うためのPowerShell関数があります。

$(get-location)

お役に立てれば。

ここからすべてを見つけました。

于 2008-10-20T10:04:57.710 に答える
5

Sysinternals フォーラムのこのフォーラム エントリに、解決策のヒントが含まれている可能性があります。GetProcessStrings 関数でこれを探します。

// Get Command Line Block

// At offset 0x00020498 is the process current directory followed by

// the system PATH. After that is the process full command line, followed

// by the exe name and the windows station it's running on.

この CodeProject の記事「リモート プロセスの環境文字列の読み取り」も役立ちます。

于 2008-10-20T17:56:35.387 に答える
2

更新:これは解決策ではありません。この回答へのコメントを参照してください。現在の作業ディレクトリ (CD または CHDIR コマンドを使用して変更できます)。」

System.Diagnostics Namespaceを使用できます。ここでは、C# コンソール アプリケーションとしての例を示します。ファイル名からパス情報 (System.IO.Path...) を簡単に抽出できます。

これを行うための権限(管理者として実行)があることを確認してください。

お役に立てれば。これが作業コードです(テスト済み):

using System;
using System.Diagnostics;
using System.IO;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Process[] procList =  Process.GetProcessesByName("cmd");

            string sFileName;

            for (int i = 0; i < procList.Length; i++ )
            {
                Console.Write(procList[i].Id);
                Console.Write(" ");

                try
                {
                    sFileName = procList[i].Modules[0].FileName;
                    Console.Write("(");
                    Console.Write(Path.GetFileName(sFileName));
                    Console.Write("): ");
                    Console.WriteLine(Path.GetDirectoryName(sFileName));
                }
                catch (Exception ex)
                {
                    // catch "Access denied" etc.
                    Console.WriteLine(ex.Message);
                }


            }

        }
    }
}

これが私のマシンの出力です(4つのコマンドラインを開きました):

代替テキスト http://img236.imageshack.us/img236/3547/processworkingdirvn4.png

于 2008-10-20T14:55:36.517 に答える
0

同様の質問に対する私の回答を参照してください(私自身)。プロセス環境変数を読み取るコマンド ライン ユーティリティと C# ラッパーを作成しました。私の質問 (java の現在のディレクトリを取得する) では、単純に catalina_base ディレクトリを読み取ります。

これが cmd.exe に直接当てはまるかどうかはわかりません。Code Project の記事で提供されているユーティリティは、cmd.exe では機能しませんでした。

于 2009-01-14T08:17:11.673 に答える