C# and VBScript Interoperability - Forms - c#

I am essentially trying to call a C# form from a vbscript. I have been able to get the interoperability to work on non-forms. The following works:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using InteropTestingForm;
[assembly:System.CLSCompliant(true)]
[assembly: ComVisible(true)]
[assembly:Guid("a22f4018-8f32-4c02-a748-6701fb617aa3")]
namespace InteropTesting
{
[Guid("a22f4018-8f32-4c02-a748-6701fb617aa3")]
public class TestReply
{
public string salutation;
public string name;
public string time;
}
[Guid("a22f4018-8f32-4c02-a748-6701fb617aa4")]
public class TestObj
{
public TestObj() { }
public TestReply SayHello(string addressee)
{
//Application.EnableVisualStyles();
//Application.SetCompatibleTextRenderingDefault(false);
//Application.Run(Form1());
return SayHello(addressee, "hello");
}
public TestReply SayHello(string addressee, string greeting)
{
string x = String.Format("{0}, {1}!", greeting, addressee);
Console.WriteLine("{0}", x);
TestReply r = new TestReply
{
salutation = greeting,
name = addressee,
time = System.DateTime.Now.ToString("u")
};
return r;
}
}
}
As can be seen in my SayHello() function, I want to run another form, possibly in the same namespace. I am not sure how to accomplish this. I keep getting the following error: "The type or namespace name Form1() could not be found (are you missing a using directive or an assembly reference)? when I try to run the following command from a Visual Studio command prompt:
csc.exe /t:library /debug+ /keyfile:InteropTesting.snk /out:InteropTesting.dll TestObj.cs

Related

Reflection instead .NET-to-.NET scenario

I created Person.dll and register it(regsvcs.exe) in Command Promt for Visual Studio 2019. As a result of registration, I got Person.tlb. I tried to add Person.tlb in console project as reference COM component but I got warning MSB3290.
warning MSB3290: Failed to create the wrapper assembly for type
library "{8b1098cb-d453-4dc7-96ac-52df54d0a2ce}". Type library
'Person' was exported from a CLR assembly and cannot be re-imported as
a CLR assembly.
How I can to add Person.tlb in console project using reflection?
Person.dll:
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
using System.Runtime.InteropServices;
using System.EnterpriseServices;
namespace COM
{
[ClassInterface(ClassInterfaceType.None)]
public class Person : ServicedComponent, COM.IPerson
{
public string FirstName { get; set; }
public string LastName { get; set; }
public bool IsMale { get; set; }
public void Persist(string FilePath)
{
StreamWriter oFile = new StreamWriter(FilePath);
XmlSerializer oXmlSerializer = new XmlSerializer(typeof(Person));
oXmlSerializer.Serialize(oFile, this);
oFile.Flush();
oFile.Close();
}
static public Person Retrieve(string FilePath)
{
StreamReader oFile = new StreamReader(FilePath);
XmlSerializer oXmlSerilizer = new XmlSerializer(typeof(Person));
Person oPerson = oXmlSerilizer.Deserialize(oFile) as Person;
return oPerson;
}
}
}
Console project:
using System;
namespace Test10
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
COM.Person per = new COM.Person();
per.FirstName = "Maxim";
per.LastName = "Donax";
per.Persist(#" C:\myFile.xml ");
}
}
}
I used other way: created Person.dll in Visual Studio and registerd it(regsvcs.exe). After use reference Person.tlb in Visual Basic 6.0.

What am i missing from my interface or assemblies?

I have this following interface IQueueClient implements AZureBus class;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Messaging;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.Management.ServiceBus;
namespace MessageQueueApp
{
public class AZBus:IQueueService
{
public string ConnectionString { get; set; }
public string QueueName { get; set; }
private static IQueueClient queueClient;
public void Send(string payload)
{
queueClient = new QueueClient(ConnectionString, QueueName);
var message = new Message(Encoding.UTF8.GetBytes(payload));
queueClient.SendAsync(message).Wait();
}
}
}
I am getting an error on my new object name QueueClient() with argument types ConnectionString, QueueName. As well my SendAsync(message).Wait(); What am i missing from this code? Please help and show me guidance to this, thanks.
You are missing a using statement:
using Microsoft.Azure.ServiceBus;

