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

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

ただいまの
回答率

87.37%

【C#】【WPF】直近起動したすべてのexeのフルパスを取得する方法はありますか

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 944

score 40

前提

環境:VS2019
言語:C# WPF
フレームワーク:MVVM  

達成したい事

直近で使用したファイルを見れるプログラムを作成しています。
その一覧に、直近で使用したexeも見れるようにしたいです。

悩んでいる事

直近で自分が起動したexe のフルパスを取得する事は可能でしょうか。
直近で使用したファイルに関しては Recentフォルダ を見れば履歴が残っていますが、exeに関しては実行してもRecentフォルダに履歴が残りません。

そもそも、自分が起動したexeの一覧を見る事自体可能でしょうか?

追記---------------------------------------------------------------
すみません、書き方がよくありませんでした。
「直近で自分が起動したexe 」は
実行しているexeのパスではなく、最近実行した.exe 全てを指しています。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

+1

C:\Windows\Prefetchを解析すればどうにかなりそうですが、私はフォルダやファイルの仕様を知りません。
このあたりの情報を検索してみてはどうでしょうか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

皆様回答をありがとうございます。
プリフェッチファイルを最初に示して頂いたZuishinさんをBAとさせて頂きました。

色々調べてみた結果、Windows10だとバイナリでは解析できませんでした。
簡易解析入門 プログラム実行の痕跡の調査 (1)Prefetch

また、更に調べを進めていくと以下のツールが管理者権限(おそらく)不要でプリフェッチファイルを解析してくれることがわかりました。
GitHub - PEcmd

ソースもC#だったので追ってみると、以下を実行すれば求めている答えに近い出力結果が得られましたので共有いたします。

//Prefetch.dllが .NET 4.6以上をターゲットとしているので注意
var prefetcFullPath = @"C:\windows\prefetch\SCREEN.EXE-63A051E2.pf";

var pf = PrefetchFile.Open(prefetcFullPath);

foreach (var filename in pf.Filenames)
{
    if (filename.Contains(pf.Header.ExecutableFilename))
    {
        Console.WriteLine(filename);
    }
}

出力結果:\VOLUME{01d1e631699b3e2a-486a06d0}\ツール一覧\SCREENTOGIF\SCREEN.EXE

プリフェッチファイルの解析に関しては以下のツールが速くて高機能でしたがソースが見当たらなかったのと起動時に管理者権限を毎回求めてくるので深くは調べませんでした。
WinPrefetchView v1.35

ファイルがどこのドライブに属しているかを調査していましたが分かったので追記します。

上記のプログラムの出力結果の
「\VOLUME{01d1e631699b3e2a-486a06d0}\ツール一覧\SCREENTOGIF\SCREEN.EXE」
でアクセスできると思っていましたが、できませんでした。

コマンドプロンプト上で「mountvol」と入力すると、以下のような結果が出ます。
イメージ説明
「\\?\Volume{475a217f-53d2-4e99-a909-6482929b2582}\」をエクスプローラー上で検索すると、確かにCドライブに飛べました。ただVolumeの後のGuid値がどのドライブとも異なっているので何か別のCドライブを表現しているのだと思いました。

もう少し調べてみると、各ドライブは製造時に一意のGuidが振られているとのことでした。
コマンドプロンプトで「vol」と検索すれば出てきます。
私のCドライブのシリアル番号はこれのようです。(48始まりはNTFSみたいですね。)
イメージ説明

私のCドライブのVolumuInfoのシリアル番号と一致するデバイス名が出力結果と同じでした。
イメージ説明

ここまで分かれば後はもう組むだけですね。

//各ドライブのシリアル番号を取得
var drives = DriveInfo.GetDrives();
var driveDictionary = new ConcurrentDictionary<string, string>();
foreach (var drive in drives)
{
    var driveName = drive.Name[0] + ":";
    using (var disk = new ManagementObject("win32_logicaldisk.deviceid=\"" + driveName + "\""))
    {
        disk.Get();
        var serialNumber = disk["VolumeSerialNumber"];
        if (serialNumber != null)
        {
            driveDictionary.TryAdd(serialNumber.ToString(), driveName);
        }
    }
}

var prefetchFullPath = @"C:\windows\prefetch\SCREEN.EXE-63A051E2.pf";
var pf = PrefetchFile.Open(prefetchFullPath);

foreach (var filename in pf.ExeFileNames)
{
    //置換対象文字列の抽出
    var volumeInfo = pf.VolumeInformation
        .FirstOrDefault(x => filename.StartsWith(x.DeviceName));
    if (volumeInfo == null) return null;

    //置換対象文字列の置換
    var serialNumber = volumeInfo.SerialNumber;
    string driveName;
    _driveVolumeSerialNumberDictionary.TryGetValue(serialNumber, out driveName);
    return driveName + filename.Replace(volumeInfo.DeviceName, string.Empty);
}

出力結果: C:\ツール一覧\SCREENTOGIF\SCREEN.EXE

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

0

C:\Windows\Prefetch を見てみたらどうでしょうか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/08/12 23:00

    その他では、実行ログを取るように Windows の設定を変えるか、またはサービスを作って独自にログを取る必要があるのではないかと思います。

    キャンセル

0

WindowsFormであれば、コマンド引数のargs[0]にフルパスが入ってますが、WPFではどーなんでしょう

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/08/12 21:35 編集

    すみません、書き方がよくありませんでした。
    「直近で自分が起動したexe 」は
    実行しているexeのパスではなく、最近実行した.exe 全てを指しています。

    キャンセル

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

  • ただいまの回答率 87.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る