Compile code on the fly

PwUP

Member
Joined
Sep 21, 2009
Messages
23
Programming Experience
1-3
Hi there, i was trying to accomplish to that task with codedom classes, but i can't compile my code!
May you post here an example which does succesfully that?
I already searched through this forum and the web but i still can't even make a step towards the solution.
Thanks in advance!
Here are son additional information i forgot to write before,
my current code is this:
VB.NET:
Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim CodeDomProvider As CodeDomProvider = CodeDomProvider.CreateProvider("VB")
        Dim fl As String = "Form1.vb"
        CompileCode(CodeDomProvider, fl, "C:\Documents and Settings\Slascio\Desktop\ciabbb.exe")
    End Sub

    Public Shared Function CompileCode(ByVal provider As CodeDomProvider, _
                                        ByVal sourceFile As String, _
                                        ByVal exeFile As String) As CompilerResults

        ' Configure a CompilerParameters that links System.dll
        ' and produces the specified executable file.
        Dim referenceAssemblies As String() = {"System.dll"}
        Dim cp As New CompilerParameters(referenceAssemblies, exeFile, False)

        ' Generate an executable rather than a DLL file.
        cp.GenerateExecutable = True

        ' Invoke compilation.
        Dim cr As CompilerResults = provider.CompileAssemblyFromFile(cp, _
            sourceFile)
        ' Return the results of compilation.
        Return cr
    End Function
End Class


and the source file Form1.vb contains:
VB.NET:
imports System
Namespace MyNamespace
Public Class Classe1
    Private Sub main()
	MsgBox("nap")
    End Sub
End Class
End Namespace

I guess the code in the source file is incorrect...
What should i write there?
 
Last edited:
I guess the code in the source file is incorrect...
No need to guess, that is exactly what CompilerResults.Errors Property property expose as problems:
No accessible 'Main' method with an appropriate signature was found in 'ciabbb'.
'MsgBox' is not declared. It may be inaccessible due to its protection level.
MsgBox Function (Visual Basic) look down the page, what namespace does MsgBox function belong to?
Main Procedure in Visual Basic this explains about the Main procedure.

Give it a try, if you fix the Main and the MsgBox call it will compile the exe. (given the target path is valid and allows write)
 
MSDN says:
"Unless you are creating a Windows Forms application, you must write the Main procedure for applications that run on their own"
and I want to compile a Windows Forms Application!

Anyway, I also read there:
In Main, you can determine which form is to be loaded first when the program starts.
So i got confused. :(
My question is, what have i to write in that source file to compile the simplest windows form application? You know, just like creating a new windows form application from Visual Basic..
 
You need an appropriate Main procedure that calls this: Application.Run Method (Form) (System.Windows.Forms)

Don't forget System.Drawing.dll and System.Windows.Forms.dll also must be referenced for Windows Forms applications.

In addition, this compiler option must be set to winexe with CompilerOptions property of the CompilerParameters object: /target (Visual Basic)
My question is, what have i to write in that source file to compile the simplest windows form application? You know, just like creating a new windows form application from Visual Basic..
A simpler option, especially since you're beginner, is to replicate the files VB generates for a basic project (a .vbproj file and one or more .vb files), then compile the .vbproj file using Msbuild.exe (from .Net folder). You can use Process class to make this call from your application. Also available programmatically with this Engine.BuildProjectFile Method (String) (Microsoft.Build.BuildEngine) (more recently replaced by this Project.Build Method (Microsoft.Build.Evaluation))
 
Ok, this functions!
At last, how may I access to the events of the Form I made?
Here is my code in "Form1.vb"
VB.NET:
Imports System
Imports System.Windows.Forms
Imports System.Drawing

Module Class3

Sub Main()
   Dim Form1 as Form = New Form()
   Dim btn As Button = New Button()
   btn.Text = "button"
   Form1.Controls.Add(btn)
   Application.Run(Form1)
End Sub

End Module
I'd like to add some code e.g. in the event btn_Click...
 
Last edited:
Sorry for the double post, i realized form1 is a class so i decleared it and i succesfully used its events.
Thanks for the replies, JohnH.
For who has my same trouble, here is the solution:
VB.NET:
Imports System
Imports System.Windows.Forms
Imports System.Drawing
Imports Microsoft.VisualBasic

Public Class Form1
    Inherits Form

	Private Sub InitializeComponent()
        Me.components = New System.ComponentModel.Container
        Me.Timer1 = New System.Windows.Forms.Timer(Me.components)
        Me.Timer1.Enabled = True
        Me.SuspendLayout()
        Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.ClientSize = New System.Drawing.Size(292, 266)
        Me.Name = "Form1"
        Me.Text = "Form1"
        Me.ResumeLayout(False)

    End Sub


    Friend WithEvents Timer1 As System.Windows.Forms.Timer

    Public Sub New()
	InitializeComponent()
    End Sub

    Protected Overrides Sub Finalize()
        MyBase.Finalize()
    End Sub


    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub
    Private components As System.ComponentModel.IContainer
    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
		MsgBox("Loop Event")
    End Sub
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
		MsgBox("Create Event")
    End Sub
End Class

Module Module1

Sub Main()
   Dim frm as Form1 = New Form1()
   Dim btn As Button = New Button()
   btn.Text = "Coglion"
   frm.Controls.Add(btn)
   Application.Run(frm)
End Sub

End Module
 
You should research the tools in System.Resources and System.Resources.Tools namespaces.

Some more detailed info:
  • Create a .resx file with ResXResourceWriter. (like Resources.resx found in 'My Project' folder)
  • Use that file with StronglyTypedResourceBuilder to generate vb source code for strongly typed access to resource members, output with provider.GenerateCodeFromCompileUnit method. (the typical Resources.Designer.vb file) Remember that this .vb file must also be compiled along the other .vb source files to the final assembly.
  • Now you need to create a .resources file if you're using CodeDom, to add to EmbeddedResources property of CompilerParameters. This file can be created using ResourceWriter, you can for example just convert the existing .resx with a ResXResourceReader. (VS output this as a temporary file in obj folder during compilation)
 
Ok i succesfully compiled the exe with the resource file. Now i don't understand how to acces to my resx.
This is the code i use to compile the resource file:
VB.NET:
        Dim writer As New System.Resources.ResXResourceWriter("resources.resx")
        Dim im As Image = Image.FromFile("poly.bmp") 'poly.bmp exists!
        writer.AddResource("imagex", im)
        writer.Generate()
        writer.Close()

Then in the compiler options i use this:

VB.NET:
        cp.EmbeddedResources.Add("resources.resx")

So, in the compiled exe i use this to take "imagex" resource:

VB.NET:
Dim oAssembly As System.Reflection.Assembly = System.Reflection.Assembly.LoadFrom(Application.ExecutablePath)
Dim names() As String = oAssembly.GetManifestResourceNames
Dim sprite0 As Image = Image.FromStream(oAssembly.GetManifestResourceStream("imagex"))

It says stream is null. :confused:
 
If you aren't going to use a typed proxy (step 2 previous post) you should go straight to step 3 and create a compiled .resources file and embed that, then you can access resources from that set using ResourceManager and GetObject, just like the My.Resources generated code does it. The .resx is as explained a xml file used by designer, and is not embedded in compiled assembly.
It is also possible to embed the image file directly (without using a resources set) and access it with GetManifestResourceStream.
 
Ok the second way seems to be easier, but i can't do it through the CompilerParameters, right? the EmbeddedResources property only accepts strings of filenames.
So how may i embed an image directly?
 
EmbeddedResources property only accepts strings of filenames
Correct, path of the .resources file or any other file you want to embed.
 
Back
Top