Why is my ASP C# WCF Service not working?

I am working on a project for school and I need to create a WCF service that I can use in my original solution.
I created the service by going to File -> New Project -> WCF Service Application (add to solution) and then I added the service reference by right clicking References under Assignment8 solution and new reference. Then I discovered services in the solution and added the Product service.
I am currently getting the error:
'Assignment8.Product.ProductClient' does not contain a definition for 'UpdateProduct' and no extension method 'UpdateProduct' accepting a first argument of type 'Assignment8.Product.ProductClient' could be found (are you missing a using directive or an assembly reference?)
The error occurs in UpdateProduct.aspx.cs on the line with the if statement in the Button1_Click method. What am I doing wrong?
Here are my files:
IProduct.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace ProductService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
[ServiceContract]
public interface IProduct
{
[OperationContract]
string GetData(int value);
[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);
[OperationContract]
Boolean UpdateProduct(int productID, string productName, string productDescription, decimal productPrice, decimal productCost);
// TODO: Add your service operations here
}
// Use a data contract as illustrated in the sample below to add composite types to service operations.
[DataContract]
public class CompositeType
{
bool boolValue = true;
string stringValue = "Hello ";
[DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}
[DataMember]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
}
}
Product.svc
<%# ServiceHost Language="C#" Debug="true" Service="ProductService.Product" CodeBehind="Product.svc.cs" %>
Product.svc.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace ProductService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing this service, please select Service1.svc or Service1.svc.cs at the Solution Explorer and start debugging.
public class Product : IProduct
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite == null)
{
throw new ArgumentNullException("composite");
}
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return composite;
}
public bool UpdateProduct(int productID, string productName, string productDescription, decimal productPrice, decimal productCost)
{
return false;
}
}
}
UpdateProduct.aspx.cs
protected void Button1_Click(object sender, EventArgs e)
{
using (Product.ProductClient orderproxy = new Product.ProductClient())
{
if(orderproxy.UpdateProduct(Request.QueryString["ID"], txtProductName.Text, txtProductName.Text, txtProductDescription.Text, Convert.ToDecimal(txtProductPrice.Text), Convert.ToDecimal(txtProductCost.Text))){
Response.Redirect("~/ProductList.aspx");
} else {
lblStatus.Text = "The product could not be updated.";
}
}
}
Your function definition of UpdateProduct takes only 5 arguments but in your call you are passing 6 arguments

System.TypeLoadException: Access is denied when using MessagePack

