Я пытаюсь найти хороший способ определить, существует ли функция до P/Invoking. Например, вызов функции native StrCmpLogicalW
:
[SuppressUnmanagedCodeSecurity]
internal static class SafeNativeMethods
{
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
public static extern int StrCmpLogicalW(string psz1, string psz2);
}
произойдет сбой в некоторых системах, у которых нет этой функции.
Я не хочу выполнять проверку версий, так как это плохая практика, и иногда может быть просто ошибочной (например, когда функциональность перегружена или когда функциональность может быть удалена).
Правильный способ - проверить наличие экспорта из 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);
}
Проблема, конечно, в том, что С# не поддерживает указатели на функции, то есть:
_StrCmpLogicalW = GetProcedure("shlwapi.dll", "StrCmpLogicalW");
не может быть выполнено.
Итак, я пытаюсь найти альтернативный синтаксис для выполнения той же логики в .NET. До сих пор у меня есть следующий псевдокод, но я становлюсь заглушенным:
[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);
}
}
и мне нужна помощь.
Другим примером некоторого экспорта, который я хочу обнаружить, будет:
-
dwmapi.dll::DwmIsCompositionEnabled
-
dwmapi.dll::DwmExtendFrameIntoClientArea
-
dwmapi.dll::DwmGetColorizationColor
-
dwmapi.dll::DwmGetColorizationParameters
(недокументированный 1 еще не экспортированный по имени, порядковый номер 127) -
dwmapi.dll::127
(недокументированный 1 DwmGetColorizationParameters)
1 по состоянию на Windows 7 SP1
В .NET должен быть шаблон проектирования для проверки наличия функций ОС. Может ли кто-нибудь указать мне пример предпочтительного способа .NET для обнаружения функций?