Communicate with main window class from CodeDom compiled code C# Wpf - c#

As the title suggests I am having a bit of trouble communicating with my wpf application's MainWindow.cs class during runtime when the code compiles.
Context:
This is a application I am writing for myself that utilizes CodeDom's compiler to compile code stored in xml format at runtime or in a triggered event(like a button or voice command)
The compiler is working neatly but I have been stuck at communicating with my classes from the original application.(MainWindow.cs)
I would like to be able to call functions and access variables from within the runtime compiled CodeDom Scripts. I have found method invoking but I don't quite understand how it works yet, any help would be appreciated!
Example of what I want to do:
Main Window Class Example
namespace WpfOverlay
{
public partial class MainWindow : Window
{
public string AccessThis;
public void ExampleFunctionToAccess(string InputString)
{
AccessThis = InputString;
}
}
}
And access that class to call ExampleFunctionToAccess(); from a CodeDom Compiled script/class in a different namespace (if possible I wouldn't mind having them in the same namespace)

The fact that you compile it at runtime has no bearing on your actual problem, what you actually want is to implement any of the myriad forms possible of IPC.
I recommend an UDP client/server approach, it's relatively easy to implement robustly.

Related

Application .NET which compile code in Windows form

I have problem. I can't find mechanism in .Net which allow me compile code in Windows form.
I want have 1 textbox with code and later compiled code show in another box.
How I can do this?
It sounds like you want to use a C# compiler from within your Windows Forms app, but I'm unsure what your other box would show.
If you're looking for just compiling and visually displaying IL, there are certainly ways to call Roslyn from Windows Forms.
If you're looking to dynamically generate a GUI, your options are a little less clear. I would consider exposing your own wrapper functions to another language. I would consider using Moonsharp to compile Lua code on the fly. IronPython would also work. I'm unfamiliar with whether F# language services could be invoked in a similar way, but these are options I'd consider.
If you're specifically looking to compile C# and use the results to display a WinForms GUI, you'll need to use CodeDOM. CodeDOM is a pretty deep rabbit hole even if it's powerful, and it won't be easy to sandbox any GUI it renders to the output container you have in mind.
As has been mentioned, compiling code using Roslyn is certainly the way forward.
If you wish to see some output by executing the compiled code you may wish to create an abstract class for script writing which provides an entry point and a way of reporting output. You could then compile the script into a dll and use reflection to load the output assembly, instantiate an instance of your class (a class that implements ScriptTemplate below) and execute via the entry point.
abstract class ScriptTemplate
{
public abstract void Main();
public string Output
{
get;
protected set;
}
}
Your form could then write the Output property to a text box for example.
class Script : ScriptTemplate
{
public override void Main()
{
Output = "Hello world!";
}
}

System.InvalidCastException trying to build a COM client and a COM server in C#

I'm trying to build a COM client which has to instantiate a in-process COM server in C#.
I made two C# projects: one for the client and one for the server. Both projects use x86 target platform and the latter has the option "Register for COM interop" set. I'm using Visual Studio 2013 on a 64bit Windows 7 and compiling with .net 4.
This is the server code:
using System.Runtime.InteropServices;
namespace ComRibbonApplicationMenuServer
{
[ComVisible(true)]
[Guid("CCF43AAC-0822-4C36-90FD-2AFF7B94E71D")]
public interface IComRibbonApplicationMenuServer
{
[DispId(1)]
int OpenWindow();
}
[ComVisible(true)]
[Guid("38B1DE85-BC15-48E1-AFAF-4A7EA506256B")]
[ClassInterface(ClassInterfaceType.None)]
public class ComRibbonApplicationMenuServerClass : IComRibbonApplicationMenuServer
{
public ComRibbonApplicationMenuServerClass()
{
// Needed for COM
}
public int OpenWindow()
{
return 33;
}
}
}
And this is the client:
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace ComRibbonApplicationMenuClient
{
[Guid("CCF43AAC-0822-4C36-90FD-2AFF7B94E71D")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
interface IComRibbonApplicationMenuServer
{
void OpenWindow();
}
[ComImport, Guid("38B1DE85-BC15-48E1-AFAF-4A7EA506256B")]
class ComRibbonApplicationMenuServerClass
{
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
ComRibbonApplicationMenuServerClass comServerClass = new ComRibbonApplicationMenuServerClass();
IComRibbonApplicationMenuServer comServer = (IComRibbonApplicationMenuServer)comServerClass;
comServer.OpenWindow();
}
}
}
The istruction new ComRibbonApplicationMenuServerClass(); throws an InvalidCastException HResult=-2147467262.
What can I do?
Edit:
Thanks Hans for your answer.
If I understand correctly, as I suspected, it is not allowed to create a dotnet COM client for a dotnet COM server without some hacking.
As you have guessed, what I'm trying to do is to test a dotnet program which I've found to work properly when executed as a standalone application, but that crashes (only in Windows XP) when executed by another application via COM.
In order to reproduce the problem I need to build a simple test program that has to start the server and call a method which executes some instructions which, probably, are causing a stack overflow exception. Both programs are using a GUI which maybe part of the problem.
To keep things simple I tried first to make winform program for the COM client, but, reading your anwser, I'm thinking that I have to make a MFC application for testing the COM scenario. What do you think?
throws an InvalidCastException HResult=-2147467262.
You are getting a much more detailed exception message, it will tell you that the cast failed due to the E_NOINTERFACE error return. Which is normally pretty hard to diagnose, except in this case, there really is no interface. The declarations you used in the client are a gross mismatch with the ones used in the server:
the ComRibbonApplicationMenuServerClass declaration in the client doesn't implement any interface. Since you arbitrarily omitted [ClassInterface(ClassInterfaceType.None)], .NET will auto-generate one. It has an random [Guid] that will never match the server's, thus generating the E_NOINTERFACE error.
you arbitrarily gave the client side interface declaration the [InterfaceType(ComInterfaceType.InterfaceIsDual)] attribute. The server omits it and thus uses the default which is ComInterfaceType.InterfaceIsIDispatch. Such an interface can only be called late-bound, the client has to use IDispatch. Which means that if you fix the problem in the first bullet, it will still fail because the server doesn't actually implement the interface. In C#, you'd have to use the dynamic keyword to use such a server.
Clearly it is absolutely essential that the client uses the exact same declarations as the server, normally ensured by using Tlbexp.exe on the server to generate a type library. It is somewhat guessable why you got into this pickle, the IDE will refuse to let you add a reference to the type library, it can see that the server was implemented in .NET and tell you to add a normal .NET reference instead. Which is rather good advice, it doesn't make sense to use COM at all when the normal .NET way already works in a much superior way.
You can fool the machine by using a decompiler on the interop library that Tlbexp.exe generates and copy/paste them into the client, thus making sure you have an exact match. Or by using late-binding with the dynamic keyword in the client app, required anyway because the server uses ComInterfaceType.InterfaceIsIDispatch. Also much less painful since you don't have to repeatedly do the copy/paste step when you alter the server.
But you do need to keep in mind that you are not actually using COM when you do this, the CLR itself is smart enough to see that there's .NET code talking to .NET code and will skip creating the RCW and CCW. So if you are doing this for testing, do keep in mind that you are not actually testing the server the way it is going to be used in a real client app. You might as well test it by actually adding a .NET reference.

C#: How to access function in EXE from CLR code built as dll?

I have created CLR in C# that handles triggers from SQL database. This is built as a dll. There is another file that is built as exe and creates a singleton instance of a TCPServer. I want to access the TCPServer instance in the dll to send the data that is received in the trigger. How can I do this? When I try using the namespace in the file, it is giving me error. Is there a way I can access the instance and its functions from the file that is built as an exe from a file that is built as a dll? Or is this a very bad design? Basic idea is to handle the SQL trigger and post the data to a socket. I am fairly new to both c# and SQL.
Code for CLR:
namespace trigger
{
public class X
{
public static void trig_hdl()
{
}
}
}
This is built as dll: csc /t:library
Code for TCPServer:
namespace TCP
{
public class TCPServer
{
public void sendTo()
}
}
This is built as exe.
Now from trig_hdl() how do I access sendTo()?
There is no difference whether the assembly is an 'exe' or 'dll' (if it is a .Net assembly), first of all you should reference it, then you will have the ability to use the code located in assembly, if both projects are in the same solution then there is absolutely no problem, just reference your project.
Regarding bad design, it seems that it really is bad, the basic idea is that you use shared class library where you put all shared code. After that you just reference that library from both of your projects, and use the code located there...

C#: Partial Classes & Web Services: Separating form and functionality

I am dabbling in the world of web services and I've been making a simple web service which mimics mathematical operations. Firstly it was simple, passing in two integers and then a binary operator would be applied to these (plus, minus etc) depending on the method called.
Then I decided to make things a little more complex and started passing objects around, but then I discovered that a web service only exposes the data side of the class and not the functional side.
I was told that a good way to deal with this is to make the class on the service side a partial class (this side of the class encapsulating form) and on the client side have another partial class (where this side of the class encapsulates functionality). This seems like an elegant way of doing things..
So, I have set up two classes as described above, but it doesn't seem to be working as I was told.
Is what I am attempting possible? If so, where am I going wrong?
Partial classes are really a tool to separate auto-generated code from developer code.
A good example is the windows forms designer in VS, or the new DBML Linq DataContext generated code.
There's also an argument for using them with VSS style source control providers where only one user can edit a file at any one time.
It's not a good idea to use them for logical separation of functionality - the division only exists pre-compilation. As soon as you compile you get just the one class, but not one that it's easy to debug or track operations inside.
What you've described sounds like a really good situation for using WCF contracts. In that case both client and server would share an Interface (or Interfaces).
Your complex code would go there and could be unit tested separately - i.e. outside of your connected application. Then when bugs are found you can eliminate code issues quickly and move to investigating connection related ones instead.
Not with partial classes. A partial class is a syntax construct that gives you the ability to have different parts of the class in different source files. However, all parts of the partial class are ultimately compiled into the same binary.
You could use extension methods to add functionality to your class that represents the data contract.
You could also try implementing the class in a shared assembly and use the svcutil.exe /reference to get it imported in the client proxy instead of having a brand new declaration in the web service namespace.
As Franci said, it simply allows you to put separate parts of the same class into different files.
How you should structure things instead really depends on what you are doing. If I were you I would likely have a rather plain data carrying class and a consumer which could be used to process that data.
The use of a shared assembly is also a good idea. However, if you really wanted to be able to send the code from the server to the client CSharpCodeProvider would work.
(This thread's probably dead but...) I was thinking of doing something similar, but with the functionality on the (in my case) Windows Service.
Both the client program and the Windows service need access to the data, but only the service needs to actually do anything with the data; they are both including in a dll that holds a partial class containing contracted data members, however I get an error saying this partial class conflicts with the partial class on my service even though they are both in the same namespace and at the moment, the server's partial class is empty.

How are partial methods used in C# 3.0?

I have read about partial methods in the latest C# language specification, so I understand the principles, but I'm wondering how people are actually using them. Is there a particular design pattern that benefits from partial methods?
Partial methods have been introduced for similar reasons to why partial classes were in .Net 2.
A partial class is one that can be split across multiple files - the compiler builds them all into one file as it runs.
The advantage for this is that Visual Studio can provide a graphical designer for part of the class while coders work on the other.
The most common example is the Form designer. Developers don't want to be positioning buttons, input boxes, etc by hand most of the time.
In .Net 1 it was auto-generated code in a #region block
In .Net 2 these became separate designer classes - the form is still one class, it's just split into one file edited by the developers and one by the form designer
This makes maintaining both much easier. Merges are simpler and there's less risk of the VS form designer accidentally undoing coders' manual changes.
In .Net 3.5 Linq has been introduced. Linq has a DBML designer for building your data structures, and that generates auto-code.
The extra bit here is that code needed to provide methods that developers might want to fill in.
As developers will extend these classes (with extra partial files) they couldn't use abstract methods here.
The other issue is that most of the time these methods wont be called, and calling empty methods is a waste of time.
Empty methods are not optimised out.
So Linq generates empty partial methods. If you don't create your own partial to complete them the C# compiler will just optimise them out.
So that it can do this partial methods always return void.
If you create a new Linq DBML file it will auto-generate a partial class, something like
[System.Data.Linq.Mapping.DatabaseAttribute(Name="MyDB")]
public partial class MyDataContext : System.Data.Linq.DataContext
{
...
partial void OnCreated();
partial void InsertMyTable(MyTable instance);
partial void UpdateMyTable(MyTable instance);
partial void DeleteMyTable(MyTable instance);
...
Then in your own partial file you can extend this:
public partial class MyDataContext
{
partial void OnCreated() {
//do something on data context creation
}
}
If you don't extend these methods they get optimised right out.
Partial methods can't be public - as then they'd have to be there for other classes to call. If you write your own code generators I can see them being useful, but otherwise they're only really useful for the VS designer.
The example I mentioned before is one possibility:
//this code will get optimised out if no body is implemented
partial void DoSomethingIfCompFlag();
#if COMPILER_FLAG
//this code won't exist if the flag is off
partial void DoSomethingIfCompFlag() {
//your code
}
#endif
Another potential use is if you had a large and complex class spilt across multiple files you might want partial references in the calling file. However I think in that case you should consider simplifying the class first.
Partial methods are very similar in concept to the GoF Template Method behavioural pattern (Design Patterns, p325).
They allow the behaviour of an algorithm or operation to be defined in one place and implemented or changed elsewhere enabling extensibility and customisation. I've started to use partial methods in C# 3.0 instead of template methods because the I think the code is cleaner.
One nice feature is that unimplemented partial methods incur no runtime overhead as they're compiled away.
Code generation is one of main reasons they exist and one of the main reasons to use them.
EDIT: Even though that link is to information specific to Visual Basic, the same basic principles are relevant to C#.
I see them as lightweight events. You can have a reusable code file (usually autogenerated but not necessarily) and for each implementation, just handle the events you care about in your partial class. In fact, this is how it's used in LINQ to SQL (and why the language feature was invented).
Here is the best resource for partial classes in C#.NET 3.0: http://msdn.microsoft.com/en-us/library/wa80x488(VS.85).aspx
I try to avoid using partial classes (with the exception of partials created by Visual Studio for designer files; those are great). To me, it's more important to have all of the code for a class in one place. If your class is well designed and represents one thing (single responsibility principle), then all of the code for that one thing should be in one place.

Categories