如何检测哪种.NET语言正在调用我的代码 [英] How to detect which .NET language is calling my code

查看:68
本文介绍了如何检测哪种.NET语言正在调用我的代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个生成用户代理字符串的库,该字符串报告一些漂亮的数据,例如OS版本和当前安装的.NET Framework版本。我很好奇:

I'm building a library that generates a user-agent string that reports some nifty data like OS version and currently installed .NET Framework versions. I'm curious:

是否可以通过编程方式检测到正在调用我的图书馆的语言?还是将源语言编译为CIL后完全不透明?

Is it possible to detect programmatically which language is calling my library? Or is the source language completely opaque once it's compiled into CIL?

推荐答案

编辑:放入小型库中,该库封装了一些启发式方法,并且易于调用。

Edit: I turned this into a small library that encapsulates a few heuristics and makes it easy to call.

我想出了一种启发式方法,似乎可以很好地满足我自己的需求。

I came up with a heuristic that seems to work well enough for my own needs.

@Don的回答,这些问题使给我一些提示:

@Don's answer and these questions gave me some hints:

  • Decompiled DLL - Clues to help tell whether it was C# or VB.NET?
  • Decompiling VB.Net assembly produces code with invalid member variable names; names starting with $STATIC$

注意事项


  • 仅区分VB.NET和C#,不区分其他CLR语言。假设C#没有足够的VB证据。

  • 这是有根据的猜测,因此误报的可能性大于0。

  • 某些提示是基于编译器实现的详细信息,可能会更改。

  • 这似乎也适用于Mono,但是YMMV。

  • 昂贵的反射,因此在现实生活中,您希望将其包装在 Lazy<> 或其他某种机制中,以确保仅调用一次。

  • 如@HABO所述,这可能是非常有用的信息,也可能不是。我主要是想知道是否可以这样做。

  • Only differentiates between VB.NET and C#, not any other CLR languages. Assumes C# if it doesn't have enough evidence of VB.
  • It's making an educated guess, so the chance of false positives is > 0.
  • Some of the hints are based on compiler implementation details, which could change.
  • This seems to work on Mono too, but YMMV.
  • It's expensive reflection, so in real life you'd want to wrap it in a Lazy<> or some other mechanism to ensure it's only called once.
  • As @HABO mentioned, this may or may not be very useful information. I was mostly curious to see if it could be done.
var lang = DetectAssemblyLanguage(Assembly.GetCallingAssembly());

public static string DetectAssemblyLanguage(Assembly assembly)
{
    var referencedAssemblies = assembly
        .GetReferencedAssemblies()
        .Select(x => x.Name);

    var types = assembly
        .GetTypes();

    // Biggest hint: almost all VB.NET projects have a
    // hidden reference to the Microsoft.VisualBasic assembly
    bool referenceToMSVB = referencedAssemblies.Contains("Microsoft.VisualBasic");

    // VB.NET projects also typically reference the special
    // (YourProject).My.My* types that VB generates
    bool areMyTypesPresent = types.Select(x => x.FullName).Where(x => x.Contains(".My.My")).Any();

    // If a VB.NET project uses any anonymous types,
    // the compiler names them like VB$AnonymousType_0`1
    bool generatedVbNames = types.Select(x => x.Name).Where(x => x.StartsWith("VB$")).Any();

    // If a C# project uses dynamic, it'll have a reference to Microsoft.CSharp
    bool referenceToMSCS = referencedAssemblies.Contains("Microsoft.CSharp");

    // If a C# project uses any anonymous types,
    // the compiler names them like <>f__AnonymousType0`1
    bool generatedCsNames = types.Select(x => x.Name).Where(x => x.StartsWith("<>")).Any();

    var evidenceForVb = new bool[] 
    {
        referenceToMSVB,
        myTypesPresent,
        vbGeneratedNames
    };

    var evidenceForCsharp = new bool[] {
        true, // freebie. ensures ties go to C#
        referenceToMSCS,
        csGeneratedNames
    };

    var scoreForVb = evidenceForVb.Count(x => x)
                     - evidenceForCsharp.Count(x => x);

    // In the case of a tie, C# is assumed
    return scoreForVb > 0
        ? "vb"
        : "cs";
}

这篇关于如何检测哪种.NET语言正在调用我的代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