Author | Message | Time |
---|---|---|
Smurfling | I got a little problem, but first of all the code: [code] Private VBP As New VBCodeProvider Private CVB As System.CodeDom.Compiler.ICodeCompiler Private PM As New System.CodeDom.Compiler.CompilerParameters Private Results As System.CodeDom.Compiler.CompilerResults Public Function CodeD() Dim FILE_NAME As String = "ChatEvents.txt" Dim fsIn As New FileStream(FILE_NAME, FileMode.Open, FileAccess.Read, FileShare.ReadWrite) Dim sr As New StreamReader(fsIn) Dim i As Integer Dim k As Integer Dim TheKey As String TheKey = sr.ReadToEnd sr.Close() fsIn.Close() CVB = VBP.CreateCompiler PM.GenerateInMemory = True PM.OutputAssembly = "CEvents.dll" PM.MainClass = "ChatEvents" PM.IncludeDebugInformation = False Dim ASM As System.Reflection.Assembly PM.ReferencedAssemblies.Clear() For Each ASM In AppDomain.CurrentDomain.GetAssemblies() PM.ReferencedAssemblies.Add(ASM.Location) Next Results = CVB.CompileAssemblyFromSource(PM, TheKey) Dim RunObj As New Object Dim vArgs() As Object RunObj = Results.CompiledAssembly.CreateInstance("CEvents" & "." & "ChatEvents", False, Reflection.BindingFlags.CreateInstance, Nothing, vArgs, Nothing, Nothing) If Not RunObj Is Nothing Then RunObj.ProcessEvents(hID, hUserFlag, hPing, hUsername, hText, bla) End If End Function [/code] Well, the code itself works fine - it's reading the code out of the .txt file, creating the .dll within the memory and all's ok. But now if i change the code within the .txt and want to update and recreate the dll there's always remaining the old code. It only works if i close the app and start it again. Can someone give me a little hint how to get it done? | October 29, 2003, 2:18 PM |
St0rm.iD | Can you explain to me what CodeDom does and how it works? I've been trying to write a new language for .NET but haven't figured out the "right way" (converting source files to jscript.net) | October 29, 2003, 8:36 PM |
Smurfling | Ok i'll try to do so... ;D Introduction: CodeDom stands for the Code Document Object Model. A popular use of the CodeDom is for developing automatic source code generators which minimize repetitive coding tasks, and minimize the number of human-generated source code lines being created. Advantages: [list][*]The CodeDom is based upon a single model for rendering source code. Therefore, source code may be generated for any language that supports the CodeDom specification. (VBScript, VB, .NET,...) [*]The CodeDom allows programs to be dynamically created, compiled, and executed at runtime. [*]The CodeDom provides a language independent object model for representing the structure of source code in memory. [/list] Limitations: [list][*]There is no support for aliasing a namespace. [*]There is no support for nested namespaces. [*]There is no support for variable declaration lists. [*]There is no support for the "unsafe" modifier. [/list] Finally: This is just a short overview, for more Information search msdn.microsoft.com. There are lot's of things i don't know about CodeDOM, i am just learning to use it's possibilities to the fullest. As far as i can tell you from the knowledge i have yet is that CodeDOM is for existing languages only, that means writing a new language for .NET could be hard/impossible to do with it. But if you only want to execute p.e. a VBScript within JScript CodeDOM is the thing you should go for. For what i am using CodeDOM is making my bot scriptable to the max., almost everything will be loaded through CD. [code] 'The Code Provider for Visual Basic . NET Private VBP As New VBCodeProvider 'The Code Compiler Private CVB As System.CodeDom.Compiler.ICodeCompiler 'The Parameters for compilation Private PM As New System.CodeDom.Compiler.CompilerParameters 'Will hold the compiled script Private Results As System.CodeDom.Compiler.CompilerResults Public Function CodeD() 'Load VB .NET Script Source from ChatEvents.txt Dim FILE_NAME As String = "ChatEvents.txt" Dim fsIn As New FileStream(FILE_NAME, FileMode.Open, FileAccess.Read, FileShare.ReadWrite) Dim sr As New StreamReader(fsIn) Dim i As Integer Dim k As Integer Dim TheKey As String TheKey = sr.ReadToEnd sr.Close() fsIn.Close() 'Creating the VB Compiler CVB = VBP.CreateCompiler 'Creating the assembly in memory PM.GenerateInMemory = True 'Setting the assembly name PM.OutputAssembly = "CEvents.dll" 'Setting the main class of the script PM.MainClass = "ChatEvents" 'I don't need debug info ;) PM.IncludeDebugInformation = False 'Adding references to the assembly Dim ASM As System.Reflection.Assembly PM.ReferencedAssemblies.Clear() For Each ASM In AppDomain.CurrentDomain.GetAssemblies() PM.ReferencedAssemblies.Add(ASM.Location) Next 'Filling the results with the compiled script Results = CVB.CompileAssemblyFromSource(PM, TheKey) 'Running the compiled script Dim RunObj As New Object Dim vArgs() As Object RunObj = Results.CompiledAssembly.CreateInstance("CEvents" & "." & "ChatEvents", False, Reflection.BindingFlags.CreateInstance, Nothing, vArgs, Nothing, Nothing) If Not RunObj Is Nothing Then 'Calling the Function ProcessEvents within the script RunObj.ProcessEvents(hID, hUserFlag, hPing, hUsername, hText, bla) End If End Function [/code] O yea, here would be the script ChatEvents.txt - that's a simple one, don't want to fill pages with the real script here ;) [code] Imports System.Windows.Forms Imports Microsoft.VisualBasic Imports System namespace CEvents Public Class ChatEvents Public Function ProcessEvents(ByVal eID As Long, ByVal eUserFlag As Long, ByVal ePing As Long, ByVal eUsername As String, ByVal eText As String, ByVal Socket As BdNBot2004.clsBNLSSocket) Const EID_SHOWUSER& = &H1 Const EID_JOIN& = &H2 Const EID_LEAVE& = &H3 Const EID_WHISPER& = &H4 Const EID_TALK& = &H5 Const EID_BROADCAST& = &H6 Const EID_CHANNEL& = &H7 Const EID_USERFLAGS& = &H9 Const EID_WHISPERSENT& = &HA Const EID_CHANNELFULL& = &HD Const EID_CHANNELDOESNOTEXIST& = &HE Const EID_CHANNELRESTRICTED& = &HF Const EID_INFO& = &H12 Const EID_ERROR& = &H13 Const EID_EMOTE& = &H17 Select Case eID Case EID_WHISPER If eText = ":TIME" Then Socket.Insert(Socket.Type.tNTString, "/w " & eUsername & " " & DateTime.Now) Socket.SendPacket(&HE) Exit Function End If End Select End Function End Class end namespace[/code] But o well, i still don't have my problem solved and can't find anything about it on the net... any help would still be appreciated :P | October 30, 2003, 9:33 AM |
Smurfling | O man i love to try out each possibility until you find the right ;) Finally solved it by my own, for those who perhaps wanna know how to reload the dll: [code] Dim FILE_NAME As String = "ChatEvents.txt" Dim fsIn As New FileStream(FILE_NAME, FileMode.Open, FileAccess.Read, FileShare.ReadWrite) Dim sr As New StreamReader(fsIn) Dim i As Integer Dim k As Integer Dim TheKey As String TheKey = sr.ReadToEnd sr.Close() fsIn.Close() Results = CVB.CompileAssemblyFromSource(PM, TheKey) [/code] The only secret was to leave the compiler and options alone (if you touch them it won't work) and only to reload the source & compile them into results again ;) Edited: If i think about it now that i solved it this is the first thing you should think about - just reload source and recompile, but o well i always try to to things the hard way | October 30, 2003, 11:13 AM |
St0rm.iD | Could I create an extension to CodeDom which compiles language X? | October 31, 2003, 1:15 AM |
zorm | Would it be possible to take advantage of this in like C/C++? | November 1, 2003, 9:43 PM |
St0rm.iD | In managed c++. | November 1, 2003, 9:45 PM |
K | Yup, the System.CodeDom namespace is a lot of fun, and very useful for making things plugin friendly without too much effort. Example! | November 1, 2003, 10:38 PM |
Skywing | [quote author=K link=board=23;threadid=3318;start=0#msg26847 date=1067726321] Yup, the System.CodeDom namespace is a lot of fun, and very useful for making things plugin friendly without too much effort. Example! [/quote] Isn't having a "File" and "This File" menu kind of silly, BTW? What're you using to parse and color code text in your editor? | November 1, 2003, 11:45 PM |
K | [quote author=Skywing link=board=23;threadid=3318;start=0#msg26858 date=1067730346] Isn't having a "File" and "This File" menu kind of silly, BTW? What're you using to parse and color code text in your editor? [/quote] Haha yes, I didn't notice that. I added the options like Quit, Save All, etc under File and the file specific ones under this file. Sounds like a merger is in order. As for the coloring, it's done using a combination of regular expressions and a list of keywords. It's kind of slow when coloring an entire document, but once it's colored it updates fairly quickly -- I only scan the visible region of the editor when a change is made, unless it's a change to a block comment. | November 2, 2003, 1:12 AM |
Myndfyr | [quote author=Andreas Strobl link=board=23;threadid=3318;start=0#msg26332 date=1067437104] I got a little problem, but first of all the code: Well, the code itself works fine - it's reading the code out of the .txt file, creating the .dll within the memory and all's ok. But now if i change the code within the .txt and want to update and recreate the dll there's always remaining the old code. It only works if i close the app and start it again. Can someone give me a little hint how to get it done? [/quote] Unfortunately, no. There is no way to unload an assembly from memory within an AppDomain until the AppDomain is terminated, i.e., the program is closed. It's a shortcoming of the .NET environment. Something you may consider, though, which I have done with my .NET apps, is to use methods called RegisterEvents and UnregisterEvents(). Any events that you want to handle are hooked by the plugin (these events are contained by another class, which I call the EventHost, an instance of which is passed into the plugin's constructor). When you're done with the plugin - that is, wish to finish it off - you just call the UnregisterEvents method. Here's the interface for it: [code] Public Interface IPlugin ' It is illegal to declare this in the constructor or as a shared method ' because of OOP, but you get the idea: Shared Function GetInstance(ByVal EH as EventHost) As IPlugin Sub RegisterEvents() Sub UnregisterEvents() Event PluginMessage As PluginEventHandler End Interface [/code] Hope that helps. --Rob | November 6, 2003, 12:42 AM |