2012-09-27 3 views
13

TL; DRWindowsでは、エクスプローラでファイルをダブルクリックすると明示的に何が起こりますか?

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


詳細

これはかなり奇妙な質問のように思えるかもしれないが、私は、Windowsエクスプローラからファイルを開くのに非常に「核心ザラザラ」の詳細について興味があります。

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

私が尋ねる理由は、ユーザーがデータベースに格納されているメタデータに基づいてファイルをブラウズして検索できるアプリケーションがあるからです。ユーザーが提供したOpenボタンをクリックすると、ルートファイルが選択されたファイルへのパスであるプロセスが開始されます。また、これらのファイルはネットワーク共有上にあることに言及する価値があります。

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

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

アプリケーション内でSystem.Processを使用するのとは異なる方法でWindowsエクスプローラのアプリケーションとは何ですか?


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

//From within 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" 
} 

もう一つ。私はthis questionを見つけましたが、この質問には適用されません。私のアプリは単にPDFといくつかのエンジニアリング図面ファイルを開こうとしているだけです。それは管理者のアクセスを必要とすべきではありません。また、ほとんどのユーザーはこのメッセージを受け取ることはなく、ネットワーク上にログインしてブラウズすることで、ネットワーク上で既に自分自身を検証しているため、ユーザー認証は必要ないと考えています。

+0

PCレベルで失敗しているクライアント間に共通性はありますか?彼らは働いているOSとは異なるOSになっていますか? –

+0

それは難しいです。私たちのIT部門は、AD移行の前に大規模なWindows 7移行を行っていました。新しいユーザーアカウントが与えられ、PCアップグレードの準備ができているか、予定時間に近づいた多くのユーザーには、勝利7を与えられた新しいPCが与えられました。問題を抱えて最も話しているマネージャーは、 Windows XPの場合しかし、それは過去にこのPC上で常に彼のために働いていた - 彼はちょうど新しいADドメインの新しいアカウントを使用して使用開始された。彼の許可を三重にチェックしました。彼は場所を参照してこれらのファイルを開くことができますが、私のapplはできません。 – RLH

+0

PDFでのみ失敗しますか? Acrobatを使用していますか? Acrobatは.NETでうまく動作しません。単一の.exeファイルで、外部からは一度に1つのファイルしか開きません。それがアクティブな場合、時には応答しないこともあります。 .NETでビューをホストしようとすると、キーダウンイベントを食べるのが一番問題になります。 – Paparazzi

答えて

5

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

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

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

    }   
} 

ここでは、あらかじめ決められた場所からこのアプリケーションを実行することができます。 SysInternalsのProcMonアプリケーションを使用して、低レベルの呼び出しを観察できます。私のマシン上でProcMonによって生成されたcsvファイルのスナップショットがあります。私は、CSVの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" 
... 

フルバージョンがpastebinで提供されたファイルにのみ含まれるようにpathをフィルタを入れています。 csvファイルのすべての行は、低レベルの呼び出しに対応します。さらに、パス上の厳密なフィルタのために除外された他のfluffもあります。

6

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

あなたはこのようにそれを修正:

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

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

+0

'file'は完全修飾です。私はこの変更を行い、それを公開します。ありがとうございました! – RLH

+0

また、Windowsエクスプローラでファイルを起動すると、これが効果的に実行されますか? – RLH

+1

答えに明示的に記載されています: 'プログラムはデフォルトの作業ディレクトリを設定するエクスプローラに依存しています' –

2

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

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

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

Windows 7では、あなたは調べることができますし、>プログラム>既定のプログラム>設定組合コントロールパネルでファイルassocationsを変更します。 .PDF拡張機能に関連するプログラムが見つからない場合は、FileNotFoundExceptionが表示される可能性がありますが、確認していないと思います。

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

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

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); 
関連する問題