C# Late Binding "Unknown Error"

N

nelsonivan

Hi,

i'm trying to reference some objects using reflection and Late Binding
accessing.

The Object API to his methods it's easy to understand, and it's as
"Object.Method" - aka. "Clientes.Existe"-
So, to reference this object, it was simplier to me resolving this
with reflection, and it was something like this:

Type motorPriBS = Type.GetTypeFromProgID("GcpBS601.GCPBS");

object clientes = motorPriBS.i .InvokeMember("Clientes",

System.Reflection.BindingFlags.GetProperty,
null,
hMotorPriBS,
null);

bool existeAl = (bool)motorPriBS.InvokeMember("Existe",

System.Reflection.BindingFlags.InvokeMethod,
null,
comercial,
new object[] {"0002"});


And it works well.

Now, the present situation changed the object API, and it's
referencing to "Object.Property.Method" -aka
"Comercial.Clientes.Existe"-

The code that i wrote is like this:

Type motorPriBS = Type.GetTypeFromProgID("GcpBS601.GCPBS");

//invoke object
object comercial= motorPriBS.InvokeMember("Comercial",

System.Reflection.BindingFlags.GetProperty,
null,
hMotorPriBS,
null);

//invoke propertie
object clientes = motorPriBS.InvokeMember("Clientes",
System.Reflection.BindingFlags.GetProperty,
null,
comercial,
null);

//invoke method
bool existeAl = (bool)motorPriBS.InvokeMember("Existe",

System.Reflection.BindingFlags.InvokeMethod,
null,
comercial,
new object[] {"0002"});

And, this don't work. When i invoke the method, it returns a error
"Unknown Name" and it seems that the object don't recognize the method
name "Existe". And i've sure it really exists.


Can anyone give a help in this matter?
 
J

Jon Skeet [C# MVP]

On Jan 21, 2:04 pm, (e-mail address removed) wrote:

And, this don't work. When i invoke the method, it returns a error
"Unknown Name" and it seems that the object don't recognize the method
name "Existe". And i've sure it really exists.

Can anyone give a help in this matter?

It would be a lot easier to follow this if you could produce a short
but complete program to demonstrate the problem.

Looking at the chaining though, I'd have expected the 4th parameter to
your last InvokeMember call to be clientes instead of comercial.

Jon
 
N

nelsonivan

On Jan 21, 2:04 pm, (e-mail address removed) wrote:




It would be a lot easier to follow this if you could produce a short
but complete program to demonstrate the problem.

Looking at the chaining though, I'd have expected the 4th parameter to
your last InvokeMember call to be clientes instead of comercial.

Jon

Sorry, my apologise. The error that Jon says, it's because a "copy/
paste" problem.

Above the complete code for the problem that i have.

Thanks in advance,
Nelson.

--------------------------------------------------------------------------------------------------------------------------

object hMotorPriBS = null;
//object hMotorPriBE; // Isto é o proxy para a DLL
//string primaveraServidor = "laptop-des05\v7";
string primaveraBaseDados = "DOROTEIAS";
string primaveraUtilizador = "";
byte[] primaveraPassword = new byte[] {};

Type motorPriBS = Type.GetTypeFromProgID("ErpBS700.ErpBS");

motorPriBS = this.AbreEmpresaTrabalho(out
hMotorPriBS,primaveraBaseDados, primaveraUtilizador,
primaveraPassword);

if (motorPriBS!=null) {

try {
object comercial = motorPriBS.InvokeMember("Comercial",
System.Reflection.BindingFlags.GetProperty,
null,
hMotorPriBS,
null);

object clientes = motorPriBS.InvokeMember("Clientes",
System.Reflection.BindingFlags.Default
| System.Reflection.BindingFlags.GetProperty,
null,
comercial,
null);

bool existeAl = (bool)motorPriBS.InvokeMember("Existe",
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.Public
| System.Reflection.BindingFlags.InvokeMethod,
null,
clientes,
new object[] {"0002"});

if (existeAl)
Trace.WriteLine("Cliente Existe");
else
Trace.WriteLine("Cliente Não Existe");

} catch(Exception ex) {
MessageBox.Show(ex.Message);
}

// Invoca o método FechaEmpresaTrabalho
motorPriBS.InvokeMember("FechaEmpresaTrabalho",
System.Reflection.BindingFlags.InvokeMethod, null, hMotorPriBS, null);
}
}
--------------------------------------------------------------------------------------------------------------------------
 
