C# Load UserControl from Plugin
This is an extension on my previous Plugin project HERE
I'm still in the brainstorming phases, but the idea is pretty basic. Now that I can create a Library, and load it into my application as a Plugin, and have a back and forward messaging system, I'm trying to take it one step further and create a Tab in my main application's Form from the Plugin to manage information.
Initially, knowing it would fail, I attempted to serialize a UserControl as an object, and pass it through the plugin system, which would create a tab, and deserialize the Control as the tab content.
Plugin Call
public interface PluginHost
{
void AddTabView(string name, object view);
...
}
Program Call
public void AddTabView(string name, object view)
{
if (tabViews.InvokeRequired)
{
AddTabViewCallBack d = new AddTabViewCallBack(AddTabView);
handle.Invoke(d, new object { name, view });
}
else
{
TabPage v = new TabPage();
v.Text = name;
tabViews.TabPages.Add(v);
v.Controls.Add(view as UserControl);
}
}
The reason this errors, is because the UserControl cannot be serialized, and more importantly, it cannot pass it's Parent, as hinted by the error System.Runtime.Remoting.RemotingException: 'Remoting cannot find field 'parent' on type 'System.Windows.Forms.Control'.'
Original View as Example

Multiple reports in my research suggest creating a scripting system to interpret the building of the control procedurally, rather than attempting to pass the object itself. My best guess would be to create a shared, serializable object containing positions, size, names, values, and any other pertinent information which could be passed back, and then loop through it to generate the UserControl I desire.
[tl;dr]
If this is the best method, what are my options as far as event
(onclick, selection_changed, etc) handling to minimize the bloating of
the Plugin architecture.
Got knows I don't want to pre-program every single scenario. The ProxyDomain DOES contain a PerfMethod, which could allow calling Methods and Functions from a string name from the plugin, but I feel it might produce a lot of excessive back-and-forth calls from Program->Plugin->Program->Plugin.
PeftMethod(string methodname, object args, ListBox lvErrors)
public object PerfMethod(string methodname, object args, ListBox lvErrors)
{
try
{
Type type = null;
try { type = _assembly.GetType(typeof(FoxBot).Namespace + ".EventHandler"); }
catch { }
if (type != null)
{
MethodInfo method = type.GetMethod(methodname);
if (method != null)
{
object ret = null;
execute = new Thread(new ThreadStart(() =>
{
try
{
object classInstance = Activator.CreateInstance(type, null);
if (method.GetParameters().Length > 0)
{
ret = method.Invoke(classInstance, args);
}
else
{
ret = method.Invoke(classInstance, null);
}
}
catch (ThreadInterruptedException)
{
}
catch (Exception e)
{
//lvErrors.Items.Add("<Scriptor> InvokeException: " + e.ToString() + ".");
MessageBox.Show(e.ToString(), "PerfMethod Failure",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}));
execute.Start();
try
{
while (execute.IsAlive)
Application.DoEvents(); //Thread.Sleep(100);
}
catch (Exception e)
{
lvErrors.Items.Add("<Scriptor> MethodException: " + e.ToString() + ".");
}
return ret;
}
else
{
lvErrors.Items.Add("<Scriptor> MethodNotFound: " + methodname + ".");
}
}
else
{
lvErrors.Items.Add("<Scriptor> TypeNotFound: " + (typeof(FoxBot).Namespace + ".EventHandler") + ".");
}
UnloadDomain();
}
catch (Exception er)
{
lvErrors.Items.Add(er.ToString());
}
return null;
}
c# plugins runtime appdomain
add a comment |
This is an extension on my previous Plugin project HERE
I'm still in the brainstorming phases, but the idea is pretty basic. Now that I can create a Library, and load it into my application as a Plugin, and have a back and forward messaging system, I'm trying to take it one step further and create a Tab in my main application's Form from the Plugin to manage information.
Initially, knowing it would fail, I attempted to serialize a UserControl as an object, and pass it through the plugin system, which would create a tab, and deserialize the Control as the tab content.
Plugin Call
public interface PluginHost
{
void AddTabView(string name, object view);
...
}
Program Call
public void AddTabView(string name, object view)
{
if (tabViews.InvokeRequired)
{
AddTabViewCallBack d = new AddTabViewCallBack(AddTabView);
handle.Invoke(d, new object { name, view });
}
else
{
TabPage v = new TabPage();
v.Text = name;
tabViews.TabPages.Add(v);
v.Controls.Add(view as UserControl);
}
}
The reason this errors, is because the UserControl cannot be serialized, and more importantly, it cannot pass it's Parent, as hinted by the error System.Runtime.Remoting.RemotingException: 'Remoting cannot find field 'parent' on type 'System.Windows.Forms.Control'.'
Original View as Example

Multiple reports in my research suggest creating a scripting system to interpret the building of the control procedurally, rather than attempting to pass the object itself. My best guess would be to create a shared, serializable object containing positions, size, names, values, and any other pertinent information which could be passed back, and then loop through it to generate the UserControl I desire.
[tl;dr]
If this is the best method, what are my options as far as event
(onclick, selection_changed, etc) handling to minimize the bloating of
the Plugin architecture.
Got knows I don't want to pre-program every single scenario. The ProxyDomain DOES contain a PerfMethod, which could allow calling Methods and Functions from a string name from the plugin, but I feel it might produce a lot of excessive back-and-forth calls from Program->Plugin->Program->Plugin.
PeftMethod(string methodname, object args, ListBox lvErrors)
public object PerfMethod(string methodname, object args, ListBox lvErrors)
{
try
{
Type type = null;
try { type = _assembly.GetType(typeof(FoxBot).Namespace + ".EventHandler"); }
catch { }
if (type != null)
{
MethodInfo method = type.GetMethod(methodname);
if (method != null)
{
object ret = null;
execute = new Thread(new ThreadStart(() =>
{
try
{
object classInstance = Activator.CreateInstance(type, null);
if (method.GetParameters().Length > 0)
{
ret = method.Invoke(classInstance, args);
}
else
{
ret = method.Invoke(classInstance, null);
}
}
catch (ThreadInterruptedException)
{
}
catch (Exception e)
{
//lvErrors.Items.Add("<Scriptor> InvokeException: " + e.ToString() + ".");
MessageBox.Show(e.ToString(), "PerfMethod Failure",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}));
execute.Start();
try
{
while (execute.IsAlive)
Application.DoEvents(); //Thread.Sleep(100);
}
catch (Exception e)
{
lvErrors.Items.Add("<Scriptor> MethodException: " + e.ToString() + ".");
}
return ret;
}
else
{
lvErrors.Items.Add("<Scriptor> MethodNotFound: " + methodname + ".");
}
}
else
{
lvErrors.Items.Add("<Scriptor> TypeNotFound: " + (typeof(FoxBot).Namespace + ".EventHandler") + ".");
}
UnloadDomain();
}
catch (Exception er)
{
lvErrors.Items.Add(er.ToString());
}
return null;
}
c# plugins runtime appdomain
add a comment |
This is an extension on my previous Plugin project HERE
I'm still in the brainstorming phases, but the idea is pretty basic. Now that I can create a Library, and load it into my application as a Plugin, and have a back and forward messaging system, I'm trying to take it one step further and create a Tab in my main application's Form from the Plugin to manage information.
Initially, knowing it would fail, I attempted to serialize a UserControl as an object, and pass it through the plugin system, which would create a tab, and deserialize the Control as the tab content.
Plugin Call
public interface PluginHost
{
void AddTabView(string name, object view);
...
}
Program Call
public void AddTabView(string name, object view)
{
if (tabViews.InvokeRequired)
{
AddTabViewCallBack d = new AddTabViewCallBack(AddTabView);
handle.Invoke(d, new object { name, view });
}
else
{
TabPage v = new TabPage();
v.Text = name;
tabViews.TabPages.Add(v);
v.Controls.Add(view as UserControl);
}
}
The reason this errors, is because the UserControl cannot be serialized, and more importantly, it cannot pass it's Parent, as hinted by the error System.Runtime.Remoting.RemotingException: 'Remoting cannot find field 'parent' on type 'System.Windows.Forms.Control'.'
Original View as Example

Multiple reports in my research suggest creating a scripting system to interpret the building of the control procedurally, rather than attempting to pass the object itself. My best guess would be to create a shared, serializable object containing positions, size, names, values, and any other pertinent information which could be passed back, and then loop through it to generate the UserControl I desire.
[tl;dr]
If this is the best method, what are my options as far as event
(onclick, selection_changed, etc) handling to minimize the bloating of
the Plugin architecture.
Got knows I don't want to pre-program every single scenario. The ProxyDomain DOES contain a PerfMethod, which could allow calling Methods and Functions from a string name from the plugin, but I feel it might produce a lot of excessive back-and-forth calls from Program->Plugin->Program->Plugin.
PeftMethod(string methodname, object args, ListBox lvErrors)
public object PerfMethod(string methodname, object args, ListBox lvErrors)
{
try
{
Type type = null;
try { type = _assembly.GetType(typeof(FoxBot).Namespace + ".EventHandler"); }
catch { }
if (type != null)
{
MethodInfo method = type.GetMethod(methodname);
if (method != null)
{
object ret = null;
execute = new Thread(new ThreadStart(() =>
{
try
{
object classInstance = Activator.CreateInstance(type, null);
if (method.GetParameters().Length > 0)
{
ret = method.Invoke(classInstance, args);
}
else
{
ret = method.Invoke(classInstance, null);
}
}
catch (ThreadInterruptedException)
{
}
catch (Exception e)
{
//lvErrors.Items.Add("<Scriptor> InvokeException: " + e.ToString() + ".");
MessageBox.Show(e.ToString(), "PerfMethod Failure",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}));
execute.Start();
try
{
while (execute.IsAlive)
Application.DoEvents(); //Thread.Sleep(100);
}
catch (Exception e)
{
lvErrors.Items.Add("<Scriptor> MethodException: " + e.ToString() + ".");
}
return ret;
}
else
{
lvErrors.Items.Add("<Scriptor> MethodNotFound: " + methodname + ".");
}
}
else
{
lvErrors.Items.Add("<Scriptor> TypeNotFound: " + (typeof(FoxBot).Namespace + ".EventHandler") + ".");
}
UnloadDomain();
}
catch (Exception er)
{
lvErrors.Items.Add(er.ToString());
}
return null;
}
c# plugins runtime appdomain
This is an extension on my previous Plugin project HERE
I'm still in the brainstorming phases, but the idea is pretty basic. Now that I can create a Library, and load it into my application as a Plugin, and have a back and forward messaging system, I'm trying to take it one step further and create a Tab in my main application's Form from the Plugin to manage information.
Initially, knowing it would fail, I attempted to serialize a UserControl as an object, and pass it through the plugin system, which would create a tab, and deserialize the Control as the tab content.
Plugin Call
public interface PluginHost
{
void AddTabView(string name, object view);
...
}
Program Call
public void AddTabView(string name, object view)
{
if (tabViews.InvokeRequired)
{
AddTabViewCallBack d = new AddTabViewCallBack(AddTabView);
handle.Invoke(d, new object { name, view });
}
else
{
TabPage v = new TabPage();
v.Text = name;
tabViews.TabPages.Add(v);
v.Controls.Add(view as UserControl);
}
}
The reason this errors, is because the UserControl cannot be serialized, and more importantly, it cannot pass it's Parent, as hinted by the error System.Runtime.Remoting.RemotingException: 'Remoting cannot find field 'parent' on type 'System.Windows.Forms.Control'.'
Original View as Example

Multiple reports in my research suggest creating a scripting system to interpret the building of the control procedurally, rather than attempting to pass the object itself. My best guess would be to create a shared, serializable object containing positions, size, names, values, and any other pertinent information which could be passed back, and then loop through it to generate the UserControl I desire.
[tl;dr]
If this is the best method, what are my options as far as event
(onclick, selection_changed, etc) handling to minimize the bloating of
the Plugin architecture.
Got knows I don't want to pre-program every single scenario. The ProxyDomain DOES contain a PerfMethod, which could allow calling Methods and Functions from a string name from the plugin, but I feel it might produce a lot of excessive back-and-forth calls from Program->Plugin->Program->Plugin.
PeftMethod(string methodname, object args, ListBox lvErrors)
public object PerfMethod(string methodname, object args, ListBox lvErrors)
{
try
{
Type type = null;
try { type = _assembly.GetType(typeof(FoxBot).Namespace + ".EventHandler"); }
catch { }
if (type != null)
{
MethodInfo method = type.GetMethod(methodname);
if (method != null)
{
object ret = null;
execute = new Thread(new ThreadStart(() =>
{
try
{
object classInstance = Activator.CreateInstance(type, null);
if (method.GetParameters().Length > 0)
{
ret = method.Invoke(classInstance, args);
}
else
{
ret = method.Invoke(classInstance, null);
}
}
catch (ThreadInterruptedException)
{
}
catch (Exception e)
{
//lvErrors.Items.Add("<Scriptor> InvokeException: " + e.ToString() + ".");
MessageBox.Show(e.ToString(), "PerfMethod Failure",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}));
execute.Start();
try
{
while (execute.IsAlive)
Application.DoEvents(); //Thread.Sleep(100);
}
catch (Exception e)
{
lvErrors.Items.Add("<Scriptor> MethodException: " + e.ToString() + ".");
}
return ret;
}
else
{
lvErrors.Items.Add("<Scriptor> MethodNotFound: " + methodname + ".");
}
}
else
{
lvErrors.Items.Add("<Scriptor> TypeNotFound: " + (typeof(FoxBot).Namespace + ".EventHandler") + ".");
}
UnloadDomain();
}
catch (Exception er)
{
lvErrors.Items.Add(er.ToString());
}
return null;
}
c# plugins runtime appdomain
c# plugins runtime appdomain
asked Nov 12 at 16:35
Komak57
61212
61212
add a comment |
add a comment |
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53266441%2fc-sharp-load-usercontrol-from-plugin%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53266441%2fc-sharp-load-usercontrol-from-plugin%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown