Özellik algılama özelliği P/Invoking'den önce bir özellik olup olmadığını tespit etmenin iyi bir yolunu bulmaya çalışıyorum.P/Invoking C# ve .NET
[SuppressUnmanagedCodeSecurity]
internal static class SafeNativeMethods
{
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
public static extern int StrCmpLogicalW(string psz1, string psz2);
}
bu özelliği yok bazı sistemlerde kilitlenmesine: Örneğin yerli StrCmpLogicalW
fonksiyonunu çağırarak.
i don't want to perform version checking
, bu kötü bir uygulamadır ve (işlevsellik geri portlu olduğunda veya işlevsellik kaldırılabilir zaman örneğin) bazen sadece yanlış olabilir olarak.doğru yolu, shlwapi.dll
gelen ihracat varlığı için kontrol etmektir:
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);
}
sorun, tabii ki, C# işlev işaretçileri, yani desteklemiyor olmasıdır
_StrCmpLogicalW = GetProcedure("shlwapi.dll", "StrCmpLogicalW");
yapılamaz.
.NET'te aynı mantığı gerçekleştirmek için alternatif sözdizimi bulmaya çalışıyorum. ben şimdiye kadar aşağıdaki sözde kod var ama ben stymied alıyorum:
[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);
}
}
ve biraz yardıma ihtiyacım var.
i varlığını tespit etmek isteyen bazı ihracatın başka örnek olacaktır:
dwmapi.dll::DwmIsCompositionEnabled
dwmapi.dll::DwmExtendFrameIntoClientArea
dwmapi.dll::DwmGetColorizationColor
dwmapi.dll::DwmGetColorizationParameters
(, belgesiz henüz dışa İsme göre, ordinal 127)dwmapi.dll::127
(belgesiz , DwmGetColorizationParameters) Windows 7 SP1itibariyle
zaten işletim sistemi özelliklerinin varlığını kontrol etmek için .NET bir tasarım deseni olmalı. Özellik algılama işlemini gerçekleştirmek için bana .NET'te tercih edilen yolun bir örneğini işaret edebilir miyim?
.NET Framework kaynak kodundaki tasarım deseni, işletim sistemi sürüm numaralarını kontrol etmektir, ancak bunu yapmak için * akıllıca * Larry Osterman'ın blog yayınında sona ermesiyle sona erer. Johann'un çözümünün muhtemelen daha iyi olduğuna katılıyorum, ama ben de bir Win32 adamıyım. 'LoadLibrary' ve' GetProcAddress'' için * sadece * anlamlıdır. .NET kod yazarken zamanımın çoğunu P/Invoke tanımlarını yazarak geçiriyorum. Aslında iyi bir şey olup olmadığından emin değilim. –
@Cody: * Gerçekten iyi bir şey olup olmadığından emin değilim * - muhtemelen hayır, hayır. :-) –
@CodeGray Sürüm numaralarına güvenemezsiniz. Bir özellik geriye dönük olarak bir işletim sistemine yüklenmiş olabilir (sürüm numarası yanlış). Bir özellik ayrıca kullanıcı tarafından yüklenemedi (sürüm numarası yanlış). –