N

nelsonivan

This is my complete code, for my class test.

Thanks,


using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Windows.Forms;

namespace LateBindingV7 {
/// <summary>
/// Summary description for test.
/// </summary>
public class Test {

/* Constructor */
public Test() {
}

public void invocation() {

object hMotorPriBS = null;
string primaveraBaseDados = "DOROTEIAS";
string primaveraUtilizador = "";
byte[] primaveraPassword = new byte[] {};

Type motorPriBS = Type.GetTypeFromProgID("ErpBS700.ErpBS");

motorPriBS = this.AbreEmpresaTrabalho(out
hMotorPriBS,primaveraBaseDados, primaveraUtilizador,
primaveraPassword);

if (motorPriBS!=null) {

try {
object comercial = motorPriBS.InvokeMember("Comercial",
System.Reflection.BindingFlags.GetProperty,
null,
hMotorPriBS,
null);

object clientes = motorPriBS.InvokeMember("Clientes",
System.Reflection.BindingFlags.GetProperty,
null,
comercial,
null);

bool existeAl = (bool)motorPriBS.InvokeMember("Existe",
System.Reflection.BindingFlags.InvokeMethod,
null,
clientes,
new object[] {"0002"});

if (existeAl)
Trace.WriteLine("Cliente Existe");
else
Trace.WriteLine("Cliente Não Existe");

} catch(Exception ex) {
MessageBox.Show(ex.Message);
}

motorPriBS.InvokeMember("FechaEmpresaTrabalho",
System.Reflection.BindingFlags.InvokeMethod, null, hMotorPriBS, null);
}
}

/// <summary>
/// Verifica se a empresa de trabalho existe.
/// </summary>
private bool ExisteEmpresaTrabalho(string Empresa, string Login,
byte[] Password) {
return true;
}

/// <summary>
/// Abre empresa de trabalho Primavera.
/// </summary>
/// <param name="Empresa"></param>
/// <param name="Login"></param>
/// <param name="Password"></param>
/// <returns></returns>
internal Type AbreEmpresaTrabalho(out object Proxy , string Empresa,
string Login, byte[] Password) {

Type motorPriBS = Type.GetTypeFromProgID("ErpBS700.ErpBS");

try {

object hMotorPriBS = Activator.CreateInstance(motorPriBS); // Isto
é o proxy para a DLL

string password =
System.Text.UTF8Encoding.UTF8.GetString(Password);

// Invoca o método AbreEmpresaTrabalho
motorPriBS.InvokeMember("AbreEmpresaTrabalho",
System.Reflection.BindingFlags.InvokeMethod, null, hMotorPriBS, new
object[] {0,Empresa,Login,password.Replace("\0","").ToString()});

Proxy = hMotorPriBS;

return motorPriBS;
}
catch(Exception e) {
motorPriBS = null;
throw new
Exception(e.InnerException.Message.Replace("Exercício","Empresa"));
}
}
}
}
 
J

