17

TL; DR

ユーザーがファイルをダブルクリックまたは選択してEnterWindowsエクスプローラー内からキーを押したときに実行される正確な低レベルのカーネルお​​よびOSプロセスは何ですか?


詳細

これはかなり奇妙な質問のように思えるかもしれませんが、Windowsエクスプローラーからファイルを開く際の非常に詳細な情報に興味があります。

Enter具体的には、ユーザーがファイルをダブルクリックまたは選択してWindowsエクスプローラー内からキーを押したときに実行される正確な低レベルのカーネルお​​よびOSプロセスについて知りたいと思います。

私が尋ねる理由は、ユーザーがデータベースに保存されているメタデータに基づいてファイルを参照および検索できるようにするアプリケーションを持っているためです。ユーザーがOpen私が提供したボタンをクリックすると、ルートファイルが選択されたファイルへのパスであるプロセスを開始します。また、これらのファイルはネットワーク共有上にあることにも言及する価値があります。

これは何年も機能していましたが、最近、私の会社が新しいActive Directoryサーバーに移行し、ごく少数のユーザー(1〜2%)のアプリケーションが壊れています。本当に奇妙なことに、これらのユーザーはこれを開くことができません。私のアプリケーションからファイルを取得しますが、その場所を参照してWindowsエクスプローラーから開くことができます。アプリケーションがファイルを開こうとすると、ファイルが見つからなかったことを示す非常に一般的な例外が発生します。

アプリケーションが使用しているパス(複数のファイルの場合)をトリプルチェックしましたが、パスが正しくありません。ファイルを開く前に、ユーザーがこれらのネットワークドライブに接続していることを確認しました。すべてが正しくセットアップされ、機能するはずですが、私のアプリケーション(またはSystem.Process)はこれらのファイルを「見る」ことも開くこともできません。

Windowsエクスプローラーアプリケーションは、アプリケーション内から使用する場合とは異なる動作をSystem.Processしますか?


答える前にコードを持っている必要がある人のために、ここに私がファイルを開くために使用する非常に簡潔なコードがあります。繰り返しになりますが、これは何年にもわたって機能しており、私が知っている限りでは、Windowsに.Net内からファイルを開かせる方法です。

//From my Button-Click Event...
string file = e.Cell.Value.ToString();
try
{
    Process p = new Process();
    p.StartInfo.FileName = file;
    p.StartInfo.Verb = "Open";
    p.Start();
} 
catch (Exception ex)
{
    MessageBox.Show("A problem has occurred while trying to open the doccument."
    + "Please make sure that the file below exists and that you have permission " 
    + "to view it."
    + Environment.NewLine + Environment.NewLine
    + file
    + Environment.NewLine + "---------------" + Environment.NewLine  +
    ex.Message

    );
    //ex.Message states "The system cannot find the file specified"
}

もう一つ。私はSOでこの質問を見つけましたが、この質問には当てはまらない/当てはまらないはずです。私のアプリは、PDFといくつかのエンジニアリング図面ファイルを開こうとしているだけです。特別なことは何もありません。管理者アクセスは必要ありません。また、ほとんどのユーザーがこのメッセージを受け取ることはなく、ログインしてネットワークの場所を参照することでネットワーク上で自分自身を検証しているため、ユーザー認証は必要ないと思います。

4

4 に答える 4

6

非常に一般的な障害モードであり、コードに存在するのは、ProcessStartInfo.WorkingDirectoryを適切に設定していないことです。プログラムのサブセットは、エクスプローラーがデフォルトの作業ディレクトリをファイルを含むディレクトリに設定し、設定されていない場合はフォールオーバーすることに依存しています。彼らは、フルパス名を指定せずに構成ファイルを開こうとするような賢明でないことをします。これは、作業ディレクトリが正しく設定されている場合にのみ機能します。

次のように修正します。

Process p = new Process();
p.StartInfo.FileName = file;
p.StartInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(file);
p.Start();

これは、ファイルのフルパス名を指定しないという同じ間違いをしないことを前提としています。

于 2012-09-27T14:00:56.500 に答える
6

