Simple COM+ server throws unexpected Exception - c#

I wrote a simple ServicedComponent
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.EnterpriseServices;
namespace ComPlusServer
{
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
[Guid("9C674ECA-1B71-42EA-9DB2-9A0EA57EC121")]
[Description("Hello Server")]
public class HelloServer : ServicedComponent
{
[Description("Say Hello!")]
public String SayHello()
{
return "Hello!, ";
}
}
}
and a Windows Forms application
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using ComPlusServer;
namespace Client
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
HelloServer server = new HelloServer();
MessageBox.Show(server.SayHello(), "Message from HelloServer");
}
}
}
on the Component Services MMC, on the application properties, security tab I lowered Authentication Level for Calls to None and Impersonation Level to Identify and Unchecked Enforce access checks for this application on Authorization.
I keep getting a ServicedComponentException exception saying
Method-level role based security requires an interface definition for
class method.
Any idea on this?

I believe that it means that methods of your Component class needs to be defined in an interface.
[ComVisable(true)]
public interface IHelloServer
{
public String SayHello();
}
Now have your componet class implement the interface:
[ComVisable(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComDefaultInterface(typeof(IHelloServer))]
[Guid("9C674ECA-1B71-42EA-9DB2-9A0EA57EC121")]
[Description("Hello Server")]
public class HelloServer : ServicedComponent, IHelloServer
{
[Description("Say Hello!")]
public String SayHello()
{
return "Hello!, ";
}
}

Related

Expected class, delegate, enum, interface, or struct (CS1518)

simple code here and the answers I find don't seem to work.
I'm using
SharpDevelop Version : 3.2.1.6466
.NET Version : 2.0.50727.5485
The problem is the error code
Expected class, delegate, enum, interface, or struct (CS1518).
Any ideas?
Program.cs codes:
using System;
using System.Threading;
namespace Threshold
{
public class Class1
{
public Class1()
{
Heritage YOLO = new Heritage();
YOLO.Fractal();
}
}
static void Main()
{
//do nothing
}
}
The cs file it calls is:
using System;
using System.Threading;
namespace Threshold
{
public class Heritage
{
int Fractal()
{
//Do stuff.
}
}
internal partial class DefineConstants
{
public const string DRIVERPATH = "d:\\tc\\bgi";
}
}
Please help with a fix.
Thanks.
Your main method is outside the class. Put it inside.

I can't access my class property

I have this C# class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Handler.FTPClient
{
public class FTP
{
private static string _message = "This is a message";
public static String message
{
get { return _message; }
set { _message = value; }
}
public FTP()
{
}
public static String GetMessage()
{
return message;
}
}
}
And am trying to call it with this:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Handler.FTPClient;
namespace swift_ftp
{
public partial class FTP : Form
{
FTP ftp;
public FTP()
{
InitializeComponent();
}
private void btnClose_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void FTP_Load(object sender, EventArgs e)
{
ftp = new FTP();
MessageBox.Show(FTP.message);
}
}
}
But for some reason, I am unable to call the property, is there something I have not done? I have also done this without static and got the same result -_-
Sorry for the stupid and basic question, it's just been such a while since I have done C#!
(I have added the ref to the second project which is where the ftp class library is held)
You have two classes with the same name. Try
ftp = new Handler.FTPClient.FTP()
to make sure you instantiate the right class.
Don't forget the variable in the class itself:
Handler.FTPClient.FTP ftp;
You should avoid the same name for different classes for exactly this reason. Since your FTP class inherits from a Form I assume it is a window ... so refactor it to "FTPWindow" and you have less problems and the code is easier to read.
Partial classes are only possible in the same assembly and the same namespace. Your (partial) classes reside in different namespaces.
See https://msdn.microsoft.com/en-us/library/wa80x488.aspx

Functions inside a static class need the name of the class to be called

I have a class named MyFillerClass in the file MyFillerClass.cs like so :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace trial
{
public static class MyFillerClass
{
public static List<string> returnCategoryNames()
{
List<string> catNames = new List<string>();
catNames.Add("one");
catNames.Add("two");
catNames.Add("three");
catNames.Add("Others");
return catNames;
}
}
}
now when i want to call it from somewhere else (like a form class) :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace trial
{
public partial class Form1 : Form
{
static string lastSelectedCategory;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
listBox1.DataSource = returnCategoryNames(); //error : The name 'returnCategoryNames' does not exist in the current context
lastSelectedCategory = listBox1.SelectedValue.ToString();
}
private void listBox1_SelectedValueChanged(object sender, EventArgs e)
{
lastSelectedCategory = listBox1.SelectedValue.ToString();
System.Diagnostics.Debug.Print("### User choosed " + lastSelectedCategory + " category");
}
}
}
the line "listBox1.DataSource = returnCategoryNames();" produce an error as indicated in the code ,to fix it i have to adjust it to "listBox1.DataSource = MyFillerClass.returnCategoryNames();".
the question is : in a long program that can add a lot of typing ,can i adjust the class MyFillerClass in such a way that i can just call the function like so : returnCategoryNames() ?
No, not in C# up to 5.0. You need to prefix the static method name with the class name.
However, in C# 6.0 there will be static using statements available. This new language feature will allow you to access directly static classes methods.
Yo can't do it in C# yet. To do it, you need to do a none static class and none static method.
You can do an extension method.
To call a function from a class you need to have an object created for that class then only you can call the method defined in the class.
In case of static class no need to create any object. you have to direct call the method followed by the class name.
In your case
MyFillerClass.returnCategoryNames();

