Можно ли определить, на каком языке сборка .NET была написана ex post facto?

Это началось как способ найти сборки С++/CLI и Managed С++, чтобы все классы, внутренние для них, могли быть протестированы, чтобы обеспечить повторное выполнение всех унаследованных методов. Я хотел бы добавить это как шаг процесса сборки, чтобы гарантировать, что это никогда не повторится.

Размышление об этой проблеме также сделало меня немного любопытным, поскольку было бы интересно уметь определять любой используемый язык .NET. Из-за этого я пошел немного дальше и сравнил сборки со всех языков .NET. Пока что я нашел через небольшую программу, которую я написал, которая сравнивает данные типа и атрибута с любым набором .NET-сборок через отражение:

  • С# - имеет атрибут AssemblyConfigurationAttribute, имеет GuidAttribute
  • VB - имеет много дополнительных типов "Мой" (например, MyApplication, MySettings), имеет GuidAttibute
  • F # - имеет FSharpInterfaceDataVersionAttribute, который также указывает версию используемого компилятора.
  • С++ (все, кроме /clr: safe) - содержит множество дополнительных типов (FrameInfo, type_info)
  • С++/clr: safe - Кажется, нет уникальных функций отражения.

Возможно, было бы разумно разобрать в этом порядке:

  • Это F #, если у него есть FSharpInterfaceDataVersionAttribute
  • Это С++, если он есть в огромном наборе дополнительных типов, которые я нашел.
  • Это VB, если у него есть типы "My *".
  • Это С#, если у него есть AssemblyConfigurationAttribute или GuidAttribute
  • Вероятно, это С++/clr: Safe

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

Ответ 1

Проверка ссылок на такие вещи, как библиотеки классов VB или F #, по-видимому, является наименее шатким способом сделать это, но, как говорят другие, это эвристика - точно так же, как нет окончательного способа определить, на каком языке написан собственный бинарный файл в (но вы можете быть почти на 100% уверены в эвристике)

Ответ 2

Когда язык .NET компилируется, все, что вы получаете, это IL. Я не знаю стандартного способа определения того, какой конкретный язык создал сборку. Вы можете взять существующую сборку и ildasm (разобрать) ее в IL и их ilasm (собрать) обратно в практически идентичную сборку.

Эвристика, которую вы используете, является разумным и умным способом определения языка, используемого для создания сборки. Однако имейте в виду, что эти детали могут меняться между версиями языков компилятора.