Các mã sau đây tồn tại trong LogEntry.cs trong Logging Application Block Thư viện của Doanh nghiệp:Quyền không được quản lý. Nó là gì?
private bool UnmanagedCodePermissionAvailable
{
get
{
if (!unmanagedCodePermissionAvailableInitialized)
{
// check whether the unmanaged code permission is available to avoid three potential stack walks
bool internalUnmanagedCodePermissionAvailable = false;
SecurityPermission unmanagedCodePermission =
new SecurityPermission(SecurityPermissionFlag.UnmanagedCode);
// avoid a stack walk by checking for the permission on the current assembly. this is safe because there are no
// stack walk modifiers before the call.
if (SecurityManager.IsGranted(unmanagedCodePermission))
{
try
{
unmanagedCodePermission.Demand();
internalUnmanagedCodePermissionAvailable = true;
}
catch (SecurityException)
{ }
}
this.UnmanagedCodePermissionAvailable =
internalUnmanagedCodePermissionAvailable;
}
return this.unmanagedCodePermissionAvailable;
}
set
{
this.unmanagedCodePermissionAvailable = value;
unmanagedCodePermissionAvailableInitialized = true;
}
}
Các hàm được gọi trước khi bất kỳ một số P/Gọi các cuộc gọi được thực hiện để lấy thông tin khác nhau để giúp điền vào các cấu trúc LogEntry . Nếu "UnmanagedCodePermission" không có sẵn, thì thuộc tính LogEntry tương ứng được đặt thành một chuỗi cho biết ("XXX không khả dụng").
Ví dụ, LogEntry muốn lấy id chuỗi Win32 và nó sử dụng hàm Win32, GetCurrentThreadId, được gọi bằng P/Invoke để lấy nó. Trước khi gọi GetCurrentThreadId, nó sẽ kiểm tra xem "quyền mã unamanged" có sẵn hay không. Nếu vậy, nó làm cho cuộc gọi, nếu không, nó không. Một cái gì đó như thế này:
private void InitializeWin32ThreadId()
{
if (this.UnmanagedCodePermissionAvailable)
{
try
{
this.Win32ThreadId = LogEntryContext.GetCurrentThreadId();
}
catch (Exception e)
{
this.Win32ThreadId = string.Format(
CultureInfo.CurrentCulture,
Properties.Resources.IntrinsicPropertyError,
e.Message);
}
}
else
{
this.Win32ThreadId = string.Format(CultureInfo.CurrentCulture,
Properties.Resources.IntrinsicPropertyError,
Properties.Resources.
LogEntryIntrinsicPropertyNoUnmanagedCodePermissionError);
}
}
Từ những gì tôi hiểu, trong đó, phải thừa nhận, không phải là nhiều, thực hiện cuộc gọi đến unmanaged code (ví dụ P/Invoke) không phải lúc nào cũng có thể do an ninh/permissions/tin tưởng. Có kiểm tra này để xem liệu các cuộc gọi mã không được quản lý có thể thực hiện được hay không, làm cho nó có thể bảo vệ tất cả các cuộc gọi không được quản lý một cách thống nhất.
Khi tôi biên dịch mã này, tôi nhận được một cảnh báo về dòng này:
if (SecurityManager.IsGranted(unmanagedCodePermission))
Đây là cảnh báo:
System.Security.SecurityManager.IsGranted (System.Security.IPermission) đã lỗi thời: 'IsGranted đã lỗi thời và sẽ bị xóa trong bản phát hành .NET Framework trong tương lai. Vui lòng sử dụng thuộc tính PermissionSet của AppDomain hoặc Assembly thay thế.
(Lưu ý rằng tôi đang xây dựng tính năng này trên .Net 4.0 sử dụng VS2010).
Vì vậy, có vẻ IsGranted đã lỗi thời. Tôi nhìn vào thuộc tính PermissionSet cho AppDomain và Assembly, và nó không rõ ràng chính xác cách thực hiện kiểm tra tương tự.
Trong trường hợp của LogEntry, có vẻ như thông tin này không quan trọng, do đó, nó không được coi là một thất bại quan trọng nếu không được phép quản lý không có sẵn. Hãy xem xét các câu hỏi sau đây từ cùng một quan điểm. Đó là, nếu không được phép quản lý mã không có sẵn, nó không phải là một việc lớn, tôi có thể sống mà không có thông tin.
Cuối cùng, một vài câu hỏi:
có phải là một ý tưởng tốt để cố gắng bảo vệ các cuộc gọi đến unmanaged code (ví dụ P/Invoke)? Đôi khi, luôn luôn, không bao giờ?
Nếu bạn nên bảo vệ các cuộc gọi này, đây có phải là mô hình hợp lý để làm như vậy không? Có cách nào tốt hơn?
Cách nào chính xác (ví dụ: không lỗi thời) để thực hiện đăng ký tương đương .Net 4.0?