public void GetIDispatchForObject_ThrowsNotSupportedException() { Assert.Throws <NotSupportedException>(() => Marshal.GetIDispatchForObject(new object())); }
public void SetValue(object obj) { vt = (short)VarEnum.VT_EMPTY; if (obj == null) { return; } Type t = obj.GetType(); if (t.IsEnum) { t = Enum.GetUnderlyingType(t); } if (t == typeof(sbyte)) { vt = (short)VarEnum.VT_I1; cVal = (sbyte)obj; } else if (t == typeof(byte)) { vt = (short)VarEnum.VT_UI1; bVal = (byte)obj; } else if (t == typeof(short)) { vt = (short)VarEnum.VT_I2; iVal = (short)obj; } else if (t == typeof(ushort)) { vt = (short)VarEnum.VT_UI2; uiVal = (ushort)obj; } else if (t == typeof(int)) { vt = (short)VarEnum.VT_I4; lVal = (int)obj; } else if (t == typeof(uint)) { vt = (short)VarEnum.VT_UI4; ulVal = (uint)obj; } else if (t == typeof(long)) { vt = (short)VarEnum.VT_I8; llVal = (long)obj; } else if (t == typeof(ulong)) { vt = (short)VarEnum.VT_UI8; ullVal = (ulong)obj; } else if (t == typeof(float)) { vt = (short)VarEnum.VT_R4; fltVal = (float)obj; } else if (t == typeof(double)) { vt = (short)VarEnum.VT_R8; dblVal = (double)obj; } else if (t == typeof(string)) { vt = (short)VarEnum.VT_BSTR; bstrVal = Marshal.StringToBSTR((string)obj); } else if (t == typeof(bool)) { vt = (short)VarEnum.VT_BOOL; lVal = ((bool)obj) ? -1 : 0; } else if (t == typeof(BStrWrapper)) { vt = (short)VarEnum.VT_BSTR; bstrVal = Marshal.StringToBSTR(((BStrWrapper)obj).WrappedObject); } else if (t == typeof(UnknownWrapper)) { vt = (short)VarEnum.VT_UNKNOWN; pdispVal = Marshal.GetIUnknownForObject(((UnknownWrapper)obj).WrappedObject); } else if (t == typeof(DispatchWrapper)) { vt = (short)VarEnum.VT_DISPATCH; pdispVal = Marshal.GetIDispatchForObject(((DispatchWrapper)obj).WrappedObject); } else { try { pdispVal = Marshal.GetIDispatchForObject(obj); vt = (short)VarEnum.VT_DISPATCH; return; } catch { } try { vt = (short)VarEnum.VT_UNKNOWN; pdispVal = Marshal.GetIUnknownForObject(obj); } catch (Exception ex) { throw new NotImplementedException(string.Format("Variant couldn't handle object of type {0}", obj.GetType()), ex); } } }
// We have an object and we want to figure out the best // type for it protected override void SetType() { if (TraceUtil.If(this, TraceLevel.Info)) { Trace.WriteLine("ComObjInfo - SetType: " + _obj); } if (_obj != null) { if (!_obj.GetType().IsCOMObject&& !_obj.GetType().Equals(Windows.COM_ROOT_TYPE)) { base.SetType(); return; } if (TypeIsGoodEnough(_obj.GetType())) { _objType = _obj.GetType(); return; } } if (TypeIsGoodEnough(_objType)) { return; } // Get the type library so we can convert it only once. If // we don't do this, the GetTypeForITypeInfo code will // try to convert it multiple times. This also sets the _typeInfo // pointer. if (_typeLib == null) { IntPtr dispPtr; // Get the IDispatch ptr try { dispPtr = Marshal.GetIDispatchForObject(_obj); } catch { // This could just be a COM object, see if it // implements any of the interfaces we know about _interfaces = ComInterfaceInfo.GetImplementedInterfacesKnown(_obj); if (_interfaces.Count == 0) { throw new Exception ("Unable to determine type of object, " + "IDispatch not implemented, and it implements " + "no interfaces associated with known type " + "libraries."); } ComInterfaceInfo ciInfo = PickBestInterface(); AssignType(ciInfo.GetCLRType()); return; } // Get the type library from the dispPtr try { Marshal.AddRef(dispPtr); GetTypeLib(dispPtr); } finally { Marshal.Release(dispPtr); } } if (_typeLib != null) { // Get the COM pointer to the ITypeInfo so we can call // GetTypeForITypeInfo below. //IntPtr iTypeInfo = Marshal.GetIUnknownForObject(_typeInfo); // This figures out the actual class of the object, by hand // based on what interfaces it implements. //Type newType = FigureOutClass(); // This returns the type of the interface this object implements, // but is done completely automatically. This is probably the // better solution (since is less of my code). // The problem this this one is that it converts any // necessary type libraries automatically without // having my hooks so I can properly find out about the // converted type libraries //Type newType = Marshal.GetTypeForITypeInfo(iTypeInfo); // Just look up the type by name from the type info's name, // this will get an interface type, which is fine. A class type // might be better, but that takes more work to figure out. // FIXME - we may want to go to find the class type for those // objects that implement multiple interfaces, see about that. String typeName = ComClassInfo.GetTypeName(_typeInfo); _comTypeName = _typeLib.Name + "." + typeName; if (TraceUtil.If(this, TraceLevel.Info)) { Trace.WriteLine("TypeName: " + typeName); } Type newType = _typeLib.FindTypeByName(typeName, !TypeLibrary.FIND_CLASS); AssignType(newType); } // Can't figure it out, let the superclass deal with it if (_objType == null) { base.SetType(); } }
public void GetIDispatchForObject_InvalidObject_ThrowsInvalidCastException(object o) { Assert.Throws <InvalidCastException>(() => Marshal.GetIDispatchForObject(o)); }
public void GetIDispatchForObject_NullObject_ThrowsArgumentNullException() { AssertExtensions.Throws <ArgumentNullException>("o", () => Marshal.GetIDispatchForObject(null)); }
/// <summary> /// Выполняет команду через COMConnector /// </summary> public V8Answer Execute(Mutex mutLogger) { string result = ""; string fName = ""; bool isDialog = false; string v8version = this.excCommand.Version.ToString(); string runPath = Service.CheckPath(System.Windows.Forms.Application.StartupPath); //Logger.Debug(this.tmSettings, "Версия COM: " + v8version, false, mutLogger); runPath = Service.CheckPath(runPath); //Logger.Debug(this.tmSettings, "Каталог запуска: " + runPath, false, mutLogger); this.success = true; v80Type = null; object v8Connector = null; try { v80Type = Type.GetTypeFromProgID("V" + v8version + ".COMConnector"); v8Connector = Activator.CreateInstance(v80Type); //Logger.Debug(this.tmSettings, "V" + v8version + ".COMConnector создан", false, mutLogger); Connection = v80Type.InvokeMember("Connect", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.InvokeMethod, null, v8Connector, new object[1] { this.excCommand.ConnectionString }); //Logger.Debug(this.tmSettings, "Connect", false, mutLogger); object externalData = GetProperty(null, "ExternalDataProcessors"); object executer = Method(externalData, "Create", new object[2] { runPath + "executer" + v8version + ".tep", this.safeMode1C }); //Logger.Debug(this.tmSettings, "ExternalDataProcessors", false, mutLogger); SetProperty(executer, "Код", this.excCommand.Code); SetProperty(executer, "ПараметрыКоманды", this.excParams); SetProperty(executer, "username", this.t_username); SetProperty(executer, "first_name", this.t_first_name); SetProperty(executer, "last_name", this.t_last_name); SetProperty(executer, "command", this.excCommand.ID); //Logger.Debug(this.tmSettings, "Start executer", false, mutLogger); Method(executer, "ExecuteCode", new object[0]); //Logger.Debug(this.tmSettings, "Finish executer", false, mutLogger); result = (string)GetProperty(executer, "Результат"); fName = (string)GetProperty(executer, "Результат_Файл"); isDialog = (bool)GetProperty(executer, "ДиалогСПараметрами"); //Logger.Debug(this.tmSettings, "Get properties", false, mutLogger); Marshal.Release(Marshal.GetIDispatchForObject(executer)); Marshal.Release(Marshal.GetIDispatchForObject(externalData)); Marshal.ReleaseComObject(executer); Marshal.ReleaseComObject(externalData); executer = null; externalData = null; } catch (Exception e) { string errorDescr = e.Message; if (e.InnerException != null) { errorDescr = errorDescr + "\r\n" + e.InnerException.Message; } Logger.Write(String.Format("Не удалось выполнить команду \"{0}\": {1}", this.excCommand.ID, errorDescr), true, mutLogger); this.success = false; } Marshal.Release(Marshal.GetIDispatchForObject(Connection)); Marshal.ReleaseComObject(Connection); Marshal.Release(Marshal.GetIDispatchForObject(v8Connector)); Marshal.ReleaseComObject(v8Connector); Connection = null; v80Type = null; GC.WaitForPendingFinalizers(); GC.Collect(); GC.WaitForFullGCComplete(); //Logger.Debug(this.tmSettings, "Answer", false, mutLogger); return(new V8Answer(result, fName, isDialog)); }
public void GetIDispatchForObject_NetCore_ThrowsPlatformNotSupportedException() { Assert.Throws <PlatformNotSupportedException>(() => Marshal.GetIDispatchForObject(null)); }
private void SetValue(object value, VarEnum vEnum = VarEnum.VT_EMPTY) { if (vEnum == VarEnum.VT_EMPTY) { vEnum = GetVarEnum(value?.GetType()); } Clear(); VarType = vEnum; // Finished if NULL or EMPTY if (vt <= 1) { return; } // Handle SAFEARRAY if (_vt.IsFlagSet(IntVarEnum.VT_ARRAY)) { SetSafeArray((object[])value); return; } // Handle BYREF null value if (_vt.IsFlagSet(IntVarEnum.VT_BYREF) && value == null) { return; } // Handle case where element type is put in w/o specifying VECTOR if (value != null && value.GetType().IsArray) { VarType |= VarEnum.VT_VECTOR; } switch (VarType) { case VarEnum.VT_I1: case VarEnum.VT_BYREF | VarEnum.VT_I1: SetStruct((sbyte?)value, VarType); break; case VarEnum.VT_UI1: case VarEnum.VT_BYREF | VarEnum.VT_UI1: SetStruct((byte?)value, VarType); break; case VarEnum.VT_I2: case VarEnum.VT_BYREF | VarEnum.VT_I2: SetStruct((short?)value, VarType); break; case VarEnum.VT_UI2: case VarEnum.VT_BYREF | VarEnum.VT_UI2: SetStruct((ushort?)value, VarType); break; case VarEnum.VT_I4: case VarEnum.VT_INT: case VarEnum.VT_BYREF | VarEnum.VT_I4: case VarEnum.VT_BYREF | VarEnum.VT_INT: SetStruct((int?)value, VarType); break; case VarEnum.VT_UI4: case VarEnum.VT_UINT: case VarEnum.VT_BYREF | VarEnum.VT_UI4: case VarEnum.VT_BYREF | VarEnum.VT_UINT: SetStruct((uint?)value, VarType); break; case VarEnum.VT_I8: case VarEnum.VT_BYREF | VarEnum.VT_I8: SetStruct((long?)value, VarType); break; case VarEnum.VT_UI8: case VarEnum.VT_BYREF | VarEnum.VT_UI8: SetStruct((ulong?)value, VarType); break; case VarEnum.VT_R4: case VarEnum.VT_BYREF | VarEnum.VT_R4: SetStruct((float?)value, VarType); break; case VarEnum.VT_R8: case VarEnum.VT_BYREF | VarEnum.VT_R8: SetStruct((double?)value, VarType); break; case VarEnum.VT_BOOL: case VarEnum.VT_BYREF | VarEnum.VT_BOOL: SetStruct((bool?)value, VarType); break; case VarEnum.VT_ERROR: case VarEnum.VT_BYREF | VarEnum.VT_ERROR: { uint?i; if (value is Win32Error) { i = (uint?)(int)(Win32Error)value; } else { i = (uint)Convert.ChangeType(value, typeof(uint)); } SetStruct(i, VarType); } break; case VarEnum.VT_HRESULT: case VarEnum.VT_BYREF | VarEnum.VT_HRESULT: { uint?i; if (value is HRESULT) { i = (uint?)(int)(HRESULT)value; } else { i = (uint)Convert.ChangeType(value, typeof(uint)); } SetStruct(i, VarType); } break; case VarEnum.VT_CY: case VarEnum.VT_BYREF | VarEnum.VT_CY: { ulong?i; if (value is decimal) { i = (ulong?)decimal.ToOACurrency((decimal)value); } else { i = (ulong)Convert.ChangeType(value, typeof(ulong)); } SetStruct(i, VarType); } break; case VarEnum.VT_DATE: case VarEnum.VT_BYREF | VarEnum.VT_DATE: { double?d = null; var dt = value as DateTime?; if (dt != null) { d = dt.Value.ToOADate(); } var ft = value as FILETIME?; if (ft != null) { d = ft.Value.ToDateTime().ToOADate(); } if (d == null) { d = (double)Convert.ChangeType(value, typeof(double)); } SetStruct(d, VarType); } break; case VarEnum.VT_FILETIME: { FILETIME?ft; var dt = value as DateTime?; if (dt != null) { ft = dt.Value.ToFileTimeStruct(); } else { ft = value as FILETIME? ?? MakeFILETIME((ulong)Convert.ChangeType(value, typeof(ulong))); } _ft = ft.GetValueOrDefault(); } break; case VarEnum.VT_CLSID: SetStruct((Guid?)value, VarType); break; case VarEnum.VT_CF: SetStruct((CLIPDATA?)value, VarType); break; case VarEnum.VT_BLOB: case VarEnum.VT_BLOB_OBJECT: _blob = (BLOB)value; break; case VarEnum.VT_BSTR: case VarEnum.VT_BYREF | VarEnum.VT_BSTR: if (value is IntPtr) { SetStruct((IntPtr?)value, VarType); } else { SetString(value?.ToString(), VarType); } break; case VarEnum.VT_LPSTR: case VarEnum.VT_LPWSTR: SetString(value?.ToString(), VarType); break; case VarEnum.VT_UNKNOWN: case VarEnum.VT_BYREF | VarEnum.VT_UNKNOWN: { var p = value as IntPtr? ?? Marshal.GetIUnknownForObject(value); SetStruct <IntPtr>(p, VarType); } break; case VarEnum.VT_DISPATCH: case VarEnum.VT_BYREF | VarEnum.VT_DISPATCH: { var p = value as IntPtr? ?? Marshal.GetIDispatchForObject(value); SetStruct <IntPtr>(p, VarType); } break; case VarEnum.VT_STREAM: case VarEnum.VT_STREAMED_OBJECT: SetStruct <IntPtr>(Marshal.GetComInterfaceForObject(value, typeof(IStream)), VarType); break; case VarEnum.VT_STORAGE: case VarEnum.VT_STORED_OBJECT: SetStruct <IntPtr>(Marshal.GetComInterfaceForObject(value, typeof(IStorage)), VarType); break; case VarEnum.VT_VECTOR | VarEnum.VT_I1: SetVector(ConvertToEnum <sbyte>(value), VarType); break; case VarEnum.VT_VECTOR | VarEnum.VT_UI1: SetVector(ConvertToEnum <byte>(value), VarType); break; case VarEnum.VT_VECTOR | VarEnum.VT_I2: SetVector(ConvertToEnum <short>(value), VarType); break; case VarEnum.VT_VECTOR | VarEnum.VT_UI2: SetVector(ConvertToEnum <ushort>(value), VarType); break; case VarEnum.VT_VECTOR | VarEnum.VT_I4: case VarEnum.VT_VECTOR | VarEnum.VT_INT: SetVector(ConvertToEnum <int>(value), VarType); break; case VarEnum.VT_VECTOR | VarEnum.VT_UI4: case VarEnum.VT_VECTOR | VarEnum.VT_UINT: SetVector(ConvertToEnum <uint>(value), VarType); break; case VarEnum.VT_VECTOR | VarEnum.VT_I8: SetVector(ConvertToEnum <long>(value), VarType); break; case VarEnum.VT_VECTOR | VarEnum.VT_UI8: SetVector(ConvertToEnum <ulong>(value), VarType); break; case VarEnum.VT_VECTOR | VarEnum.VT_R4: SetVector(ConvertToEnum <float>(value), VarType); break; case VarEnum.VT_VECTOR | VarEnum.VT_R8: SetVector(ConvertToEnum <double>(value), VarType); break; case VarEnum.VT_VECTOR | VarEnum.VT_BOOL: SetVector(ConvertToEnum <bool>(value).Select(b => (ushort)(b ? -1 : 0)), VarType); break; case VarEnum.VT_VECTOR | VarEnum.VT_ERROR: { var ee = (value as IEnumerable <Win32Error>)?.Select(w => (uint)(int)w) ?? ConvertToEnum <uint>(value); SetVector(ee, VarType); } break; case VarEnum.VT_VECTOR | VarEnum.VT_HRESULT: { var ee = (value as IEnumerable <HRESULT>)?.Select(w => (uint)(int)w) ?? ConvertToEnum <uint>(value); SetVector(ee, VarType); } break; case VarEnum.VT_VECTOR | VarEnum.VT_CY: { var ecy = (value as IEnumerable <decimal>)?.Select(d => (ulong)decimal.ToOACurrency(d)) ?? ConvertToEnum <ulong>(value); SetVector(ecy, VarType); } break; case VarEnum.VT_VECTOR | VarEnum.VT_DATE: { var ed = (value as IEnumerable <DateTime>)?.Select(d => d.ToOADate()) ?? (value as IEnumerable <FILETIME>)?.Select(ft => ft.ToDateTime().ToOADate()) ?? ConvertToEnum <double>(value); SetVector(ed, VarType); } break; case VarEnum.VT_VECTOR | VarEnum.VT_FILETIME: { var ed = value as IEnumerable <FILETIME> ?? (value as IEnumerable <DateTime>)?.Select(d => d.ToFileTimeStruct()) ?? ConvertToEnum <ulong>(value)?.Select(MakeFILETIME); SetVector(ed, VarType); } break; case VarEnum.VT_VECTOR | VarEnum.VT_CLSID: SetVector(ConvertToEnum <Guid>(value), VarType); break; case VarEnum.VT_VECTOR | VarEnum.VT_CF: SetVector(ConvertToEnum <CLIPDATA>(value), VarType); break; case VarEnum.VT_VECTOR | VarEnum.VT_BSTR: { var ep = value as IEnumerable <IntPtr>; if (ep != null) { SetVector(ep, VarType); } else { SetStringVector(ConvertToEnum <string>(value), VarType); } } break; case VarEnum.VT_VECTOR | VarEnum.VT_LPSTR: case VarEnum.VT_VECTOR | VarEnum.VT_LPWSTR: SetStringVector(ConvertToEnum <string>(value), VarType); break; case VarEnum.VT_VECTOR | VarEnum.VT_VARIANT: SetVector(ConvertToEnum <PROPVARIANT>(value), VarType); break; case VarEnum.VT_VECTOR | VarEnum.VT_DECIMAL: SetVector(ConvertToEnum <decimal>(value), VarType); break; case VarEnum.VT_BYREF | VarEnum.VT_DECIMAL: SetDecimal((decimal?)value); break; case VarEnum.VT_BYREF | VarEnum.VT_VARIANT: _ptr = this.StructureToPtr(); break; case VarEnum.VT_VOID: case VarEnum.VT_PTR: case VarEnum.VT_USERDEFINED: case VarEnum.VT_RECORD: _ptr = (IntPtr)value; break; default: throw new ArgumentOutOfRangeException(); } }
public void GetIDispatchForObject_NonDispatchObject_ThrowsInvalidCastException() { Assert.Throws <InvalidCastException>(() => Marshal.GetIDispatchForObject(string.Empty)); }
void УничтожитьОбъект(object Объект) { Marshal.Release(Marshal.GetIDispatchForObject(Объект)); Marshal.ReleaseComObject(Объект); }
static void Main(string[] args) { int hr; Guid CLSID = new Guid("1ACD2158-6E0E-48B6-A01C-ACF1CAC48580"); string machineName = "MyPCName"; System.Type typeInfo = Type.GetTypeFromCLSID(CLSID, machineName, true); Console.WriteLine("Type.GetTypeFromCLSID successful"); Console.ReadLine(); object objDCOM = Activator.CreateInstance(typeInfo); Console.WriteLine("Activator.CreateInstance successful"); Console.ReadLine(); COAUTHIDENTITY Auth = new COAUTHIDENTITY(); IntPtr pAuth = Marshal.AllocCoTaskMem(28); Auth.User = "******"; Auth.UserLength = (uint)Auth.User.Length; Auth.Domain = "mydomain"; Auth.DomainLength = (uint)Auth.Domain.Length; Auth.Password = "******"; Auth.PasswordLength = (uint)Auth.Password.Length; Auth.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; Marshal.StructureToPtr(Auth, pAuth, false); hr = CoSetProxyBlanket(Marshal.GetIUnknownForObject(objDCOM), // pProxy RPC_C_AUTHN_WINNT, // dwAuthnSvc RPC_C_AUTHZ_NONE, // dwAuthzSvc 0, // pServerPrincName RPC_C_AUTHN_LEVEL_DEFAULT, // dwAuthnLevel RPC_C_IMP_LEVEL_IMPERSONATE, // dwImpLevel pAuth, // pAuthInfo EOAC_NONE); // dwCapabilities Console.WriteLine("CoSetProxyBlanket for IUnknown returned " + hr); if (hr != 0) { return; } hr = CoSetProxyBlanket(Marshal.GetIDispatchForObject(objDCOM), // pProxy RPC_C_AUTHN_WINNT, // dwAuthnSvc RPC_C_AUTHZ_NONE, // dwAuthzSvc 0, // pServerPrincName RPC_C_AUTHN_LEVEL_DEFAULT, // dwAuthnLevel RPC_C_IMP_LEVEL_IMPERSONATE, // dwImpLevel pAuth, // pAuthInfo EOAC_NONE); // dwCapabilities Console.WriteLine("CoSetProxyBlanket for IDispatch returned " + hr); if (hr != 0) { return; } object actualReturnValue = typeInfo.InvokeMember("TestMe", BindingFlags.Default | BindingFlags.InvokeMethod, null, objDCOM, null, null, null, null); Console.WriteLine("Done"); }
private static void ValidateMarshalAPIs(bool validateUseRegistered) { string scenario = validateUseRegistered ? "use registered wrapper" : "fall back to runtime"; Console.WriteLine($"Running {nameof(ValidateMarshalAPIs)}: {scenario}..."); GlobalComWrappers registeredWrapper = GlobalComWrappers.Instance; registeredWrapper.ReturnInvalid = !validateUseRegistered; Console.WriteLine($" -- Validate Marshal.GetIUnknownForObject..."); var testObj = new Test(); IntPtr comWrapper1 = Marshal.GetIUnknownForObject(testObj); Assert.AreNotEqual(IntPtr.Zero, comWrapper1); Assert.AreEqual(testObj, registeredWrapper.LastComputeVtablesObject, "Registered ComWrappers instance should have been called"); IntPtr comWrapper2 = Marshal.GetIUnknownForObject(testObj); Assert.AreEqual(comWrapper1, comWrapper2); Marshal.Release(comWrapper1); Marshal.Release(comWrapper2); Console.WriteLine($" -- Validate Marshal.GetIDispatchForObject..."); Assert.Throws <InvalidCastException>(() => Marshal.GetIDispatchForObject(testObj)); if (validateUseRegistered) { var dispatchObj = new TestEx(IID_IDISPATCH); IntPtr dispatchWrapper = Marshal.GetIDispatchForObject(dispatchObj); Assert.AreNotEqual(IntPtr.Zero, dispatchWrapper); Assert.AreEqual(dispatchObj, registeredWrapper.LastComputeVtablesObject, "Registered ComWrappers instance should have been called"); Console.WriteLine($" -- Validate Marshal.GetIDispatchForObject != Marshal.GetIUnknownForObject..."); IntPtr unknownWrapper = Marshal.GetIUnknownForObject(dispatchObj); Assert.AreNotEqual(IntPtr.Zero, unknownWrapper); Assert.AreNotEqual(unknownWrapper, dispatchWrapper); } Console.WriteLine($" -- Validate Marshal.GetObjectForIUnknown..."); IntPtr trackerObjRaw = MockReferenceTrackerRuntime.CreateTrackerObject(); object objWrapper1 = Marshal.GetObjectForIUnknown(trackerObjRaw); Assert.AreEqual(validateUseRegistered, objWrapper1 is FakeWrapper, $"GetObjectForIUnknown should{(validateUseRegistered ? string.Empty : "not")} have returned {nameof(FakeWrapper)} instance"); object objWrapper2 = Marshal.GetObjectForIUnknown(trackerObjRaw); Assert.AreEqual(objWrapper1, objWrapper2); Console.WriteLine($" -- Validate Marshal.GetUniqueObjectForIUnknown..."); object objWrapper3 = Marshal.GetUniqueObjectForIUnknown(trackerObjRaw); Assert.AreEqual(validateUseRegistered, objWrapper3 is FakeWrapper, $"GetObjectForIUnknown should{(validateUseRegistered ? string.Empty : "not")} have returned {nameof(FakeWrapper)} instance"); Assert.AreNotEqual(objWrapper1, objWrapper3); Marshal.Release(trackerObjRaw); }
unsafe internal void CopyFromIndirect(object value) { VarEnum vt = (VarEnum)(((int)VariantType) & ~((int)VarEnum.VT_BYREF)); if (value == null) { if (vt == VarEnum.VT_DISPATCH || vt == VarEnum.VT_UNKNOWN || vt == VarEnum.VT_BSTR) { *(IntPtr *)_typeUnion._unionTypes._byref = IntPtr.Zero; } return; } if ((vt & VarEnum.VT_ARRAY) != 0) { Variant vArray; Marshal.GetNativeVariantForObject(value, (IntPtr)(void *)&vArray); *(IntPtr *)_typeUnion._unionTypes._byref = vArray._typeUnion._unionTypes._byref; return; } switch (vt) { case VarEnum.VT_I1: *(sbyte *)_typeUnion._unionTypes._byref = (sbyte)value; break; case VarEnum.VT_UI1: *(byte *)_typeUnion._unionTypes._byref = (byte)value; break; case VarEnum.VT_I2: *(short *)_typeUnion._unionTypes._byref = (short)value; break; case VarEnum.VT_UI2: *(ushort *)_typeUnion._unionTypes._byref = (ushort)value; break; case VarEnum.VT_BOOL: // VARIANT_TRUE = -1 // VARIANT_FALSE = 0 *(short *)_typeUnion._unionTypes._byref = (bool)value ? (short)-1 : (short)0; break; case VarEnum.VT_I4: case VarEnum.VT_INT: *(int *)_typeUnion._unionTypes._byref = (int)value; break; case VarEnum.VT_UI4: case VarEnum.VT_UINT: *(uint *)_typeUnion._unionTypes._byref = (uint)value; break; case VarEnum.VT_ERROR: *(int *)_typeUnion._unionTypes._byref = ((ErrorWrapper)value).ErrorCode; break; case VarEnum.VT_I8: *(Int64 *)_typeUnion._unionTypes._byref = (Int64)value; break; case VarEnum.VT_UI8: *(UInt64 *)_typeUnion._unionTypes._byref = (UInt64)value; break; case VarEnum.VT_R4: *(float *)_typeUnion._unionTypes._byref = (float)value; break; case VarEnum.VT_R8: *(double *)_typeUnion._unionTypes._byref = (double)value; break; case VarEnum.VT_DATE: *(double *)_typeUnion._unionTypes._byref = ((DateTime)value).ToOADate(); break; case VarEnum.VT_UNKNOWN: *(IntPtr *)_typeUnion._unionTypes._byref = Marshal.GetIUnknownForObject(value); break; case VarEnum.VT_DISPATCH: #if !NETCOREAPP *(IntPtr *)_typeUnion._unionTypes._byref = Marshal.GetIDispatchForObject(value); #else *(IntPtr *)_typeUnion._unionTypes._byref = Marshal.GetIUnknownForObject(value); #endif break; case VarEnum.VT_BSTR: *(IntPtr *)_typeUnion._unionTypes._byref = Marshal.StringToBSTR((string)value); break; case VarEnum.VT_CY: *(long *)_typeUnion._unionTypes._byref = decimal.ToOACurrency((decimal)value); break; case VarEnum.VT_DECIMAL: *(decimal *)_typeUnion._unionTypes._byref = (decimal)value; break; case VarEnum.VT_VARIANT: Marshal.GetNativeVariantForObject(value, _typeUnion._unionTypes._byref); break; default: throw new ArgumentException(); } }
private string GetName(IDispatch dispatch) { string theName = null; if (nameProperty != null) { IntPtr ptrDispatch = Marshal.GetIDispatchForObject(dispatch); try { if (ptrDispatch != IntPtr.Zero) { object typedObject = Marshal.GetTypedObjectForIUnknown(ptrDispatch, comType); if (typedObject != null) { theName = (string)nameProperty.GetValue(typedObject, null); } } } catch { theName = null; } finally { if (ptrDispatch != IntPtr.Zero) { Marshal.Release(ptrDispatch); ptrDispatch = IntPtr.Zero; } } } if (theName == null) { Guid guid = Guid.Empty; string[] names = new string[] { "Name" }; int[] dispIds = new int[] { 0 }; int hr = dispatch.GetIDsOfNames(ref guid, names, names.Length, 0, dispIds); if (dispIds[0] != -1) { ComTypes.DISPPARAMS[] dispParams = new ComTypes.DISPPARAMS[1]; dispParams[0].cNamedArgs = 0; dispParams[0].rgdispidNamedArgs = IntPtr.Zero; dispParams[0].cArgs = 1; dispParams[0].rgvarg = Marshal.AllocCoTaskMem(0x1000); try { Marshal.GetNativeVariantForObject(theName, dispParams[0].rgvarg); hr = dispatch.Invoke( dispIds[0], ref guid, CultureInfo.CurrentCulture.LCID, (short)ComTypes.INVOKEKIND.INVOKE_PROPERTYGET, dispParams, null, null, null); object retValue = Marshal.GetObjectForNativeVariant(dispParams[0].rgvarg); if (retValue is string) { theName = (string)retValue; } } finally { Marshal.FreeCoTaskMem(dispParams[0].rgvarg); dispParams[0].rgvarg = IntPtr.Zero; } } } return(theName); }
public void SetValue(object obj) { this.vt = 0; if (obj == null) { return; } Type type = obj.GetType(); if (type.IsEnum) { type = Enum.GetUnderlyingType(type); } if (type == typeof(sbyte)) { this.vt = 16; this.cVal = (sbyte)obj; } else if (type == typeof(byte)) { this.vt = 17; this.bVal = (byte)obj; } else if (type == typeof(short)) { this.vt = 2; this.iVal = (short)obj; } else if (type == typeof(ushort)) { this.vt = 18; this.uiVal = (ushort)obj; } else if (type == typeof(int)) { this.vt = 3; this.lVal = (int)obj; } else if (type == typeof(uint)) { this.vt = 19; this.ulVal = (uint)obj; } else if (type == typeof(long)) { this.vt = 20; this.llVal = (long)obj; } else if (type == typeof(ulong)) { this.vt = 21; this.ullVal = (ulong)obj; } else if (type == typeof(float)) { this.vt = 4; this.fltVal = (float)obj; } else if (type == typeof(double)) { this.vt = 5; this.dblVal = (double)obj; } else if (type == typeof(string)) { this.vt = 8; this.bstrVal = Marshal.StringToBSTR((string)obj); } else if (type == typeof(bool)) { this.vt = 11; this.lVal = ((!(bool)obj) ? 0 : -1); } else if (type == typeof(BStrWrapper)) { this.vt = 8; this.bstrVal = Marshal.StringToBSTR(((BStrWrapper)obj).WrappedObject); } else if (type == typeof(UnknownWrapper)) { this.vt = 13; this.pdispVal = Marshal.GetIUnknownForObject(((UnknownWrapper)obj).WrappedObject); } else if (type == typeof(DispatchWrapper)) { this.vt = 9; this.pdispVal = Marshal.GetIDispatchForObject(((DispatchWrapper)obj).WrappedObject); } else { try { this.pdispVal = Marshal.GetIDispatchForObject(obj); this.vt = 9; return; } catch { } try { this.vt = 13; this.pdispVal = Marshal.GetIUnknownForObject(obj); } catch (Exception inner) { throw new NotImplementedException(string.Format("Variant couldn't handle object of type {0}", obj.GetType()), inner); } } }
public void GetIDispatchForObject_ManagedIInspectableObject_Fail() { Assert.Throws <PlatformNotSupportedException>(() => Marshal.GetIDispatchForObject(new IInspectableManagedObject())); }
public static IEnumerable <object[]> GetObjectForNativeVariant_PrimitivesByRef_TestData() { // VT_NULL => null. yield return(new object[] { CreateVariant(VT_NULL, new UnionTypes { _byref = IntPtr.Zero }), DBNull.Value }); yield return(new object[] { CreateVariant(VT_NULL, new UnionTypes { _byref = (IntPtr)10 }), DBNull.Value }); // VT_I2 => short. yield return(new object[] { CreateVariant(VT_I2, new UnionTypes { _i2 = 10 }), (short)10 }); yield return(new object[] { CreateVariant(VT_I2, new UnionTypes { _i2 = 0 }), (short)0 }); yield return(new object[] { CreateVariant(VT_I2, new UnionTypes { _i2 = -10 }), (short)(-10) }); // VT_I4 => int. yield return(new object[] { CreateVariant(VT_I4, new UnionTypes { _i4 = 10 }), 10 }); yield return(new object[] { CreateVariant(VT_I4, new UnionTypes { _i4 = 0 }), 0 }); yield return(new object[] { CreateVariant(VT_I4, new UnionTypes { _i4 = -10 }), -10 }); // VT_R4 => float. yield return(new object[] { CreateVariant(VT_R4, new UnionTypes { _r4 = 10 }), (float)10 }); yield return(new object[] { CreateVariant(VT_R4, new UnionTypes { _r4 = 0 }), (float)0 }); yield return(new object[] { CreateVariant(VT_R4, new UnionTypes { _r4 = -10 }), (float)(-10) }); yield return(new object[] { CreateVariant(VT_R4, new UnionTypes { _r4 = float.PositiveInfinity }), float.PositiveInfinity }); yield return(new object[] { CreateVariant(VT_R4, new UnionTypes { _r4 = float.NegativeInfinity }), float.NegativeInfinity }); yield return(new object[] { CreateVariant(VT_R4, new UnionTypes { _r4 = float.NaN }), float.NaN }); // VT_R8 => double. yield return(new object[] { CreateVariant(VT_R8, new UnionTypes { _r8 = 10 }), (double)10 }); yield return(new object[] { CreateVariant(VT_R8, new UnionTypes { _r8 = 0 }), (double)0 }); yield return(new object[] { CreateVariant(VT_R8, new UnionTypes { _r8 = -10 }), (double)(-10) }); yield return(new object[] { CreateVariant(VT_R8, new UnionTypes { _r8 = double.PositiveInfinity }), double.PositiveInfinity }); yield return(new object[] { CreateVariant(VT_R8, new UnionTypes { _r8 = double.NegativeInfinity }), double.NegativeInfinity }); yield return(new object[] { CreateVariant(VT_R8, new UnionTypes { _r8 = double.NaN }), double.NaN }); // VT_CY => decimal. yield return(new object[] { CreateVariant(VT_CY, new UnionTypes { _cy = 200 }), 0.02m }); yield return(new object[] { CreateVariant(VT_CY, new UnionTypes { _cy = 0 }), 0m }); yield return(new object[] { CreateVariant(VT_CY, new UnionTypes { _cy = -200 }), -0.02m }); // VT_DATE => DateTime. DateTime maxDate = DateTime.MaxValue; yield return(new object[] { CreateVariant(VT_DATE, new UnionTypes { _date = maxDate.ToOADate() }), new DateTime(9999, 12, 31, 23, 59, 59, 999) }); yield return(new object[] { CreateVariant(VT_DATE, new UnionTypes { _date = 200 }), new DateTime(1900, 07, 18) }); yield return(new object[] { CreateVariant(VT_DATE, new UnionTypes { _date = 0.5 }), new DateTime(1899, 12, 30, 12, 0, 0) }); yield return(new object[] { CreateVariant(VT_DATE, new UnionTypes { _date = 0 }), new DateTime(1899, 12, 30) }); yield return(new object[] { CreateVariant(VT_DATE, new UnionTypes { _date = -0.5 }), new DateTime(1899, 12, 30, 12, 0, 0) }); yield return(new object[] { CreateVariant(VT_DATE, new UnionTypes { _date = -200 }), new DateTime(1899, 06, 13) }); DateTime minDate = new DateTime(100, 01, 01, 23, 59, 59, 999); yield return(new object[] { CreateVariant(VT_DATE, new UnionTypes { _date = minDate.ToOADate() }), minDate }); // VT_BSTR => string. yield return(new object[] { CreateVariant(VT_BSTR, new UnionTypes { _bstr = IntPtr.Zero }), null }); IntPtr emptyString = Marshal.StringToBSTR(""); yield return(new object[] { CreateVariant(VT_BSTR, new UnionTypes { _bstr = emptyString }), "" }); IntPtr oneLetterString = Marshal.StringToBSTR("a"); yield return(new object[] { CreateVariant(VT_BSTR, new UnionTypes { _bstr = oneLetterString }), "a" }); IntPtr twoLetterString = Marshal.StringToBSTR("ab"); yield return(new object[] { CreateVariant(VT_BSTR, new UnionTypes { _bstr = twoLetterString }), "ab" }); IntPtr embeddedNullString = Marshal.StringToBSTR("a\0c"); yield return(new object[] { CreateVariant(VT_BSTR, new UnionTypes { _bstr = embeddedNullString }), "a\0c" }); // VT_DISPATCH => object. yield return(new object[] { CreateVariant(VT_DISPATCH, new UnionTypes { _dispatch = IntPtr.Zero }), null }); var obj = new object(); #if !netstandard // Marshal.GetIDispatchForObject is not in netstandard2.0 if (!PlatformDetection.IsNetCore) { IntPtr dispatch = Marshal.GetIDispatchForObject(obj); yield return(new object[] { CreateVariant(VT_DISPATCH, new UnionTypes { _dispatch = dispatch }), obj }); } else { Assert.Throws <PlatformNotSupportedException>(() => Marshal.GetIDispatchForObject(obj)); } #endif // VT_ERROR => int. yield return(new object[] { CreateVariant(VT_ERROR, new UnionTypes { _error = int.MaxValue }), int.MaxValue }); yield return(new object[] { CreateVariant(VT_ERROR, new UnionTypes { _error = 0 }), 0 }); yield return(new object[] { CreateVariant(VT_ERROR, new UnionTypes { _error = int.MinValue }), int.MinValue }); // VT_BOOL => bool. yield return(new object[] { CreateVariant(VT_BOOL, new UnionTypes { _i1 = 1 }), true }); yield return(new object[] { CreateVariant(VT_BOOL, new UnionTypes { _i1 = 0 }), false }); yield return(new object[] { CreateVariant(VT_BOOL, new UnionTypes { _i1 = -1 }), true }); // VT_UNKNOWN => object. yield return(new object[] { CreateVariant(VT_UNKNOWN, new UnionTypes { _unknown = IntPtr.Zero }), null }); IntPtr unknown = Marshal.GetIUnknownForObject(obj); yield return(new object[] { CreateVariant(VT_UNKNOWN, new UnionTypes { _unknown = unknown }), obj }); // VT_I1 => sbyte. yield return(new object[] { CreateVariant(VT_I1, new UnionTypes { _i1 = 10 }), (sbyte)10 }); yield return(new object[] { CreateVariant(VT_I1, new UnionTypes { _i1 = 0 }), (sbyte)0 }); yield return(new object[] { CreateVariant(VT_I1, new UnionTypes { _i1 = -10 }), (sbyte)(-10) }); // VT_UI1 => byte. yield return(new object[] { CreateVariant(VT_UI1, new UnionTypes { _ui1 = 10 }), (byte)10 }); yield return(new object[] { CreateVariant(VT_UI1, new UnionTypes { _ui1 = 0 }), (byte)0 }); // VT_UI2 => ushort. yield return(new object[] { CreateVariant(VT_UI2, new UnionTypes { _ui2 = 10 }), (ushort)10 }); yield return(new object[] { CreateVariant(VT_UI2, new UnionTypes { _ui2 = 0 }), (ushort)0 }); // VT_UI4 => uint. yield return(new object[] { CreateVariant(VT_UI4, new UnionTypes { _ui4 = 10 }), (uint)10 }); yield return(new object[] { CreateVariant(VT_UI4, new UnionTypes { _ui4 = 0 }), (uint)0 }); // VT_I8 => long. yield return(new object[] { CreateVariant(VT_I8, new UnionTypes { _i8 = 10 }), (long)10 }); yield return(new object[] { CreateVariant(VT_I8, new UnionTypes { _i8 = 0 }), (long)0 }); yield return(new object[] { CreateVariant(VT_I8, new UnionTypes { _i8 = -10 }), (long)(-10) }); // VT_UI8 => ulong. yield return(new object[] { CreateVariant(VT_UI8, new UnionTypes { _ui8 = 10 }), (ulong)10 }); yield return(new object[] { CreateVariant(VT_UI8, new UnionTypes { _ui8 = 0 }), (ulong)0 }); // VT_INT => int. yield return(new object[] { CreateVariant(VT_INT, new UnionTypes { _int = 10 }), 10 }); yield return(new object[] { CreateVariant(VT_INT, new UnionTypes { _int = 0 }), 0 }); yield return(new object[] { CreateVariant(VT_INT, new UnionTypes { _int = -10 }), -10 }); // VT_UINT => uint. yield return(new object[] { CreateVariant(VT_UINT, new UnionTypes { _uint = 10 }), (uint)10 }); yield return(new object[] { CreateVariant(VT_UINT, new UnionTypes { _uint = 0 }), (uint)0 }); // VT_VOID => null. yield return(new object[] { CreateVariant(VT_VOID, new UnionTypes()), null }); }
public static IntPtr GetIDispatchPointer(object o) => Marshal.GetIDispatchForObject(o);