2014-03-12 61 views
0

我正在編寫可作爲控制檯應用程序或服務運行的C#代碼。當作爲控制檯應用程序運行時,它工作正常。當作爲服務運行時,我收到了一個奇怪的錯誤。服務報告'找不到指定的文件'存在的文件

啓動時,我的服務產生一個線程,此線程搜索目錄中的插件.dll,它們實現了某些服務的功能。我枚舉插件目錄中的文件,然後爲每個找到的文件嘗試加載程序集並確定它是否實現了所需的接口。

這種架構描述如下:http://code.msdn.microsoft.com/windowsdesktop/Creating-a-simple-plugin-b6174b62

我發現我可以列舉所有的插件,但是當我打電話Assembly.GetTypes(),我得到與消息LoaderException:「無法加載文件或程序集「MyProject,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null」或它的某個依賴項,系統找不到指定的文件。

嗯,這是雙層因爲在代碼只是這一次前行,該文件是從到Directory.GetFiles調用枚舉(路徑,「* .dll文件」)。請記住,此代碼在以控制檯應用程序運行時也可以找到。

我的服務以本地系統運行,SYSTEM帳戶對文件具有完全權限,管理員也是如此。根據this page,本地系統的令牌包括NT AUTHORITY \ SYSTEM和BUILTIN \ Administrators SID,所以我不認爲這是文件系統權限問題。

我正在失望。任何人都可以提出一個原因和解決方案?

下面的代碼(它看起來長,但它的很多是記錄):

private void LoadPlugins() 
    { 
     lstPlugins = new List<MyDesiredInterface>(); 
     string path = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); 
     path += "\\PlugIns"; 
     if (Directory.Exists(path)) 
     { 
      Log("PlugIns folder exists.", TAG); 
      string[] dllFileNames = Directory.GetFiles(path, "*.dll"); 
      ICollection<Assembly> assemblies = new List<Assembly>(dllFileNames.Length); 
      foreach (string dllFile in dllFileNames) 
      { 
       AssemblyName an = AssemblyName.GetAssemblyName(dllFile); 
       Assembly assembly = Assembly.Load(an); 
       assemblies.Add(assembly); 
      } 

      Log("Found " + assemblies.Count + " assemblies.", TAG); 

      Type pluginType = typeof(MyDesiredInterface); 
      ICollection<Type> pluginTypes = new List<Type>(); 
      foreach (Assembly assembly in assemblies) 
      { 
       if (assembly != null) 
       { 
        Log("Evaluating assembly: " + assembly.Location, TAG); 
        try 
        { 
         Type[] types = assembly.GetTypes(); <-- error happens here 
         foreach (Type type in types) 
         { 
          if (type.IsInterface || type.IsAbstract) 
          { 
           Log("Assembly does not implement our interface.", TAG); 
           continue; 
          } 
          else 
          { 
           if (type.GetInterface(pluginType.FullName) != null) 
           { 
            Log("Assembly implements our interface!", TAG); 
            pluginTypes.Add(type); 
           } 
          } 
         } 
        } 
        catch (ReflectionTypeLoadException ex) 
        { 
         StringBuilder errMsg = new StringBuilder("An exception occurred tying to load types in an assembly.\r\n"); 
         errMsg.Append("The assembly is: " + assembly.Location + "\r\n"); 
         errMsg.Append("Exceptions are:\r\n"); 
         foreach (Exception e in ex.LoaderExceptions) 
         { 
          errMsg.Append(e.Message + "\r\n"); 
         } 
         Log(errMsg.ToString(), TAG); 
        } 
       } 
      } 


      foreach (Type type in pluginTypes) 
      { 
       MyDesiredInterface plugin = (MyDesiredInterface)Activator.CreateInstance(type); 
       this.Log("Loading plugin: " + plugin.CommandName(), TAG); 
       plugin.Register(this); 
       lstPlugins.Add(plugin); 
      } 
      this.Log("Total plugins loaded: " + lstPlugins.Count, TAG); 
     } 
     else 
     { 
      Log("PlugIns folder not found.", TAG); 
     } 
    } 

這裏的日誌文件:

3/12/2014 9:53:46 AM chatInterface LoadPlugIns() 
3/12/2014 9:53:46 AM chatInterface PlugIns folder exists. 
3/12/2014 9:53:46 AM chatInterface Found 13 assemblies. 
3/12/2014 9:53:46 AM chatInterface Evaluating assembly: C:\Users\MyUsername\Documents\Visual Studio 2010\Projects\MyProject\MyProjectService\bin\Debug\PlugIns\PlugIn1.dll 
3/12/2014 9:53:46 AM chatInterface An exception occurred tying to load types in an assembly. 
The assembly is: C:\Users\MyUsername\Documents\Visual Studio 2010\Projects\MyProject\MyProjectService\bin\Debug\PlugIns\PlugIn1.dll 
Exceptions are: 
Could not load file or assembly 'MyProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified. 

