Getting the CLR ID

2019-02-21 17:56发布

问题:

Is there any where to get the CLR ID at runtime for the current application? I am monitoring my system using Performance Monitors and the name used for the instance is:

ApplicationName.exe_p4952_r15_ad1

I can get all other parameters programmatically but not the r15 which is the runtime ID of the common language runtime (instance) that executes your code. I noticed it is always 15, but it is best to get it dynamically to avoid complications.

回答1:

You can get the whole "suffix", i.e. the part after Application.exe using the same infrastructure that the .NET framework (e.g. the peformance counters) does.

There is the method System.Runtime.Versioning.VersioningHelper.MakeVersionSafeName, which can do that. Note that the method is described as being "Infrastructure" and "This API supports the .NET Framework infrastructure and is not intended to be used directly from your code.", but nevertheless is public. I don't think there is any "better supported" way to get the information you want. At least it is more robust and resilient to future changes, then reverse engineering the information based on documentation.

string suffix = System.Runtime.Versioning.VersioningHelper.MakeVersionSafeName("",                         
    System.Runtime.Versioning.ResourceScope.Machine,
    System.Runtime.Versioning.ResourceScope.AppDomain));

This returns _p4472_r16_ad1, for example.

Of course, you could also directly pass the basename of the performance counter to directly get the full name. The usage of the empty string above is only a trick to just get the "suffix".

string str = VersioningHelper.MakeVersionSafeName("Application.exe",
    ResourceScope.Machine, ResourceScope.AppDomain);

// str -> "Application.exe_p4472_r16_ad1".

The class VersioningHelpers also has the private method GetRuntimeId(), but given the above, I don't think it is neccessary to use reflection on that achieve what you need.



回答2:

As far as I can see there is no way to predict what that value will be - here is a quote from the MSDN page you linked (emphasis mine)

runtimeID is a common language runtime identifier.

The article is slightly confusing as it gives an example whereby an application myapp.exe hosts two CLR runtimes however in the example the two instances appear to have different process IDs but the same CLR runtime ID.

The article however definitely doesn't give any promises about what the value of the CLR runtime ID will be or how to find it (it doesn't even state that its a number), which implies to me that its an internal thing and you shouldn't rely on being able to work out what it is.

My approach would probably be to enumerate through all Perfmon counters and monitor any of them that match your PID. If there is more than one (which will happen if you are using any .Net 2.0 components) then you will just have to monitor both.

Can you give any more information about what it is you are trying to do?



回答3:

You can find it easily by splitting the string you get :

This function split the instance name , and search for the only part that begins with "r" and does not end with ".exe". Once the right part of the string has been found , just delete the first letter "r" and just keep the number to convert it into an integer number and return it. If the CLR ID is not found , just return "-1" to let the parent function notice this.

    int getClrID(string instance_name)
    {
        string[] instance_name_parts = instance_name.Split('_');
        string clr_id = "";

        for (int i = 0; i < instance_name_parts.Length; i++)
        {
            if (instance_name_parts[i].StartsWith("r") && !instance_name_parts[i].EndsWith(".exe"))
            {
                clr_id = instance_name_parts[i];
                break;
            }
        }

        if (clr_id == "") // An error occured ...
            return -1;
        else 
            return Convert.ToInt32(clr_id.Substring(1));
    }

I hope I helped you.



标签: c# winforms clr