|
Just interested in opinions and suggestions regarding how to comprehensively, safely and dynamically (to allow 3rd party plugins to be callable) expose C# code through a script editor!
I'm working on a Node based Scene Graph written in C# which is near complete. It uses Reflection Emit to support a very light weight C# "script" interface ( and indeed all .net languages). Using a custom text editor, the user enters some C#, which the system concatenates into the text body of a class definition, compiles, emits and calls all at run-time etc etc
All works great, however, an obvious side effect is that a casual script user has the same access as I have within the code! This is not ideal for many reasons, but mainly as undo cant be supported at this low level. (I cant use "internal" to overly limit access as 3rd party plug-in developers must have free access)
Undo is currently supported in GUI, but in scripts only by my providing commonly needed operations as member funcs of the class within which the script is compiled into, which work in a way which can be undone... (I cant prevent the user interacting or changing with objects members, as you could do in C++ by using const)
A solution might be to emit, at run time, wrappers for every node class to provide safe indirection to actions the user performs allowing them to be undone.
I'd love to hear from anyone who has experience of anything like this or has any suggestions or observations.
Thanks!
|
|
|
|
|
I don't really get where you are going with this. From your description, I'm assuming you have a script editor window of some sort and then a UI of some sort. Inside the script editor, you can edit scripts. Outside the script editor, you can manipulate the UI in other ways. You want undo functionality. Why wouldn't the script editor window just undo changes made to the script? It would be kind of wacky for the script editor to be able to undo stuff outside of the script editor. Outside the script editor, the undo/redo would be on a more unitized level?
Also, not sure why you are using reflection for C# scripting? There are Microsoft assemblies to compile C# code.
|
|
|
|
|
Firstly, Reflection Emit IS (one of) the MS assemblies you mention needed to compile and C# (along with CodeDom/ICodeProvidor) Lets not worry about that, it all works just fine.
A unified interface for undo is in no way wacky. The purpose of a script editor is to automate and parametrise repetitive tasks the user makes in the GUI. Allowing total, destructive access to an entire application is not good practice. It also means that whether a script is called from the editor, or a gui button, the behaviour is consistent
A node based system mirrors OO principals- all user data is stored in attributes within classified nodes, so its important that the script interface is not merely a limited set of high level functions, for one because the system makes use of plugins
|
|
|
|
|
So currently I'm working on some code to dynamically trace the execution of methods in a separate DLL, once the methods complete, the trace of calls is written to a log file using a StreamWriter.
traceString = SeparateClass.TraceString;
traceFile.Write(traceString.ToString());
traceFile.Flush();
traceFile.Close()
traceFile being declared as a static global variale within the Program class.
However, some of the methods being traced, call the System.Environment.Exit(); command, which completely kill the entire app.
So...I want to use the AppDomain.ProcessExit Event handler to write the data to the log file and flush/close the file before it the app is killed.
I have defined a delegate to be set as the AppDomain.ProcessExit Event as follows...
testDomain.ProcessExit += delegate(object sender, EventArgs e)
{
traceString = SeparateClass.TraceString;
traceFile.Write(traceString.ToString());
traceFile.Flush();
traceFile.Close();
};
But...when the event is fired, I am getting NullReferenceExceptions at the first line, saying that SeparateClass is Null.
Are the values null and void as soon as AppDomain.ProcessExit is entered? If so, any idea how to close the file another way?
Thanks.
Jenni
A girl in Engineering AND IT?!...what is this nonsense?
|
|
|
|
|
Hi Jenni,
Application.Exit() and its event handler work just fine for me. Here is an example (using a Form with a Button and a Label):
using System;
using System.ComponentModel;
using System.IO;
using System.Windows.Forms;
namespace WindowsFormsApplication2 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
log("start");
Application.ApplicationExit+=delegate(object sender, EventArgs e) {
string s=SomeTrace.TraceLog;
label1.Text="all logs: "+s;
MessageBox.Show(s);
File.WriteAllText("log.txt", s);
};
}
private void log(string s) {
label1.Text=s;
SomeTrace.log(s);
}
private void btnQuit_Click(object sender, EventArgs e) {
log("btnQuit_Click");
Application.DoEvents();
Application.Exit();
}
}
public class SomeTrace {
public static string TraceLog=DateTime.Now.ToLongTimeString();
public static void log(string s) {
TraceLog+=Environment.NewLine+s;
}
}
}
Note the behavior depends on how the app quits: closing the main form just creates the file, there will not be a MessageBox as the main form is no longer present. Clicking the Button closes the main form (due to the exit) AND shows the MessageBox.
Remarks:
1. you don't need Flush before a Close;
2. if something is already a string (I suspect TraceString is), there is no use in calling it's ToString() method;
3. I wouldn't use a static trace object, I'd rather instantiate one and pass it along
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
|
|
|
|
|
Hi Luc
Thanks for that, this appears to be more of a GC issue, as the core console process hosts a DLL dynamically (which contains the SeparateClass definition). It is the hosted DLL code, inside the SeparateClas s code that calls System.Environment.Exit() .
The AppDomain.ProcessExit definition must be called when the Console process itself is exiting, rather than the hosted DLL.
So given that, the GC must have already tidied up the SeparateClass at this point?
I'm going to have to refactor anyway, so that the SeparateClass code is executed on a new thread, as I don't like it killing off my entire process.
Thanks again.
Jenni.
A girl in Engineering AND IT?!...what is this nonsense?
|
|
|
|
|
thatdiceygirl wrote: the GC must have already tidied up the SeparateClass at this point?
I don't think so, static classes never get collected at all by the GC, once the class got referenced its statics are initialized and never disappear, until the process vanishes at the Windows level.
I'm afraid you haven't figured out yet what is really going on. And I can't tell you from what you told us. Any chance your DLL is loaded through reflection, and calling its stuff is using some more code (and data) than my example does?
thatdiceygirl wrote: have to refactor anyway,
I agree. I wouldn't want a DLL to call Application.Exit(), DLL classes should be accommodating, not lethal.
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
|
|
|
|
|
Yeah the SeparateClass definition DLL is loaded via reflection, and instantiated using an interface defined in a common assembly.
foreach (Type type in assembly.GetTypes())
{
if (type.IsClass == true)
{
SeparateClass = Activator.CreateInstance(type) as ISeparateClass;
}
}
The TraceString property is called through the interface and returns a StringBuilder object, hence the .ToString() call.
A girl in Engineering AND IT?!...what is this nonsense?
|
|
|
|
|
OK, then some part of your reflection stuff is failing while the app is winding down. AFAIK there isn't a fundamental reason why ApplicationExit would be different from anything else.
If you want to go to the bottom of this, better show all relevant code including the type definitions and their scope.
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
|
|
|
|
|
Hi,
How to take database back up from asp.net.
i try BACKUP DATABASE [tablename] To DISK = [path]
using stored procedure and query text
exception shown - "Cannot perform a backup or restore operation within a transaction.BACKUP DATABASE is terminating abnormally"
Cant we able to take database back up from code behind in asp.net
Thankyou
Yesu
|
|
|
|
|
Try posting your query in the correct forum, this is a Database question.
I must get a clever new signature for 2011.
|
|
|
|
|
I hopes i posted it in the right forum. I need to take back up from 'ASP.NET'. The query is working fine from SQL Server Management Studio
|
|
|
|
|
Yes i need to initiate the database backup from a asp.net webpage.
|
|
|
|
|
you can use SQLDMO library to take the backup in asp.net application..
HELLO GUY
|
|
|
|
|
Well as you can see, this is neither the Database nor the ASP.NET forum.
I must get a clever new signature for 2011.
|
|
|
|
|
You want a backup that is initiated in "ASP.NET"? Are you trying to initiate the database backup from a webpage?
|
|
|
|
|
you can use SQLDMO library to take backup using asp.NET application..
HELLO GUY
|
|
|
|
|
Hey guys!
In my setup project, I want my software to appear in the [Open With] context menu for a certain file extension, however if I do so, the file association makes my software the default file association in Windows for that particular extension. I Do want windows to associate my software with the file extension, but I don't want my setup to change the default association for that file extension.
Is that possible?
|
|
|
|
|
Meaning "Don't change the association if one already exists, but create an association if it doesn't"?
Me, I'd avoid doing it during Setup, and just have your application check to see if the file association is there, then prompt the user asking if they would like the assocation created or changed, as appropriate. (Kind of like email programs do if they find they're not the deafult mailer, or Quicktime with image types, etc.)
|
|
|
|
|
The solution is to change the verb of the file association's action to openas in stead of open. The openas verb makes your software appear in the 'Open With' context menu, but doesn't change the default file association which is exactly what I wanted.
Thanks for your reply!
|
|
|
|
|
|
I found the solution ( this[^] message explains more)
Thanks for your reply!
|
|
|
|
|
Hi ,
I have a search on my form[say,parent form]. When I click on search button ,I want to display the results in a modal window and return the selection back to parent form and populate controls with the returned data.
Any suggestions would be appreciated.
Thanks
|
|
|
|
|
This[^] shows how to do what you want. It uses a string, but you can pass any type you wish.
|
|
|
|
|
Do it with events. When the data is returned, post a custom event, and have the first form hook that event and perform the appropriate processing.
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass." - Dale Earnhardt, 1997
|
|
|
|