loading an assembly into a .net System.Windows.Forms.Form
-
- Posts: 3
- Joined: Mon Jun 18, 2018 8:42 pm
loading an assembly into a .net System.Windows.Forms.Form
We are currently evaluating replacing SilkTest with ranorex. SilkTest has a feature that allows the user to "inject" a dll into the AUT and invoke the members of that dll. So instead of constantly calling "Invoke" in the testing app we have an external dll that gets loaded into the same domain of the AUT and then we invoke a single call from the testing app to the AUT and the code actually runs within the AUT process. I should also note that we are not using ranorex studio or even a repository but just utilizing the APIs from a C# project. Is there a way to do this in Ranorex, I've searched the help files and dlls but could find anything, I would imagine there ranorex has this capability because it injects itself into the AUT process but maybe it a hidden feature?
Re: loading an assembly into a .net System.Windows.Forms.Form
Ranorex provides the same functionality for Windows Forms controls (since 2007) by means of the Control adapter. The corresponding method is called InvokeRemotely and allows to pass in a delegate that is invoked in the other application, passing in the WinForms control InvokeRemotely was called for.
The only thing you need to make sure is that all input parameter and return values are serializable (if you need any), e.g. simple types like int, string, or lists of such types.
The following (old, but still valid) blog provides some more info on that topic:
https://www.ranorex.com/blog/transferin ... t-control/
Regards,
Alex
Ranorex Team
The only thing you need to make sure is that all input parameter and return values are serializable (if you need any), e.g. simple types like int, string, or lists of such types.
The following (old, but still valid) blog provides some more info on that topic:
https://www.ranorex.com/blog/transferin ... t-control/
Regards,
Alex
Ranorex Team
-
- Posts: 3
- Joined: Mon Jun 18, 2018 8:42 pm
Re: loading an assembly into a .net System.Windows.Forms.Form
Intersting, so would I be correct in saying that I could call invokeremotely twice, one delegate to load the assembly into the AUT then another delegate to invoke any method in that now loaded assembly?
Re: loading an assembly into a .net System.Windows.Forms.Form
You should be able to call methods in that assembly from the first call already...michael.gorman wrote:Intersting, so would I be correct in saying that I could call invokeremotely twice, one delegate to load the assembly into the AUT then another delegate to invoke any method in that now loaded assembly?
Regards,
Alex
Ranorex Team
-
- Posts: 3
- Joined: Mon Jun 18, 2018 8:42 pm
Re: loading an assembly into a .net System.Windows.Forms.Form
Additional information: Action 'invokeremotely' failed on element '{Form:DesktopFormStandalone}'
Looking at the inner exception it appears to be attempting to load the assembly that I am already running from into the AUT app domain just to execute the custom code, I don't want that at all. Is there another way to crack this egg cause I can't have my monster of a testing app actually loaded into the AUT?
HResult=-2146233088
Message=Action 'invokeremotely' failed on element '{Form:DesktopFormStandalone}'.
Name=invokeremotely
Source=Ranorex.Core
StackTrace:
at Ranorex.Core.Element.InvokeAction(String name, Object[] args)
at Ranorex.Control.InvokeRemotely(RemotelyInvokedDelegate deleg)
at R3.Class1.foo() in D:\builds\blast\prototypes\Ranorex\R3\R3\Class1.cs:line 38
InnerException:
HResult=-2146233076
Message=Unable to find assembly 'R3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
Source=mscorlib
StackTrace:
Server stack trace:
at System.Runtime.Serialization.Formatters.Binary.BinaryAssemblyInfo.GetAssembly()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetType(BinaryAssemblyInfo assemblyInfo, String name)
at System.Runtime.Serialization.Formatters.Binary.ObjectMap..ctor(String objectName, String[] memberNames, BinaryTypeEnum[] binaryTypeEnumA, Object[] typeInformationA, Int32[] memberAssemIds, ObjectReader objectReader, Int32 objectId, BinaryAssemblyInfo assemblyInfo, SizedArray assemIdToAssemblyTable)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryObjectWithMapTyped record)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryHeaderEnum binaryHeaderEnum)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Remoting.Channels.CoreChannel.DeserializeBinaryRequestMessage(String objectUri, Stream inputStream, Boolean bStrictBinding, TypeFilterLevel securityLevel)
at System.Runtime.Remoting.Channels.BinaryServerFormatterSink.ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, IMessage& responseMsg, ITransportHeaders& responseHeaders, Stream& responseStream)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at Ranorex.Libs.WinForms.IControlProxy.InvokeRemotely(Delegate deleg, Object inputData, Int32 timeout)
at Ranorex.Libs.RemotingBreaker`1.Invoke[TRes](Func`2 call)
at Ranorex.Plugin.WinFormsFlavorElement.InvokeRemotely(RemotelyInvokedDelegate deleg, Object inputData, Duration timeout)
at Ranorex.Plugin.WinFormsFlavorElement.InvokeAction(Element element, String name, Object[] args)
at Ranorex.Core.Element.InvokeAction(String name, Object[] args)
InnerException:
Looking at the inner exception it appears to be attempting to load the assembly that I am already running from into the AUT app domain just to execute the custom code, I don't want that at all. Is there another way to crack this egg cause I can't have my monster of a testing app actually loaded into the AUT?
Ranorex.Control win1 = Host.Local.FindSingle<Ranorex.Control>("/*[@handle='462902']"); win1.InvokeRemotely(LoadAssembly); public static Object LoadAssembly(System.Windows.Forms.Control ctrl, Object input) { return null; }Ranorex.ActionFailedException occurred
HResult=-2146233088
Message=Action 'invokeremotely' failed on element '{Form:DesktopFormStandalone}'.
Name=invokeremotely
Source=Ranorex.Core
StackTrace:
at Ranorex.Core.Element.InvokeAction(String name, Object[] args)
at Ranorex.Control.InvokeRemotely(RemotelyInvokedDelegate deleg)
at R3.Class1.foo() in D:\builds\blast\prototypes\Ranorex\R3\R3\Class1.cs:line 38
InnerException:
HResult=-2146233076
Message=Unable to find assembly 'R3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
Source=mscorlib
StackTrace:
Server stack trace:
at System.Runtime.Serialization.Formatters.Binary.BinaryAssemblyInfo.GetAssembly()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetType(BinaryAssemblyInfo assemblyInfo, String name)
at System.Runtime.Serialization.Formatters.Binary.ObjectMap..ctor(String objectName, String[] memberNames, BinaryTypeEnum[] binaryTypeEnumA, Object[] typeInformationA, Int32[] memberAssemIds, ObjectReader objectReader, Int32 objectId, BinaryAssemblyInfo assemblyInfo, SizedArray assemIdToAssemblyTable)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryObjectWithMapTyped record)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryHeaderEnum binaryHeaderEnum)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Remoting.Channels.CoreChannel.DeserializeBinaryRequestMessage(String objectUri, Stream inputStream, Boolean bStrictBinding, TypeFilterLevel securityLevel)
at System.Runtime.Remoting.Channels.BinaryServerFormatterSink.ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, IMessage& responseMsg, ITransportHeaders& responseHeaders, Stream& responseStream)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at Ranorex.Libs.WinForms.IControlProxy.InvokeRemotely(Delegate deleg, Object inputData, Int32 timeout)
at Ranorex.Libs.RemotingBreaker`1.Invoke[TRes](Func`2 call)
at Ranorex.Plugin.WinFormsFlavorElement.InvokeRemotely(RemotelyInvokedDelegate deleg, Object inputData, Duration timeout)
at Ranorex.Plugin.WinFormsFlavorElement.InvokeAction(Element element, String name, Object[] args)
at Ranorex.Core.Element.InvokeAction(String name, Object[] args)
InnerException:
Re: loading an assembly into a .net System.Windows.Forms.Form
Put the "LoadAssembly" method in a separate DLL (=library project) and make sure that the DLL is compiled to target "Any CPU". Then only that DLL should be loaded.michael.gorman wrote:Is there another way to crack this egg cause I can't have my monster of a testing app actually loaded into the AUT?
Regards,
Alex
Ranorex Team