2012-03-29 12 views
3

新しいファイルを作成するための特定のフォルダをポーリングするWindowsサービスがあります。これは、フォルダがC:やDなどのローカルドライブのいずれかにある場合に問題なく動作します。 サービスは、マップされたドライブ上のフォルダを見つけることができません。ここでC#で書かれたWindowsサービスからマップされたフォルダにアクセスする

はフォルダをチェックするんコードで、ポーリングの前に存在します。

System.Security.Principal.WindowsIdentity userIdentity = 
      System.Security.Principal.WindowsIdentity.GetCurrent(); 
      System.Security.Principal.WindowsPrincipal principal = 
       new System.Security.Principal.WindowsPrincipal(userIdentity); 

      MappedDriveResolver mdr = new MappedDriveResolver(); 
      if (mdr.isNetworkDrive(folderPath)) 
      { 
       LoggingAppWrapper.LogDeveloperMessage(folderPath + " is on a Mapped drive", 1, TraceEventType.Information, string.Empty); 

      } 

MappedDriveResolverは、単純なコンソールアプリケーションから正常に動作しているリンクで、私はここにHow do I determine a mapped drive's actual path?

を発見したクラスのコードです、それがWindowsサービスの一部であるときに失敗します。 Windowsサービスでコードを動作させるために何をすべきかに関する提案はありますか?

よろしくお願いいたします。

+0

サービスが実行されているアカウントに適切な権限があることは確かですか? – kpcrash

+0

私はこの答えはあなたを助けると思う:http://stackoverflow.com:[1] を[スレッドの回答は、 "サービスが使用するネットワークドライブをマップ"] [1] /a/4763324/3860297 – sekerg

答えて

4

サービスを実行しているサーバー上にないフォルダに対してUNCパスを使用するようにサービスを構成することをお勧めします。

マップされたドライブは、ユーザーのユーザビリティ機能であり、ユーザープロファイル/環境に固有のものです。つまり、ログインするとドライブXがあります:\\ server1 \ share1にマップされますが、ドライブXにログインすると、\\ server2 \ share2にマップすることができます。実際のマッピングプロセスは、「ログオン時に再接続」を使用してプロファイルの一部として保存されるか、ログオンスクリプトによって処理されます。

サービスが実行されているアカウントを確認し、そのユーザー環境に対応するマップされたドライブが存在することを確認する必要があります(How to map a network drive to be used by a serviceが役に立ちます)。

編集:

理由あなたのコンソールアプリケーションの機能とサービスがされているため、それらが実行されている環境との違いのない

このコンソールアプリケーションを取り、これを説明するために、それをコンパイルしてからスケジュールタスクとして実行します。 「パス」変数を​​、ユーザーがアクセスできるマップされたドライブに設定します。

static void Main(string[] args) { 
     MappedDriveResolver mdr = new MappedDriveResolver(); 
     string logfile; 
     string path = @"I:\"; 
     string[] files; 

     // Write out "log" file to where this is running from 
     logfile = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location); 
     logfile = Path.Combine(logfile, "log.txt"); 

     using (StreamWriter sw = new StreamWriter(logfile, true)) { 

      try { 
       sw.WriteLine("Checking path " + path); 
       if (mdr.isNetworkDrive(path)) { 
        sw.WriteLine("Network Drive: Yes"); 
       } else { 
        sw.WriteLine("Network Drive: No"); 
       } 
      } catch (Exception ex) { 
       sw.WriteLine("Exception: " + ex.Message); 
      } 

      try { 
       sw.WriteLine("Resolve path " + path); 
       string newpath = mdr.ResolveToUNC(path); 
       sw.WriteLine("Resolved path " + newpath); 
      } catch (Exception ex) { 
       sw.WriteLine("Exception: " + ex.Message); 
      } 

      try { 
       sw.WriteLine("Get file list from " + path); 
       files = Directory.GetFiles(path); 
       if (files == null || files.Length == 0) { 
        sw.WriteLine("No files found"); 
       } else { 
        sw.WriteLine(string.Format("Found {0} files.", files.Length)); 
       } 
      } catch (Exception ex) { 
       sw.WriteLine("Exception: " + ex.Message); 
      } 

      sw.Flush(); 
      sw.Close(); 
     } 
    } 

注:ちょうどそれをダブルクリックしてアプリケーションを実行します。これは、Windows 7のタスクスケジューラ

テスト1です。
結果:成功

テスト2:成功

テスト3:
結果を設定し、スケジュールを使用してユーザーアカウントとして実行するタスク「ユーザーがログオンしている場合にのみ実行してください」として実行するように設定し、スケジュールされたタスクあなたユーザーがログオンしているかどうかにかかわらず実行するユーザーアカウント
結果:例外

テスト4:「ローカルサービス」アカウントとして実行するスケジュールタスクを構成します。
結果:例外

テスト1 & 2作品を、彼らは現在、それの一部であるマッピングされたドライブを含むユーザー環境にログインして使用しているため。

テスト3 & 4マップされたドライブが構成されていない独自のユーザー環境が作成されているため、テストに失敗します。相違点は現時点では逃げ出しますが、「対話型」と「非対話型」環境はいくつかの重要な点で異なります。

+0

Ok ...私はそれを得る...しかし、なぜコードはコンソールアプリケーションからは動作しますが、サービスからは動作しませんか? – Codehelp

+0

私はここでいくつかの良い情報を見つけました[http://stackoverflow.com/questions/4396634/how-can-i-determine-if-a-given-drive-letter-is-a-local-mapped-usb-drive] ...もう一度これは、コンソールアプリケーションからうまく動作しますが、サービスを通じて失敗します! – Codehelp

+0

@ Codehelpうまくいけば説明とテスト方法を追加しました。 – Vermis

関連する問題