我正在尝试寻找一种好的方法,在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中执行功能检测的首选方法的示例吗?
LoadLibrary
和GetProcAddress
对我来说很自然。当我写 .NET 代码时,我大部分时间都在编写 P/Invoke 定义。我不确定这是否真的是一件好事。 - Cody Gray