Hi Oisin,
Thanks for your reply. I tried a late bound call and yes it does work but it
isn't really a viable solution for us (the Powershell scripts were intended
to be written by a test team whose 'programming' skillset isn't the highest).
I believe that for us the better of the two solutions would be to write the
additional layer as you suggest.
I've seen a similar post relating to access of explicitly implemented
interfaces. Hopefully Microsoft will address these 'limitations' in a future
release?!
Thanks again, Adam
"Oisin (x0n) Grehan [MVP]" wrote:
Quote:
> Hi,
>
> It looks like powershell is choking on the transparentproxy/realproxy
> trickery that is remoting. One approach might be that you create your
> own delegating wrapper type to pass to powershell as a workaround.
> E.g. a full class that takes the marshalbyrefobject instance in its
> constructor and its methods just delegate to the transparentproxy
> instance. Another simpler (but uglier) approach might be to use late
> bound calls against the remoted instance:
>
> ps>
> [remotingserver.iremotingservice].getmethod("GetServerName").invoke($objRemServer,
> @())
> TheServerName (hopefully ;-))
>
> This case is definitely a deficiency in powershell and probably needs
> its own adapter.
>
> - Oisin
> PowerShell MVP
> http://www.nivot.org/
>
>
> On Aug 5, 11:38 am, adamhearn <adamhe...@xxxxxx>
> wrote: Quote:
> > The platform is Powershell V1 (tried V2 runtime as well) on Windows XP SP3
> > against an application written using .NET 2.0 SP1.
> >
> > I'm trying to use Powershell to run (script) part of our .NET application
> > but have come across a [serious] issue attempting to call methods on an
> > Interface
> >
> > implemented by a class accessed by .NET Remoting.
> >
> > I've created simple object in order to demonstrate the issue.
> >
> > 1) Interfaces - Declares the contract for the object
> >
> > namespace RemotingInterfaces
> > {
> > using System;
> >
> > public interface IRemotingService
> > {
> > string GetServerName();
> > }
> >
> > }
> >
> > 2) Server - Implements the contract in a class that is also derived from
> > MarshallByRefObject
> >
> > namespace RemotingServer
> > {
> > public class EntryPoint
> > {
> > public static void Main( string[] args )
> > {
> > TcpServerChannel channel = new TcpServerChannel( 9988 );
> > ChannelServices.RegisterChannel( channel, false );
> > RemotingConfiguration.RegisterWellKnownServiceType( typeof(
> > RemotingService ), "RemotingService", WellKnownObjectMode.Singleton );
> > Console.WriteLine( "Press Any Key" );
> > Console.ReadLine();
> > }
> > }
> >
> > public class RemotingService : MarshalByRefObject, IRemotingService
> > {
> > public RemotingService() { }
> >
> > public string GetServerName()
> > {
> > return Dns.GetHostName();
> > }
> >
> > public override object InitializeLifetimeService()
> > {
> > return null;
> > }
> > }
> >
> > }
> >
> > 3) Client - Provides access to the class using a factory pattern
> >
> > namespace RemotingClient
> > {
> > public class RemClient
> > {
> > private IRemotingService resService;
> >
> > public RemClient()
> > {
> > ChannelServices.RegisterChannel( new TcpClientChannel() );
> > }
> >
> > public IRemotingService GetServer()
> > {
> > resService = (IRemotingService) Activator.GetObject( typeof(
> > IRemotingService ), "tcp://localhost:9988/RemotingService" );
> > return resService;
> > }
> > }
> >
> > }
> >
> > Here's an extract of the Powershell script that demonstrates the problem:
> >
> > [Reflection.Assembly]::LoadFrom( $binPath + "\RemotingClient.exe")
> > [Reflection.Assembly]::LoadFrom( $binPath + "\RemotingInterfaces.dll")
> >
> > $objRemClient = New-Object -TypeName RemotingClient.RemClient
> > $objRemServer = $objRemClient.GetServer()
> > $objRemServer.GetType()
> >
> > $objRemServer.GetServerName()
> >
> > The call to GetType() on the $objRemServer object returns the following:
> >
> > TypeHandle : System.RuntimeTypeHandle
> > DeclaringMethod :
> > BaseType : System.Object
> > UnderlyingSystemType : System.MarshalByRefObject
> > FullName : System.MarshalByRefObject
> >
> > Attempting to call GetServerName() on $objRemServer yields the following
> > error:
> >
> > Method invocation failed because [System.MarshalByRefObject] doesn't contain
> > a method named 'GetServerName'.
> >
> > I've tried casting the value using the following syntax:
> >
> > $objRemServer = [RemotingInterfaces.IRemotingService]
> > $objRemClient.GetServer()
> >
> > but this yields the following error:
> >
> > Cannot convert value "RemotingServer.RemotingService" to type
> > "RemotingInterfaces.IRemotingService". Error: "Attempted to call a method
> > declared on type
> >
> > 'System.IConvertible' on an object which exposes
> > 'RemotingServer.RemotingService'."
> >
> > Even reflecting the server types directly in to the Powershell script using:
> >
> > [Reflection.Assembly]::LoadFrom( $binPath + "\RemotingServer.exe")
> > ...
> > $objRemServer = [RemotingServer.RemotingService] $objRemClient.GetServer()
> >
> > yields the following error:
> >
> > Cannot convert value "RemotingServer.RemotingService" to type
> > "RemotingServer.RemotingService". Error: "Attempted to call a method declared
> > on type
> >
> > 'System.IConvertible' on an object which exposes
> > 'RemotingServer.RemotingService'."
> >
> > As can be seen by the error messages, Powershell does actually know what
> > type the object is (RemotingServer.RemotingService) but when accessed
> > directly it
> >
> > implies it is 'only' of type MarshalByRefObject and it does not seem
> > possible to successfully cast to a different type in the object hierarchy..
> >
> > Does anyone know of a way to access the members of the Interface as
> > implemented by an object instance accessed through .NET Remoting? Thanks in
> > advance!
>
>
>
>