Guaranteed way to find the filepath of the ildasm.exe and ilasm.exe files regardless of .NET version/environment?

前端 未结 2 1543
生来不讨喜
生来不讨喜 2021-02-14 10:12

Is there a way to programmatically get the FileInfo/Path of the ildasm.exe/ilasm.exe executables? I\'m attempting to decompile and recompile a dll/exe file appropriately after m

相关标签:
2条回答
  • 2021-02-14 10:36

    One option would be to reference Microsoft.Build.Utilities.Core and use:

    var ildasm = Microsoft.Build.Utilities.ToolLocationHelper.GetPathToDotNetFrameworkSdkFile("ildasm.exe", TargetDotNetFrameworkVersion.VersionLatest);
    var ilasm = Microsoft.Build.Utilities.ToolLocationHelper.GetPathToDotNetFrameworkFile("ilasm.exe", TargetDotNetFrameworkVersion.VersionLatest);
    

    Right now on my machine this returns:

    ildasm = C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6 Tools\ildasm.exe

    ilasm = C:\Windows\Microsoft.NET\Framework\v4.0.30319\ilasm.exe

    0 讨论(0)
  • 2021-02-14 10:55

    I recently needed to do this so I trawled the interwebs for all the possible paths of the Windows SDK and search through those in most recent known order. I also check for whether the OS and process is 64bit and then just use that version by looking in the appropriate Program Files folders. I don't think choosing 64-bit over the 32-bit versions of the tools has any great significance. The x86 version of ILAsm can happily assemble 64-bit preferred assemblies without a hitch, it's all IL and not actually executing any of the code.

    ILDasm is part of the Windows SDK where ILAsm is just the .NET Framework SDK so here are some static methods to hunt them down with. The code is baked for .NET 4.0 but you could make some minor tweaks to get it building on .NET 2.0 if you want.

    // ILDasm.exe will be somewhere in here
    private static string FindPathForWindowsSdk()
    {
      string[] windowsSdkPaths = new[]
      {
        @"Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\",
        @"Microsoft SDKs\Windows\v8.0A\bin\",
        @"Microsoft SDKs\Windows\v8.0\bin\NETFX 4.0 Tools\",
        @"Microsoft SDKs\Windows\v8.0\bin\",
        @"Microsoft SDKs\Windows\v7.1A\bin\NETFX 4.0 Tools\",
        @"Microsoft SDKs\Windows\v7.1A\bin\",
        @"Microsoft SDKs\Windows\v7.0A\bin\NETFX 4.0 Tools\",
        @"Microsoft SDKs\Windows\v7.0A\bin\",
        @"Microsoft SDKs\Windows\v6.1A\bin\",        
        @"Microsoft SDKs\Windows\v6.0A\bin\",
        @"Microsoft SDKs\Windows\v6.0\bin\",
        @"Microsoft.NET\FrameworkSDK\bin"
      };
    
      foreach (var possiblePath in windowsSdkPaths)
      {
        string fullPath = string.Empty;
    
        // Check alternate program file paths as well as 64-bit versions.
        if (Environment.Is64BitProcess)
        {
          fullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), possiblePath, "x64");
          if (Directory.Exists(fullPath))
          {
            return fullPath;
          }
    
          fullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), possiblePath, "x64");
          if (Directory.Exists(fullPath))
          {
            return fullPath;
          }
        }
    
        fullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), possiblePath);
        if (Directory.Exists(fullPath))
        {
          return fullPath;
        }
    
        fullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), possiblePath);
        if (Directory.Exists(fullPath))
        {
          return fullPath;
        }
      }
    
      return null;
    }
    
    // ILAsm.exe will be somewhere in here
    private static string FindPathForDotNetFramework()
    {
      string[] frameworkPaths = new[]
      {
        @"Microsoft.NET\Framework\v4.0.30319",
        @"Microsoft.NET\Framework\v2.0.50727"
      };
    
      foreach (var possiblePath in frameworkPaths)
      {
        string fullPath = string.Empty;
    
        if (Environment.Is64BitProcess)
        {
          fullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), possiblePath.Replace(@"\Framework\", @"\Framework64\"));
          if (Directory.Exists(fullPath))
          {
            return fullPath;
          }
        }
    
        fullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), possiblePath);
        if (Directory.Exists(fullPath))
        {
          return fullPath;
        }
      }
    
      return null;
    }
    

    You can augment this by passing in the executable you are looking for and change Directory.Exists with File.Exists as well, up to you. You could also take the possible lists and put them in a config file so you can add more without recompiling.

    0 讨论(0)
提交回复
热议问题