2012-04-02 81 views
1

我有一个dll使用.Net2.0的regasm进行了很好的注册,但是当尝试使用.NET4.0 regasm进行注册时,出现错误“无法加载文件或组装 'FILENAMEHERE' 或它的一个依赖关系,不支持操作(从HRESULT异常:。0x8013515 代码和汇编如下RegAsm dll .net2.0到.net4.0

STARTelnet.cs

/** 
*Steven T. Norris  Created: 3/27/2012 
*Last Updated By: Steven T. Norris  Last Updated On: 3/27/2012 
* 
*/ 

using System; 
using MinimalisticTelnet; 
using System.Net.Sockets; 

/** 
* @brief Used to connect to, read, and respond to a STAR terminal session. 
* 
* Steven T. Norris  Created: 3/27/2012 
*/ 
namespace STARTelnet 
{ 
    /** 
    * Class used to connect to, read, and respond to a STAR terminal session. 
    */ 
    public class STARConnection 
    { 
     private TelnetConnection conn; 
     private string output; 
     private string command; 
     private string prompt; 

     /** 
     * Instantiates new STARConnection. <br/> 
     * Recommended login timeout is 2000. <br/> 
     * Recommended overall timeout is 500. <br/> 
     * Throws SocketException, PromptException, LoginException 
     * 
     * @param [in] string username:Username for login 
     * @param [in] string password:Password for login 
     * @param [in] int loginTimeout:timeout milliseconds for login 
     * @param [in] int overallTimeout:timeout milliseconds for session 
     */ 
     public STARConnection(string username, string password, int loginTimeout, int overallTimeout) 
     { 
      output = ""; 
      conn = new TelnetConnection("HOSTHOSTHOST", 23); 
      this.SetTimeout(overallTimeout); 
      try 
      { 
       output = conn.Login(username, password, loginTimeout); 
       if(output.Contains("You entered an invalid login name or password")) 
       { 
        throw new LoginException("Failed to login"); 
       } 
       this.ParsePrompt(); 
      } 
      catch(Exception e) 
      { 
       if(e.Message.Contains("login prompt")) 
       { 
        throw new PromptException("Login", "Could not find login prompt"); 
       } 
       else if(e.Message.Contains("password prompt")) 
       { 
        throw new PromptException("Password", "Could not find password prompt"); 
       } 
       else 
       { 
        throw e; 
       } 
      } 
     } 

     /** 
     * Sets the timeout for the session in milliseconds 
     * @param [in] int timeout:timeout for session 
     */ 
     public void SetTimeout(int timeout) 
     { 
      conn.MainTimeOutMs = timeout; 
      conn.TimeOutMs = timeout; 
     } 

     /** 
     * Gets the current timeout for the session in milliseconds 
     * @param [out] int:timout for session 
     */ 
     public int GetTimeout() 
     { 
      return conn.TimeOutMs; 
     } 

     /** 
     * Writes a command to the STAR session 
     * @param [in] string command:command to write 
     */ 
     public void Write(string command) 
     { 
      this.command = command; 
      conn.Write(this.command); 
      this.command = this.command.Replace("\n", "{newLine}"); 
     } 


     /** 
     * Writes a command followed by a new line (\n) to the STAR session 
     * @param [in] string command:command to write 
     */ 
     public void WriteLine(string command) 
     { 
      this.command = command; 
      conn.WriteLine(this.command); 
      this.command += "{newLine}"; 
     } 

     /** 
     * Reads output from STAR session. Assumes no data within given timeout denotes end of stream 
     * @param [out] string:output from STAR session 
     */ 
     public string Read() 
     { 
      output = conn.Read(); 
      this.ParsePrompt(); 
      return output; 
     } 

     /** 
     * Reads output from STAR session with timeout changed for only this read. Assumes no data within 
     * timeout denotes end of stream. 
     * @param [in] int timeout:timeout for this read only 
     * @param [out] string:output from STAR session 
     */ 
     public string Read(int timeout) 
     { 
      int temp = this.GetTimeout(); 
      this.SetTimeout(timeout); 
      this.Read(); 
      this.SetTimeout(temp); 
      return output; 
     } 

     /* 
     * Parse prompt from output 
     */ 
     private void ParsePrompt() 
     { 
      prompt = output.Substring(output.LastIndexOf("\n") + 1); 
     } 

     /** 
     * Gets output from last read 
     * @param [out] string:output from last read 
     */ 
     public string GetOutput() 
     { 
      return output; 
     } 

     /** 
     * Gets last command entered 
     * @param [out] string:last command entered 
     */ 
     public string GetCommand() 
     { 
      return command; 
     } 

     /** 
     * Gets prompt from last read 
     * @param [out] string:last prompt 
     */ 
     public string GetPrompt() 
     { 
      return prompt; 
     } 

     /** 
     * Checks for connection 
     * @param [out] bool:connection status 
     */ 
     public bool IsConnected() 
     { 
      return conn.IsConnected; 
     } 
    } 

    /** 
    * Exception for failed logins 
    */ 
    class LoginException: Exception 
    { 

     private string offender = ""; 
     public LoginException() : base() { } 
     public LoginException(string message) : base(message) { } 

     /** 
     * Creates exception 
     * @param string offender:element causing exception 
     * @param string message:exception message 
     */ 
     public LoginException(string offender, string message) 
      : base(message) 
     { 
      this.offender = offender; 
     } 

     /** 
     * To String method for getting exception string 
     * @param [out] string:string representation of exception 
     */ 
     public override string ToString() 
     { 
      if(offender == "") 
      { 
       return this.GetType() + ": "+this.Message+"\n"+this.StackTrace; 
      } 
      else 
      { 
       return "Incorrect login: " + offender + "--" + this.Message + "\n" + this.StackTrace; 
      } 
     } 
    } 

    /** 
    * Exception for failed STAR prompts 
    */ 
    class PromptException: Exception 
    { 

     private string prompt = ""; 
     public PromptException() : base(){ } 
     public PromptException(string message) : base(message){ } 

     /** 
     * Creates exeption 
     * @param string prompt:prompt causing exception 
     * @param string message:exception message 
     */ 
     public PromptException(string prompt, string message) 
      : base(message) 
     { 
      this.prompt = prompt; 
     } 

     /** 
     * To String method for getting exception string 
     * @param [out] string:string representation of exception 
     */ 
     public override string ToString() 
     { 
      if(prompt == "") 
      { 
       return this.GetType() + ": " + this.Message + "\n" + this.StackTrace; 
      } 
      else 
      { 
       return "Prompt failed: " + prompt + "--" + this.Message + "\n" + this.StackTrace; 
      } 
     } 

    } 
} 

的AssemblyInfo.cs

using System.Reflection; 
using System.Runtime.CompilerServices; 
using System.Runtime.InteropServices; 

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information 
// associated with an assembly. 
[assembly: AssemblyTitle("STARTelnet")] 
[assembly: AssemblyDescription("")] 
[assembly: AssemblyConfiguration("")] 
[assembly: AssemblyCompany("COMPANY")] 
[assembly: AssemblyProduct("STARTelnet")] 
[assembly: AssemblyCopyright("Copyright © COMPANY 2012")] 
[assembly: AssemblyTrademark("")] 
[assembly: AssemblyCulture("")] 

// Setting ComVisible to false makes the types in this assembly not visible 
// to COM components. If you need to access a type in this assembly from 
// COM, set the ComVisible attribute to true on that type. 
[assembly: ComVisible(true)] 

// The following GUID is for the ID of the typelib if this project is exposed to COM 
[assembly: Guid("d7ae512d-c840-4ebc-8057-73a10f286225")] 

// Version information for an assembly consists of the following four values: 
// 
//  Major Version 
//  Minor Version 
//  Build Number 
//  Revision 
// 
// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below: 
// [assembly: AssemblyVersion("1.0.*")] 
[assembly: AssemblyVersion("1.0.0.0")] 
[assembly: AssemblyFileVersion("1.0.0.0")] 
+0

不要混淆错误消息,HEXVALUEHERE不能帮助我们帮助你。当您实际上已将项目更改为以.NET 4为目标时,才使用版本4 Regasm。 – 2012-04-02 14:27:31

+0

该项目不能更改为.NET 4.它必须是.NET 2.0的兼容性问题。我的印象是.NET向后兼容。我已经调整了上面的十六进制代码。 – steventnorris 2012-04-02 14:30:49

+0

那么你为什么要注册版本4 Regasm而不是使用版本2? – 2012-04-02 14:32:53

回答

2

有些特殊的规则适用于像你这样的COM服务器。 .NET 4中的CLR支持CLR的进程内并行版本控制,允许进程托管多个版本的CLR。这对COM服务器来说尤其重要,它解决了以前无法可靠地创建托管外壳扩展的CLR版本注入问题。 CLR版本2和更早版本仅支持一个流程中的CLR版本。由于无论COM服务器首先加载CLR的副作用,都会导致以后无法加载需要更高版本CLR的COM服务器。特别是如果第一个COM服务器加载了CLR的1.0或1.1版本的话,那就太糟糕了。

如果您不想以.NET 4为目标,那么您将不得不要求用户安装.NET 3.5 SP1,以便服务器可以注册。您还必须为客户端程序提供一个app.exe.config文件,以告诉CLR您知道您的COM服务器是为较早版本的CLR而构建的,并且可以使用版本4 CLR运行它。这可以防止使用版本2 CLR。 .config文件应该是这样的:

<configuration> 
    <startup useLegacyV2RuntimeActivationPolicy="true"> 
     <supportedRuntime version="v4"/> 
     <supportedRuntime version="v2.0.50727"/> 
    </startup> 
</configuration> 

显然你会通过为只有4和DO记住,你实际上可能更喜欢得到第2版的CLR加载用户针对.NET 4提前如果客户端程序完全是本地的,那么这可能是你测试过代码的版本。第4版是高度兼容的,但它确实有一些错误修复,可以防止代码无意中依赖的错误。

+0

我在哪里可以找到/编辑app.exe.config文件以便分发给用户PC,以及如何将其与RegAsm绑定?我假设这是在“框架”目录中的某个地方?用户将通过RegAsm在他们的本地PC上使用他们的终端窗口注册这个DLL。 – steventnorris 2012-04-02 16:02:00

+0

你必须创建它。 Notepad.exe将会很好。它必须使用客户端程序的名称存储在包含* client *应用程序EXE的目录中。因此,如果c:\ foo \ bar.exe使用您的COM服务器,那么您必须创建c:\ foo \ bar.exe.config – 2012-04-02 16:07:05

+0

您是什么意思使用我的COM服务器?这些都是在单个用户PC上本地运行的。 – steventnorris 2012-04-02 17:07:45