Tôi đang cố gắng tìm một cách hay để phát hiện xem một đối tượng địa lý có tồn tại trước khi P/Invoking không. Ví dụ: gọi hàm gốc StrCmpLogicalW
:Phát hiện tính năng khi P/Gọi trong C# và .NET
[SuppressUnmanagedCodeSecurity]
internal static class SafeNativeMethods
{
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
public static extern int StrCmpLogicalW(string psz1, string psz2);
}
sẽ gặp sự cố trên một số hệ thống không có tính năng này.
i don't want to perform version checking, vì đó là thực hành không tốt và đôi khi có thể sai (ví dụ: khi chức năng được truyền lại hoặc khi chức năng có thể được gỡ cài đặt).
Cách đúng, là để kiểm tra sự hiện diện của việc xuất khẩu từ shlwapi.dll
:
private static _StrCmpLogicalW: function(String psz1, String psz2): Integer;
private Boolean _StrCmpLogicalWInitialized;
public int StrCmpLogicalW(String psz1, psz2)
{
if (!_StrCmpLogialInitialized)
{
_StrCmpLogicalW = GetProcedure("shlwapi.dll", "StrCmpLogicalW");
_StrCmpLogicalWInitialized = true;
}
if (_StrCmpLogicalW)
return _StrCmpLogicalW(psz1, psz2)
else
return String.Compare(psz1, psz2, StringComparison.CurrentCultureIgnoreCase);
}
Vấn đề, tất nhiên, là C# không hỗ trợ chức năng gợi ý, ví dụ:
_StrCmpLogicalW = GetProcedure("shlwapi.dll", "StrCmpLogicalW");
không thể thực hiện được.
Vì vậy, tôi đang cố gắng tìm cú pháp thay thế để thực hiện cùng một logic trong .NET. Tôi có mã giả sau đây cho đến nay, nhưng tôi đang nhận được stymied:
[SuppressUnmanagedCodeSecurity]
internal static class SafeNativeMethods
{
private Boolean IsSupported = false;
private Boolean IsInitialized = false;
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode, Export="StrCmpLogicalW", CaseSensitivie=false, SetsLastError=true, IsNative=false, SupportsPeanutMandMs=true)]
private static extern int UnsafeStrCmpLogicalW(string psz1, string psz2);
public int StrCmpLogicalW(string s1, string s2)
{
if (!IsInitialized)
{
//todo: figure out how to loadLibrary in .net
//todo: figure out how to getProcedureAddress in .net
IsSupported = (result from getProcedureAddress is not null);
IsInitialized = true;
}
if (IsSupported)
return UnsafeStrCmpLogicalW(s1, s2);
else
return String.Compare(s1, s2, StringComparison.CurrentCultureIgnoreCase);
}
}
và tôi cần một số trợ giúp.
Một ví dụ khác của một số kim ngạch xuất khẩu mà tôi muốn để phát hiện sự hiện diện của sẽ là:
dwmapi.dll::DwmIsCompositionEnabled
dwmapi.dll::DwmExtendFrameIntoClientArea
dwmapi.dll::DwmGetColorizationColor
dwmapi.dll::DwmGetColorizationParameters
(cung cấp tài liệu , chưa xuất khẩu theo tên, thứ tự 127)dwmapi.dll::127
(không có giấy tờ , DwmGetColorizationParameters)
như của Windows 7 SP1
Hiện đã phải là một mẫu thiết kế trong .NET để kiểm tra sự hiện diện của các tính năng hệ điều hành. Bất cứ ai có thể chỉ cho tôi một ví dụ về cách ưa thích trong. NET để thực hiện tính năng phát hiện?
Mẫu thiết kế trong mã nguồn .NET Framework là để kiểm tra số phiên bản hệ điều hành, nhưng để làm như vậy * thông minh * như Larry Osterman kết thúc lên trong bài đăng trên blog của mình. Tôi đồng ý rằng giải pháp của Johann có lẽ là một giải pháp tốt hơn, nhưng tôi cũng là một anh chàng Win32. 'LoadLibrary' và' GetProcAddress' chỉ * có ý nghĩa * đối với tôi. Tôi dành phần lớn thời gian của tôi viết P/Gọi định nghĩa khi tôi viết mã .NET. Tôi không chắc đó có phải là một điều tốt hay không. –
@Cody: * Tôi không chắc đó có thực sự là một điều hay không * - có lẽ không, không. :-) –
@CodeGray Bạn không thể dựa vào số phiên bản. Một tính năng có thể đã được chuyển về một hệ điều hành (làm cho số phiên bản sai). Một tính năng cũng có thể không được cài đặt bởi người dùng (làm cho số phiên bản sai). –