これは少しトリッキーなので、我慢してください...
私は簡単な小さな方法を持っています:
Public Overloads Shared Function DoStuff(ByVal path As String) As Boolean
If Not IO.File.Exists(ipath) Then Throw New ArgumentException
Dim result As Boolean
Using fs As FileStream = New FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)
' do stuff here, details are not important
fs.Close()
End Using
Return result
End Function
メソッドがストリームの使用方法を示していないことを理解していますが、以下で説明するように詳細は関係ありません。
このメソッドは、クラス ライブラリにぴったりと収まっています。他のさまざまなプロジェクトで参照するヘルパー。明らかに、ほとんどのコードは、パスが有効であり、アクセス可能であるなどの前提で問題なく見えるはずです。
さて本題。ヘルパーアセンブリで前述のメソッドを参照および使用する WCF サービス ライブラリがあります。WCF サービス ライブラリは Windows サービス内でホストされており、これはサーバーの 1 つに常駐しています。WCF サービスには、ファイルの UNC パスを受け取る操作があり、通常のフローでは、ヘルパー クラスで上記のメソッドを呼び出します。
私が送信するパスは、ネットワーク上の共有上のファイル用です。「Using fs As...」という行は、次の例外で失敗します。
System.UnauthorizedAccessException: パス ' my file path is listed here ' へのアクセスが拒否されました。System.IO.__Error.WinIOError (Int32 errorCode、文字列の多分フルパス) で System.IO.FileStream.Init (文字列パス、FileMode モード、FileAccess アクセス、Int32 権限、ブール値の useRights、FileShare 共有、Int32 bufferSize、FileOptions オプション、SECURITY_ATTRIBUTES secAttrs 、System.IO.FileStream..ctor(文字列パス、FileMode モード、FileAccess アクセス、FileShare 共有、Int32 bufferSize、FileOptions オプション、文字列 msgPath、ブール bFromProxy) の文字列 msgPath、ブール値の bFromProxy、ブール値の useLongPath) ..ctor(String パス、FileMode モード) at MyHelperAssemblyName.DoStuff(String filePath)残りの例外は、メソッド、アセンブリ、wcf サービスなどを指すスタック トレースです。 "
さて、私が問題を診断しようとしたことのリスト(ばかばかしいほど明白な手順を含む):
スタック トレースにリストされているパスを Windows エクスプローラー (ローカル マシンとサーバーの両方) にコピー アンド ペーストして、ファイルが存在し、アクセス可能であることを確認します -->ファイルにアクセスできます
Windows サービスのアカウントがファイルを読み取るための十分なアクセス許可を持っていることを確認します --> [有効なアクセス許可] には、サービスのアカウントがフル コントロールとしてリストされます。
個人の管理者アカウントを使用するように Windows サービスのアカウントを変更し (一時的な措置)、明らかにサービスを再起動して変更を有効にする -->同じコード行が失敗する
ファイルを含むディレクトリをローカル マシンにコピーし、ローカル マシンに対してサービスを実行します (ファイルをホストする NAS が原因ではないことを確認したかったのです) -->同じコード行が失敗します
簡単なコンソール アプリケーションを作成し、ヘルパー アセンブリのメソッドからアプリケーションにコードをコピーして貼り付け、同じファイル パスを挿入し、ローカルで実行してからサーバーで実行します (サーバー上とは、同じ管理者を使用してサーバーにリモート接続することを意味します)。前述のアカウントを作成して実行します) -->アプリケーションは問題なくコードを実行できます
コンソール アプリケーションを作成し、コンソール アプリケーション内で WCF サービス ライブラリをホストする一括標準方法を使用します。アプリケーションをローカルで実行し、コンソール アプリのベース アドレスとして指定したローカル アドレスに対してWcfStormを使用して、通常のサービスが失敗するのと同じパスで同じメソッドを呼び出します --> WcfStorm からの結果は、コードが問題はありませんでした
WCF サービス ライブラリのコードを再確認して、テストに影響を与える固有の条件付きロジックがないことを確認します -->ヘルパー メソッドは、サービス操作の実装が開始された直後 (引数の検証の直後) に呼び出されます。ヘルパー メソッドを実行せずに操作で一貫した結果を返すことはできないため、以前に一貫した結果を受け取っていて、「奇妙な」ファイル アクセス コードが実行されたと想定していたときに、実際には実行されていました。
Windows サービス ホスト、WCF サービス ライブラリ、およびヘルパー アセンブリをクリーンにリビルドしてサービスを再展開しました (画面上のコードがサーバー上で実行されていたコードと同じであることを確認したかったため) -->変更なし
EDIT 2011-06-24 16:32GMT - 以前に作成したコンソール アプリを使用して WCF サービスをホストし、それに応じて baseAddress を調整し、サーバーに展開します。上記と同じ管理者アカウントを使用してアプリを実行します。WcfStorm を使用して、新しいベース アドレスで新しいアプリをテストします。-->コードは期待どおりに動作し、良好な結果を返します (この段階では、Windows サービスの障害に絞り込むことができると思いますか?)
EDIT 2011-06-27 10:21GMT - ヘルパー クラスを参照する単純な Windows サービスを作成しました。サーバーにインストールされ、サービスのアカウントはライブ サーバーと同じに設定されます。-->新しいサービスはコードを実行し、ファイルにアクセスできました
EDIT 2011-06-27 10:23GMT - サービスが機能していたことに腹を立て、週末に実行したままにしていた WcfStorm を開きました。結果は、ライブ サービスが失敗したことを示す金曜日から表示された静止画でした。同じリクエストを再送します -->うまくいきました...問題を追跡する実際の手段がないため、実際にはもっとイライラしています
したがって、サービスは今のところ正しく機能しています。このような断続的な失敗の原因は何ですか? 同僚は、週末に何も変更されていないことを保証しています(少なくとも手動ではありません)。困惑...