Updating form elements from classes that don't have access to them

I want to access certain form elements from classes that normally don't have access to them. Allow me to illustrate the problem.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;
using System.Collections;
namespace MyApp {
public partial class MyApp : Form
{
public MyApp()
{
InitializeComponent();
// Code
}
public void updateLabel(string message)
{
myLabel.Text = message;
}
}
public class NewClass
{
public NewClass()
{
// I want to call updateLabel("My message") here, but 'MyApp.updateLabel("My message");' didn't work even though I made updateLabel public
}
}
}
How do I tackle this issue? I'm relatively new to C#, but I have experience with C, PHP, Java and JavaScript. I'm using Visual C# 2010 Express.
You need to pass the instance of the MyApp class to the NewClass class.
You can then call UpdateLabel on the MyApp instance, without making the label public.
Since updateLabel is a non-static member method in MyApp, you need to create an instance of MyApp before calling any of its instance methods.
use following line of code inside NewClass ctor:
MyApp myapp = new MyApp();
myapp.updateLabel("Hello World");
I assume MyApp class is already instantiated, in which case you have to pass the reference to NewClass (may be over constructor) as SLaks already mentioned.
May be technique below will be helpfull. It may use Action's or Func's:
[Test]
public void ActionsTest()
{
var parent = new Parent();
parent.Child.RaiseCallFromParent();
parent.Child.RaiseCallInParent();
}
public class Parent
{
private readonly Child _child = new Child();
public Parent()
{
Child.ActionToCallMethodFromParent = methodCalledFromChild;
Child.ActionToBeCalledInParent += actionCalledInParent;
}
public Child Child
{
get { return _child; }
}
private void actionCalledInParent()
{
Console.WriteLine("It is called in parent on child initiative.");
}
private void methodCalledFromChild()
{
Console.WriteLine("It is called from child");
}
}
public class Child
{
public Action ActionToCallMethodFromParent;
public Action ActionToBeCalledInParent;
public void RaiseCallFromParent()
{
//This works in cases when you need to consume something from Parent but here you cannot take it directly
if (ActionToCallMethodFromParent != null)
ActionToCallMethodFromParent();
}
public void RaiseCallInParent()
{
//This works like an event
if (ActionToBeCalledInParent != null)
ActionToBeCalledInParent();
}
}
Here's my own proposed solution. I pass the myLabel as a parameter to the class constructor that needs access to the label, like so:
The call:
NewClass newClassObj = new NewClass(myLabel);
The class:
public class NewClass
{
public NewClass(Label myLabel)
{
myLabel.Text = "Hello world!";
}
}
Unless this a bad programming practice, I'd prefer this solution. Thoughts?
Its probably better to raise an event from your own class then catch it in the form and update the controls from there, then you are not connecting your logic to specific UI elements.
Change public void updatelabel(string message) to public static void updatelabel(string message).
Then from new class you would access it like myapp.updatelabel(message).
You would of have to add using myapp to top of new class.

How do I add common C# code to a Visual C# 2008 Express project/solution?

(I still feel like a complete newbie in MS Visual environments... so please bear with!)
I'm using Microsoft Visual C# 2008 Express Edition.
I have a project and in that project are two different forms. The .cs file for each form starts out:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace MyNameSpace
{
public partial class MyFormName : Form
{
...
(...and the second is "MyFormName2" but no differences besides that)
I want to write a function that I know both forms are going to need to access. I right-clicked on my project, selected "Add", selected "New Item" then selected "Code File" and named my file "Common.cs" and it gave me a completely blank file that's in my project.
How do I set this up...? I thought I should do the following...
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace MyNameSpace
{
}
...but then when I try to add a function like:
public void mytestfunc() {
}
within that namespace I get the following error:
"Expected class, delegate, enum, interface, or struct"
How do I set things up so I can have "mytestfunc" be available to both MyFormName and MyFormName2?
Thanks!
-Adeena
UPDATE:
Understand (now) that everything must be in a class, but then I don't understand how to really use it. Does that mean I have to create an object? This common function happens to just be some math...
so now if I have this:
namespace MyNameSpace
{
public class MyCommonClass
{
public void testFunc()
{
MessageBox.Show("Hee hee!");
return;
}
}
}
...how do I call testFunc from my Form? Must I do the following:
MyCommonClass temp = new MyCommonClass;
temp.testFunc();
or is there another way to call testFunc?
If you do something like:
namespace MyNameSpace
{
public class myclass
{
public myMethod()
{
// Code
}
}
}
You will be able to instantiate and access it. If you change it to:
namespace MyNameSpace
{
public class myclass
{
public static myMethod()
{
// Code
}
}
}
You will be able to call myClass.myMethod without instantiating a new myClass.
The short answer is that everything needs to be inside a class; I'd suggest you sit down with a basic tutorial to help you get to grips with the basics...
Code need to be inside classes.
It would look something like this:
using System;
namespace MyNameSpace
{
public class CommonHelper
{
public string FormatMyData(object obj)
{
//do something
return String.Empty;
}
}
}
If the function you call is not related to the forms, make it static
namespace myns
{
public static class myhelper
{
public static void DoSomething()
{
}
}
}
and call the method using myhelper.DoSomething();
If the function you want to call is somehow form-related, e.g. common functionality across multiple forms, derive a class from Form (does not need a visual form) and make it base class of the visual forms:
namespace myns
{
public class MyFormBase : Form
{
protected void DoSomethingWithTheForm()
{
}
}
}
and in your form's .cs:
namespace myns
{
public partial class MyFormName : MyFormBase
{
}
}

Categories