pythonnet / pythonnet/clr-loader
Missing TargetFrameworkName from AppDomain.SetupInformation
Chưa có ai nhận issue này.
- Ngôn ngữ chính
- Python
- Star
- 42
- Fork
- 32
- Merge trung bình
- 14 giờ 1 phút
- Pull request đã merge (30 ngày)
- 1
Mô tả
When the .Net code is launched from pythonnet, the TargetFrameworkName property of the AppDomain.SetupInformation is not configured / provided.
Here is what AppDomain setup information returns from the normally executed .Net code:
AppDomain setup information:
AppDomainManagerAssembly = NULL
AppDomainManagerType = NULL
ApplicationBase = D:\_WorkRoot\Clients\...\bin\Debug\
ConfigurationFile = D:\_WorkRoot\Clients\...\bin\Debug\UPSTest.exe.Config
TargetFrameworkName = .NETFramework,Version=v4.8
DynamicBase = NULL
DisallowPublisherPolicy = False
DisallowBindingRedirects = False
DisallowCodeDownload = False
DisallowApplicationBaseProbing = False
ApplicationName = UPSTest.exe
PrivateBinPath = NULL
PrivateBinPathProbe = NULL
ShadowCopyDirectories = NULL
ShadowCopyFiles = NULL
CachePath = NULL
LicenseFile = NULL
LoaderOptimization = NotSpecified
SandboxInterop = False
Here is how it is setup when called from PythonNet:
AppDomain setup information:
AppDomainManagerAssembly = NULL
AppDomainManagerType = NULL
ApplicationBase = C:\Program Files\Python310\
ConfigurationFile = C:\Program Files\Python310\python.exe.Config
TargetFrameworkName = NULL
DynamicBase = NULL
DisallowPublisherPolicy = False
DisallowBindingRedirects = False
DisallowCodeDownload = False
DisallowApplicationBaseProbing = False
ApplicationName = python.exe
PrivateBinPath = NULL
PrivateBinPathProbe = NULL
ShadowCopyDirectories = NULL
ShadowCopyFiles = NULL
CachePath = NULL
LicenseFile = NULL
LoaderOptimization = NotSpecified
SandboxInterop = False
Why is it important? The below is the copy of the .Net 4.7.2 code that uses that moniker inside AppContext class (system\AppContext\AppContextDefaultValues.cs) (added in .Net 4.6.2).
internal static partial class AppContextDefaultValues
{
public static void PopulateDefaultValues()
{
string platformIdentifier, profile;
int version;
ParseTargetFrameworkName(out platformIdentifier, out profile, out version);
// Call into each library to populate their default switches
PopulateDefaultValuesPartial(platformIdentifier, profile, version);
}
/// <summary>
/// We have this separate method for getting the parsed elements out of the TargetFrameworkName so we can
/// more easily support this on other platforms.
/// </summary>
private static void ParseTargetFrameworkName(out string identifier, out string profile, out int version)
{
string targetFrameworkMoniker = AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName;
// If we don't have a TFM then we should default to the 4.0 behavior where all quirks are turned on.
if (!TryParseFrameworkName(targetFrameworkMoniker, out identifier, out version, out profile))
{
#if FEATURE_CORECLR
if (CompatibilitySwitches.UseLatestBehaviorWhenTFMNotSpecified)
{
// If we want to use the latest behavior it is enough to set the value of the switch to string.Empty.
// When the get to the caller of this method (PopulateDefaultValuesPartial) we are going to use the
// identifier we just set to decide which switches to turn on. By having an empty string as the
// identifier we are simply saying -- don't turn on any switches, and we are going to get the latest
// behavior for all the switches
identifier = string.Empty;
}
else
#endif
{
identifier = ".NETFramework";
version = 40000;
profile = string.Empty;
}
}
}
The AppContext switches control behavior of number of .Net components (between versions). For example, one of such switches controls behavior of asymmetric encryption. It may mean that any code that calls .Net API impacted by any of those switches will behave differently inside Python than what is expected by the .Net code author.
It creates uncertainties for the .Net code that calls such .Net Framework API. For example, we are trying to detect which level of compatibility we are currently under to call our encryption code accordingly. That determination includes TargetFramework of the entry assembly or supportedRuntime element in the config file. And our code might not have a proper recovery strategy to go all the way back to .Net 4.0 compatibility (yet having installed all the latest .Net and compiled using latest .Net Framework).
Some switches are explictely controllable via configuration file but missing framework in the AppDomain setup just opens the mine field of discrepancies.
Hướng dẫn đóng góp
Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Hướng nghiên cứu
Bắt đầu bằng cách đọc system\AppContext\AppContextDefaultValues.cs và theo dõi cách AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName được điền khi mã được khởi chạy thông qua pythonnet. So sánh đường đi đó với một ứng dụng .NET được thực thi bình thường; hoàn tất khi AppDomain được khởi chạy bằng Python báo cáo framework đích phù hợp thay vì NULL.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Công nghệ
- python
- Lĩnh vực
- tooling
- Loại issue
- Lỗi
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức độ hoạt động
- Đình trệ
- Độ rõ ràng
- Khá rõ ràng
- Mức phù hợp với người mới
- 35/100