是否有用于检查最低.NET框架版本的工具?

时间:2012-03-24 22:52:01

标签: .net

我最近写了一个没有在某些PC上运行的C#应用​​程序。问题是我使用的方法只是在3.5 .NET框架的SP1版本中添加。

当调用该方法时,我会得到一个MethodNotFound异常,就像这个问题一样:Exception is occuring only on my machine: Method not found: WaitHandle.WaitOne(Int32)

我的问题:是否有一个工具可以检查我的代码(静态?),并告诉我我需要的.NET框架的最低版本(包括服务包)?

看起来它会很方便,虽然我不确定这有多常见。

2 个答案:

答案 0 :(得分:1)

当然,这里写的所有内容都是正确的,但原来的问题尚未得到解答。从理论上讲,您可以通过迭代代码自己编写这样的工具,看看是否找到了对此SP1中首先存在的方法的引用。这是一个使用Cecil来解析程序集的粗略示例:

namespace SampleNamespace
{
  using System;
  using Mono.Cecil;
  using Mono.Cecil.Cil;

  internal static class Program
  {
    public static void Main(string[] args)
    {
      foreach (string arg in args)
      {
        Console.WriteLine("{0}: {1}", arg, NeedsDotNet35SP1(arg));
        Console.ReadLine();
      }
    }

    private static bool NeedsDotNet35SP1(string fileName)
    {
      return NeedsDotNet35SP1(ModuleDefinition.ReadModule(fileName));
    }

    private static bool NeedsDotNet35SP1(ModuleDefinition module)
    {
      if (TargetRuntime.Net_2_0 != module.Runtime)
      {
        // I don't care about .NET 1.0, 1.1. or 4.0 for this example.
        return false;
      }

      foreach (TypeDefinition type in module.Types)
      {
        if (NeedsDotNet35SP1(type))
        {
          return true;
        }
      }

      return false;
    }

    private static bool NeedsDotNet35SP1(TypeDefinition type)
    {
      foreach (MethodDefinition method in type.Methods)
      {
        if (NeedsDotNet35SP1(method))
        {
          return true;
        }
      }

      return false;
    }

    private static bool NeedsDotNet35SP1(MethodDefinition method)
    {
      return NeedsDotNet35SP1(method.Body);
    }

    private static bool NeedsDotNet35SP1(MethodBody body)
    {
      foreach (Instruction instruction in body.Instructions)
      {
        if (NeedsDotNet35SP1(instruction))
        {
          return true;
        }
      }

      return false;
    }

    private static bool NeedsDotNet35SP1(Instruction instruction)
    {
      if (OperandType.InlineMethod != instruction.OpCode.OperandType)
      {
        return false;
      }

      return NeedsDotNet35SP1((MethodReference)instruction.Operand);
    }

    private static bool NeedsDotNet35SP1(MethodReference method)
    {
      return method.FullName.Equals(
        "System.Boolean System.Threading.WaitHandle::WaitOne(System.Int32)",
        StringComparison.OrdinalIgnoreCase);
    }
  }
}

显然,这个例子只考虑了一种方法,但是如果你真的需要,应该可以扩展它。 :)

答案 1 :(得分:0)

我不知道有任何工具可以识别代码需要工作的最低版本的框架。 但是,您可以使用requiredRuntime和supportedRuntime配置设置自行指定它,以声明应用程序需要或支持的框架版本。

加载应用程序时,CLR将引发错误并通知用户安装的版本是否不足以执行您的代码。