ユーザーがファイルをダブルクリックまたは選択してWindowsエクスプローラー内からEnterキーを押したときに実行される、正確な低レベルのカーネルお​​よびOS呼び出しとは何ですか?

自分でテストできます。これが私がそれをした方法です:サンプルのC#プログラムコード

class Program
{
    static void Main(string[] args)
    {

    }        
}

これで、事前に定義された場所からこのアプリケーションを実行できます。次に、SysInternalsのProcMonアプリケーションを使用して、低レベルの呼び出しを監視できます。これは、私のマシンでProcMonによって生成されたcsvファイルのスナップショットです。pathファイルに含めるためだけにフィルターを配置しました。c:\test.exe

"Time of Day","Process Name","PID","Operation","Path","Result","Detail"
"14:57:55.3495633","Explorer.EXE","2568","CreateFile","C:\Test.exe","SUCCESS","Desired Access: Generic Read, Disposition: Open, Options: Open Requiring Oplock, Attributes: N, ShareMode: Read, AllocationSize: n/a, OpenResult: Opened"
"14:57:55.3498808","Explorer.EXE","2568","FileSystemControl","C:\Test.exe","SUCCESS","Control: FSCTL_REQUEST_FILTER_OPLOCK"
"14:57:55.3507711","Explorer.EXE","2568","CreateFile","C:\Test.exe","SUCCESS","Desired Access: Read Attributes, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, OpenResult: Opened"
...

csvのフルバージョンはpastebinで入手できます。csvファイルのすべての行は低レベルの呼び出しに対応し、さらにパスの厳密なフィルターのために除外された他の綿毛があります。

于 2012-09-27T14:21:02.653 に答える
2

あなたの「TL;DR」の質問は簡潔で要点がありますが、その質問に答えることであなたの問題が解決するかどうかはわかりません。ハンス・パッサントの答えはおそらくはるかに有用です。それにもかかわらず、私は少しの情報を提供しようとします。

Windowsにはいくつかのレイヤーがあり、この場合、2つの興味深いレイヤーはWindowsShellAPIとSystemServicesAPIです。WindowsシェルでProcess.Start()呼び出す方法で使用しています。ShellExecuteExWindowsシェルは、デスクトップ(実際には一部のディスク上のフォルダー)があり、ファイルがこれらのドキュメントを操作するためのアイコンと動詞を持つドキュメントとして扱われるWindows上に抽象化を提供します。あなたの場合、Open動詞を使用しています。

Windowsシェルは非常に複雑で拡張できるShellExecuteExため、特定のパスと動詞に対して何をしているのかは簡単に答えることができます。ローカルマシンに何が登録されているかによります。ただし、ファイルがPDFファイルで動詞がの場合、レジストリ内の拡張機能にOpen関連付けられているアプリケーションはすべてシェルで実行されると予想されます。.PDF

Windows 7では、 [コントロールパネル] >[プログラム] >[既定のプログラム] >[関連付けの設定]でファイルの関連付けを調べて変更できます。.PDF拡張機能に関連付けられているプログラムが見つからない場合は、取得できるFileNotFoundExceptionと思いますが、確認していません。

シェルがアプリケーションを実行する必要があると判断した場合、ある時点でシステムサービスレイヤーを呼び出し、そのCreateProcess関数を使用して新しいプロセスを作成します。PDFファイル(の登録に応じて)の場合、単一のコマンドライン引数(指定したファイル.PDF)で実行されるプロセスが作成されます。Acrobat.exe

問題のトラブルシューティングを行うには、コマンドプロンプトで書き込みfile.pdf(ファイルが存在する必要があります)して、シェルがPDFファイルを開くことができるかどうかを確認します。

于 2012-09-27T14:40:23.540 に答える
0

FileSystemInfo.FullNameを使用してこのようなことを試すことができますか?

string file = e.Cell.Value.ToString();
var fileInfo = new FileInfo(Path.Combine(System.IO.Path.GetDirectoryName(file) + file));
if (!fileInfo.Exists)
{
    throw new FileNotFoundException(fileInfo.FullName + " was not found");
}
System.Diagnostics.Process.Start(fileInfo.FullName);
于 2012-09-27T15:30:32.717 に答える