I'm trying to use MessagePack to serialize my objects, but whenever I try to run the serialization I'm getting an Unhandled Exception error.
Here's my code:
CSCDP_TCPClient.cs
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Diagnostics;
using System.IO;
using MsgPack;
using MsgPack.Serialization;
namespace CSCDPApp
{
class CSCDP_TCPClient
{
public void Connect(string server, int portno, Script Script)
{
var serializer = MessagePackSerializer.Get<Script>();
var tempstream = new MemoryStream();
serializer.Pack(tempstream, script);
tempstream.Position = 0;
var deserializedObject = serializer.Unpack(tempstream);
Debug.WriteLine("Same object? {0}", Object.ReferenceEquals(script, deserializedObject));
}
}
}
Script.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CSCDPApp
{
class Script
{
public string cardID;
public string time;
public string device;
public string command;
public Script()
{
//Parameterless Constructor for serialization
}
public Script(string cardID, string time, string device, string command)
{
this.cardID = cardID;
this.time = time;
this.device = device;
this.command = command;
}
}
}
And I'm just calling it in main with:
CSCDP_TCPClient tcpclient = new CSCDP_TCPClient();
Script tempscript = new Script("test1","test2","test3","test4");
tcpclient.Connect("0.0.0.0",1,tempscript);
And here's the error I'm getting:
Unhandled Exception: System.TypeLoadException: Access is denied: 'MsgPack.Serial
ization.MessagePackSerializer`1[CSCDPApp.Script]'.
at System.Reflection.Emit.TypeBuilder.TermCreateClass(RuntimeModule module, I
nt32 tk, ObjectHandleOnStack type)
at System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()
at System.Reflection.Emit.TypeBuilder.CreateType()
at MsgPack.Serialization.EmittingSerializers.FieldBasedSerializerEmitter.Crea
teConstructor[T]()
at MsgPack.Serialization.EmittingSerializers.SerializerEmitter.CreateInstance
[T](SerializationContext context)
at MsgPack.Serialization.EmittingSerializers.ILEmittingSerializerBuilder`2.<>
c__DisplayClass5a.<CreateSerializerConstructor>b__59(SerializationContext contex
t)
at MsgPack.Serialization.AbstractSerializers.SerializerBuilder`3.BuildSeriali
zerInstance(SerializationContext context)
at MsgPack.Serialization.AutoMessagePackSerializer`1..ctor(SerializationConte
xt context, ISerializerBuilder`1 builder)
at MsgPack.Serialization.MessagePackSerializer.CreateInternal[T](Serializatio
nContext context)
at MsgPack.Serialization.SerializationContext.GetSerializer[T](Object provide
rParameter)
at MsgPack.Serialization.MessagePackSerializer.Get[T](SerializationContext co
ntext, Object providerParameter)
at CSCDPApp.CSCDP_TCPClient.Connect(String server, Int32 portno, Script scrip
t) in d:\TFS\MSVC 2013_CTSDev1\CommonComponents\sdnet\tools\CSCDPService\CSCDPAp
p\CSCDP_TCPClient.cs:line 21
at CSCDPApp.Program.Main(String[] args) in d:\TFS\MSVC 2013_CTSDev1\CommonCom
ponents\sdnet\tools\CSCDPService\CSCDPApp\Program.cs:line 64
I have my visual studio project in my D: drive, and I've checked that permissions are correct. I have the MessagePack.dll in the same directory as all my compiled executeables and have the reference linked. Is there anything I might possibly be missing?
Figured it out! My Script class wasn't declared public which is why the serializer couldn't find it

why my first WCF Server doesn't work (wrong value returned to client)

This is my first WCF Server:
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
namespace Myns.MBClient
{
[ServiceContract]
public interface IManagementConsole
{
[OperationContract]
ConsoleData GetData(int strategyId);
}
[ServiceContract]
public class ConsoleData
{
private int currentIndicator;
[OperationContract]
public double GetCurrentIndicator()
{
return currentIndicator;
}
public void SetCurrentIndicator(int currentIndicator)
{
this.currentIndicator = currentIndicator;
}
}
class ManagementConsole : IManagementConsole
{
public ConsoleData GetData(int strategyId)
{
ConsoleData data = new ConsoleData();
data.SetCurrentIndicator(33);
return data;
}
}
}
In client I just call pipeProxy.GetData(0).GetCurrentIndicator()
Why program prints 0 while it supposed to print 33?
Client code (which I think has no problems):
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using Commons;
using myns.MBClient;
namespace myns.MBClientConsole
{
class Program
{
static void Main(string[] args)
{
ChannelFactory<IManagementConsole> pipeFactory =
new ChannelFactory<IManagementConsole>(
new NetNamedPipeBinding(),
new EndpointAddress(
"net.pipe://localhost/PipeMBClientManagementConsole"));
IManagementConsole pipeProxy =
pipeFactory.CreateChannel();
while (true)
{
string str = Console.ReadLine();
Console.WriteLine("pipe: " +
pipeProxy.GetData(0).GetCurrentIndicator());
}
}
}
}
If you create your own complex type to use with WCF you have to add a DataContract attribute instead of a ServiceContract, and you should use fields/properties that are decorated with DataMember. And do yourself a favor and use plain DTOs (DataTransferObjects - Objects with only fields/properties but no behavior):
[DataContract]
public class ConsoleData
{
[DataMember]
public int CurrentIndicator {get;set;}
}
You can find more on this here

Categories

Resources