3/12/2014 9:53:46 AM chatInterface Evaluating assembly: C:\Users\MyUsername\Documents\Visual Studio 2010\Projects\MyProject\MyProjectService\bin\Debug\PlugIns\PlugIn2.dll 
3/12/2014 9:53:46 AM chatInterface An exception occurred tying to load types in an assembly. 
The assembly is: C:\Users\MyUsername\Documents\Visual Studio 2010\Projects\MyProject\MyProjectService\bin\Debug\PlugIns\PlugIn2.dll 
Exceptions are: 
Could not load file or assembly 'MyProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified. 

有人建議我用集綁定日誌查看器(fuslogvw.exe)記錄失敗。下面是該日誌顯示:

*** Assembly Binder Log Entry (3/13/2014 @ 9:50:30 AM) *** 

The operation was successful. 
Bind result: hr = 0x0. The operation completed successfully. 

Assembly manager loaded from: C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll 
Running under executable C:\Users\MyUsername\Documents\Visual Studio 2010\Projects\MyProject\MyProjectService\bin\Debug\MyProjectService.exe 
--- A detailed error log follows. 

=== Pre-bind state information === 
LOG: User = NT AUTHORITY\SYSTEM 
LOG: Where-ref bind. Location = C:\Users\MyUsername\Documents\Visual Studio 2010\Projects\MyProject\MyProjectService\bin\Debug\PlugIns\MyPlugIn.dll 
LOG: Appbase = file:///C:/Users/MyUsername/Documents/Visual Studio 2010/Projects/MyProject/MyProjectService/bin/Debug/ 
LOG: Initial PrivatePath = NULL 
LOG: Dynamic Base = NULL 
LOG: Cache Base = NULL 
LOG: AppName = NULL 
Calling assembly : (Unknown). 
=== 
LOG: This bind starts in LoadFrom load context. 
WRN: Native image will not be probed in LoadFrom context. Native image will only be probed in default load context, like with Assembly.Load(). 
LOG: No application configuration file found. 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v2.0.50727\config\machine.config. 
LOG: Attempting download of new URL file:///C:/Users/MyUsername/Documents/Visual Studio 2010/Projects/MyProject/MyProjectService/bin/Debug/PlugIns/MyPlugIn.dll. 
LOG: Assembly download was successful. Attempting setup of file: C:\Users\MyUsername\Documents\Visual Studio 2010\Projects\MyProject\MyProjectService\bin\Debug\PlugIns\MyPlugIn.dll 
LOG: Entering run-from-source setup phase. 
LOG: Assembly Name is: MyPlugIn, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 
LOG: Re-apply policy for where-ref bind. 
LOG: Binding succeeds. Returns assembly from C:\Users\MyUsername\Documents\Visual Studio 2010\Projects\MyProject\MyProjectService\bin\Debug\PlugIns\MyPlugIn.dll. 
LOG: Assembly is loaded in LoadFrom load context. 

在這個測試中來看,我使用Assembly.LoadFrom()而不是Assembly.Load(),但在這兩種情況下,裝配負荷。這個日誌顯示它在LoadFrom加載上下文中,我有其他的運行,顯示它在Load load上下文與另一個調用。在任何情況下,加載成功,但嘗試枚舉GetTypes將失敗,並顯示「系統找不到指定的文件」。

任何幫助,將不勝感激!

回答

0

請檢查您是否引用一個組件,它反過來引用的是舊版本。刪除,重建和重新引用可能有所幫助。

FuseLogVw」有助於找到誰是加載程序集,定義日誌路徑,並運行您的解決方案,然後選中第一行FuseLogVw

+0

感謝,CodeMad。日誌查看器沒有顯示任何故障。 –

0

http://msdn.microsoft.com/en-us/library/ky3942xh(v=vs.110).aspx

「FileLoadException是,如果assemblyString拋出指定完整集名稱,相匹配的簡單的名稱有不同的版本,區域性或公鑰標記的第一組件,加載程序不會繼續探索的匹配簡單的名字,其他組件。「

那麼,本屆大會的有多個版本?

+0

謝謝!這是很有必要知道,但沒有,該目錄只有1每個文件的版本。 –

相關問題