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( "PressAny 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!