Я пытаюсь найти хороший способ определить, существует ли функция до P / Invoking. Например, вызов встроенной функции 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);
}
Проблема, конечно же, в том, что C # не поддерживает функцию указатели, например:
_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?