Jon Skeet [C# MVP]

This is my complete code, for my class test.

That's not going to be much use to us without the type returned for
"ErpBS700.ErpBS" though.

We need to have something that will be able to work from just the
systems we already have...

Jon
 
W

Willy Denoyette [MVP]

This is my complete code, for my class test.

Thanks,


using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Windows.Forms;

namespace LateBindingV7 {
/// <summary>
/// Summary description for test.
/// </summary>
public class Test {

/* Constructor */
public Test() {
}

public void invocation() {

object hMotorPriBS = null;
string primaveraBaseDados = "DOROTEIAS";
string primaveraUtilizador = "";
byte[] primaveraPassword = new byte[] {};

Type motorPriBS = Type.GetTypeFromProgID("ErpBS700.ErpBS");

motorPriBS = this.AbreEmpresaTrabalho(out
hMotorPriBS,primaveraBaseDados, primaveraUtilizador,
primaveraPassword);

if (motorPriBS!=null) {

try {
object comercial = motorPriBS.InvokeMember("Comercial",
System.Reflection.BindingFlags.GetProperty,
null,
hMotorPriBS,
null);

object clientes = motorPriBS.InvokeMember("Clientes",
System.Reflection.BindingFlags.GetProperty,
null,
comercial,
null);

bool existeAl = (bool)motorPriBS.InvokeMember("Existe",
System.Reflection.BindingFlags.InvokeMethod,
null,
clientes,
new object[] {"0002"});

if (existeAl)
Trace.WriteLine("Cliente Existe");
else
Trace.WriteLine("Cliente Não Existe");

} catch(Exception ex) {
MessageBox.Show(ex.Message);
}

motorPriBS.InvokeMember("FechaEmpresaTrabalho",
System.Reflection.BindingFlags.InvokeMethod, null, hMotorPriBS, null);
}
}

/// <summary>
/// Verifica se a empresa de trabalho existe.
/// </summary>
private bool ExisteEmpresaTrabalho(string Empresa, string Login,
byte[] Password) {
return true;
}

/// <summary>
/// Abre empresa de trabalho Primavera.
/// </summary>
/// <param name="Empresa"></param>
/// <param name="Login"></param>
/// <param name="Password"></param>
/// <returns></returns>
internal Type AbreEmpresaTrabalho(out object Proxy , string Empresa,
string Login, byte[] Password) {

Type motorPriBS = Type.GetTypeFromProgID("ErpBS700.ErpBS");

try {

object hMotorPriBS = Activator.CreateInstance(motorPriBS); // Isto
é o proxy para a DLL

string password =
System.Text.UTF8Encoding.UTF8.GetString(Password);

// Invoca o método AbreEmpresaTrabalho
motorPriBS.InvokeMember("AbreEmpresaTrabalho",
System.Reflection.BindingFlags.InvokeMethod, null, hMotorPriBS, new
object[] {0,Empresa,Login,password.Replace("\0","").ToString()});

Proxy = hMotorPriBS;

return motorPriBS;
}
catch(Exception e) {
motorPriBS = null;
throw new
Exception(e.InnerException.Message.Replace("Exercício","Empresa"));
}
}
}
}



This is not a complete sample, notably we are missing where clientes comes
from in :

bool existeAl = (bool)motorPriBS.InvokeMember("Existe",
System.Reflection.BindingFlags.InvokeMethod,
null,
clientes,
new object[] {"0002"});

Also, we need to know what ("ErpBS700.ErpBS") is referring to, my guess is
that it's a COM object. If this is the case we need to see the IDL or the
oleview output. Another question is, why are you late binding against COM?,
this is for masochists from C#.

Willy.
 
N

nelsonivan

That's not going to be much use to us without the type returned for
"ErpBS700.ErpBS" though.

We need to have something that will be able to work from just the
systems we already have...

Jon

Hi Jon,
thanks again.

I only have to know, is how to invoke a method from my object, when at
begin it works and now with a different API in same object the
invocation won't work.
In order to understand, in VB the direct invocation of the object, is
something like this:

Set sMotor7 = New ErpBS700.ErpBS
Set eCli7 = New GcpBE700.GcpBECliente

sMotor7.AbreEmpresaTrabalho
bool = sMotor7.Clientes.Existe "0002"


Now the diference is

Set sMotor7 = New ErpBS700.ErpBS
Set eCli7 = New GcpBE700.GcpBECliente

sMotor7.AbreEmpresaTrabalho
bool = sMotor7.Comercial.Clientes.Existe "0002"


In first example, the C# Late Binding code, works very well. but in
the second example with a new Property (Comercial) between object and
the initial property (Clientes), the Late binding invocation won't
work.
I want to know if there's any reason for this don't work.


Nelson.
 
N

nelsonivan

As Willy indicated, why are you doing late-binding with COM? Can't you just
set a reference to the COM dll from the VS.NET COM tab and let it generatea
Runtime Callable Wrapper assembly for you, and code against that?
--Peter
Site:http://www.eggheadcafe.com
UnBlog:http://petesbloggerama.blogspot.com
MetaFinder:http://www.blogmetafinder.com


Well, it's been really anoying. (but i am not so masochist)

For testing, i've made a DLL with the same structure as the object
"ErpBS700.ErpBS", and it works fine. After, register and unregister
those DLL's and try another solutions, i realise that this just don't
work for some reason that i missing.
Now, I m going to change all code, to implement a wrapper and use it
to call the methods that i need.

Thanks to all,
Nelson.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top