Гарантированный способ найти путь к ildasm.exe и ilasm.exe файлы независимо of.NET версия / окружающая среда?

есть ли способ программно получить FileInfo / Path ildasm.exe / ilasm.исполняемые файлы exe? Я пытаюсь декомпилировать и перекомпилировать файл dll / exe соответствующим образом после внесения в него некоторых изменений (я предполагаю, что PostSharp делает что-то подобное, чтобы изменить IL после компиляции).

Я нашел сообщение в блоге, которое указывало на:

var pfDir = Environment.GetFolderPath(Environment.SpecialFolders.ProgramFiles));
var sdkDir = Path.Combine(pfDir, @"Microsoft SDKsWindowsv6.0Abin");

...

однако, когда я запускал этот код, каталог не существовал (в основном потому, что моя версия SDK-7.1), поэтому на моем локальном машина правильный путь @"Microsoft SDKsWindowsv7.1bin". Как мне убедиться, что я действительно могу найти ildasm.exe?

аналогично, я нашел еще одно сообщение в блоге о том, как получить доступ к ilasm.exe как:

string windows = Environment.GetFolderPath(Environment.SpecialFolder.System);
string fwork = Path.Combine(windows, @"..Microsoft.NETFrameworkv2.0.50727");

...

пока это работает, я заметил, что у меня есть Framework и Framework64, и в самой структуре у меня есть все версии до v4.0.30319 (то же самое с Framework64). Итак, как я узнаю, какой из них использовать? Он должен быть основан на .Net версии я целеуказание?

резюме:

  • как я могу надлежащим образом гарантировать, чтобы найти правильный путь к ildasm.exe?
  • Как правильно выбрать правильный ilasm.exe для компиляции?

2 ответов


одним из вариантов было бы ссылаться Microsoft.Build.Utilities.Core и использовать:

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

сейчас на моей машине это возвращает:

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


недавно мне нужно было сделать это, поэтому я тралил паутины для всех возможных путей Windows SDK и просматривал их в самом последнем известном порядке. Я также проверяю, является ли ОС и процесс 64bit, а затем просто использовать эту версию, посмотрев в соответствующих папках Program Files. Я не думаю, что выбор 64-разрядной версии над 32-разрядными версиями инструментов имеет какое-либо большое значение. Версия x86 ILAsm может с радостью собирать 64-битные предпочтительные сборки без заминки, это все IL и фактически не выполняет какой-либо код.

ILDasm является частью Windows SDK, где ILAsm - это просто SDK .NET Framework, поэтому вот некоторые статические методы для их поиска. Код запечен для .NET 4.0, но вы можете сделать некоторые незначительные настройки, чтобы получить его на .NET 2.0, если хотите.

// 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;
}

вы можете увеличить это, передав исполняемый файл, который вы ищете, и изменить .Существует С .Существует также, до вы. Вы также можете взять возможные списки и поместить их в конфигурационный файл, чтобы добавить больше без перекомпиляции.