How do I convert type _ComObject to a native type like Long or other (getting cast error)?

雨燕双飞 提交于 2019-12-11 14:16:00

问题


I am trying to get the LastLogonTimestamp from Active Directory by calling

Principal.ExtensionGet("lastLogonTimestamp")

VB.NET code:

<DirectoryProperty("lastLogonTimestamp")>
Public Property LastLogonTimestamp() As Date? ' no matter what this type is, I cannot cast the Object coming in
    Get
        Dim valueArray = ExtensionGet("lastLogonTimestamp")
        If valueArray Is Nothing OrElse valueArray.Length = 0 Then Return Nothing
        Return DateTime.FromFileTimeUtc(valueArray(0))
    End Get
    Set(value As Date?)
        ExtensionSet("lastLogonTimestamp", value)
    End Set
End Property

This returns an array of Object (i.e. Object()) or null. The trouble is it complains about my cast to Long (or other types I have tried like: ULong, Date, and String). It always tells me something like this:

Conversion from type '_ComObject' to type 'Long' is not valid.

In a new question, I set out to go the other way (from DateTime to 64 bit)


回答1:


Using C# code provided in link via HansPassant's comment below, I resolved this with the following VB code:

<DirectoryProperty("lastLogonTimestamp")>
Public Property LastLogonTimestamp() As Date?
    Get
        'Dim valueArray = GetProperty("whenChanged")
        Dim valueArray = ExtensionGet("lastLogonTimestamp") 'ExtensionGet("LastLogon")
        If valueArray Is Nothing OrElse valueArray.Length = 0 Then Return Nothing

        Dim lastLogonDate = valueArray(0)
        Dim lastLogonDateType = lastLogonDate.GetType()
        Dim highPart = CType(lastLogonDateType.InvokeMember("HighPart", Reflection.BindingFlags.GetProperty, Nothing, lastLogonDate, Nothing), Int32)
        Dim lowPart = CType(lastLogonDateType.InvokeMember("LowPart", Reflection.BindingFlags.GetProperty Or Reflection.BindingFlags.Public, Nothing, lastLogonDate, Nothing), Int32)
        Dim longDate = CLng(highPart) << 32 Or (CLng(lowPart) And &HFFFFFFFFL)
        Dim result = IIf(longDate > 0, CType(DateTime.FromFileTime(longDate), DateTime?), Nothing)

        Return result
        'Return DateTime.FromFileTimeUtc(valueArray(0))
    End Get
    Set(value As Date?)
        ExtensionSet("lastLogonTimestamp", value)
    End Set
End Property

And the C# version (clipped from source):

[DirectoryProperty("RealLastLogon")]
public DateTime? RealLastLogon
{
    get
    {
        if (ExtensionGet("LastLogon").Length > 0)
        {
            var lastLogonDate = ExtensionGet("LastLogon")[0];
            var lastLogonDateType = lastLogonDate.GetType();
            var highPart = (Int32)lastLogonDateType.InvokeMember("HighPart", BindingFlags.GetProperty, null, lastLogonDate, null);
            var lowPart = (Int32)lastLogonDateType.InvokeMember("LowPart", BindingFlags.GetProperty | BindingFlags.Public, null, lastLogonDate, null);

            var longDate = ((Int64)highPart << 32 | (UInt32)lowPart);

            return longDate > 0 ? (DateTime?) DateTime.FromFileTime(longDate) : null;
        }

        return null;
    }
}


来源:https://stackoverflow.com/questions/49059032/how-do-i-convert-type-comobject-to-a-native-type-like-long-or-other-getting-ca

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!