Visual Basic Development Bookmark and Share   
 Home > Visual Basic Language > CompileExecutable function. Anyone got it working please?
 

CompileExecutable function. Anyone got it working please?

Hi ALL,

I refer to the CompileExecutable function at.>>

http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.vbcodeprovider.aspx

I have attempted to try and get it working for a Windows Forms based application from about my 4th post in this thread.>>

http://social.msdn.microsoft.com/Forums/en-US/vblanguage/thread/b49331ff-5cf7-4c24-bcca-ef7ea2f16068#page:1


Has anyone had any success in using it or a variation of it please?


Regards,

John


For links to VB.Net tutorials see here.>> http://social.msdn.microsoft.com/Forums/en-US/vblanguage/thread/29f2179b-997b-4115-a96d-a0834853b835
John Anthony Oliver  Sunday, November 16, 2008 3:25 AM
Ok To make your code run:

Dim cp As CompilerParameters = New CompilerParameters()
Dim references() As String = {"System.Windows.Forms.dll", "System.Drawing.dll", "Microsoft.VisualBasic.dll", "System.dll"}
cp.ReferencedAssemblies.AddRange(references)

cp.CompilerOptions = "/target:winexe /m:Form1"


and in your class please import (for messagebox to work)

Option Strict On
Imports System.Windows.Forms

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
Inherits System.Windows.Forms.Form


Arjun Paudel
Arjun Paudel  Sunday, November 16, 2008 6:34 AM
Hi John!

Some changes in your compiler code:

Dim cp As CompilerParameters = New CompilerParameters()
Dim references() As String = {"System.Windows.Forms.dll", "Microsoft.VisualBasic.dll", "System.dll"}
cp.ReferencedAssemblies.AddRange(references)


cp.CompilerOptions = "/target:winexe /m:myForm"

and a simple form class


Imports System
Imports System.Windows.Forms

Public Class myForm
Inherits Form
Dim WithEvents myButton As Button

Public Sub New()

myButton = New Button()
myButton.Text = "Auto Generated"
myButton.Top = 70
myButton.Left = 70

Me.controls.add(myButton)

End Sub

Private Sub myButtonClick(ByVal sender As Object, ByVal e As EventArgs) _
Handles myButton.Click
MessageBox.Show("Hello World!")
End Sub

End Class

Arjun Paudel
  • Edited byArjun PaudelMVPSunday, November 16, 2008 6:26 AM"System.Drawing.dll",
  •  
Arjun Paudel  Sunday, November 16, 2008 6:21 AM
Ok To make your code run:

Dim cp As CompilerParameters = New CompilerParameters()
Dim references() As String = {"System.Windows.Forms.dll", "System.Drawing.dll", "Microsoft.VisualBasic.dll", "System.dll"}
cp.ReferencedAssemblies.AddRange(references)

cp.CompilerOptions = "/target:winexe /m:Form1"


and in your class please import (for messagebox to work)

Option Strict On
Imports System.Windows.Forms

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
Inherits System.Windows.Forms.Form


Arjun Paudel
Arjun Paudel  Sunday, November 16, 2008 6:34 AM
Arjun Paudel said:

Ok To make your code run:

Dim cp As CompilerParameters = New CompilerParameters()
Dim references() As String = {"System.Windows.Forms.dll", "System.Drawing.dll", "Microsoft.VisualBasic.dll", "System.dll"}
cp.ReferencedAssemblies.AddRange(references)

cp.CompilerOptions = "/target:winexe /m:Form1"


and in your class please import (for messagebox to work)

Option Strict On
Imports System.Windows.Forms

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
Inherits System.Windows.Forms.Form


Arjun Paudel



Hi Arjun,

As you discovered a reference to System.Drawing.dll was also needed, compared to your 1st post.

So you could delete your 1st post above and edit the 2nd one, if you wish.

You are a star mate!!

If you were near here in the N.E. of England, I would give you a medal and buy you some drinks!!

:-) :-] :-} ;-) ;-] ;-}

I thought I might have had to do something with these Compiler Options but I found I did not need to.

cp.MainClass = "Form1"

cp.Win32Resource = "C:\Test.Resx"

Anyway thanks again for your help. :-)

1) Before I go what changes would be needed for a CONSOLE APPLICATION please?

2) How to change the output path?

3) Could I still do this with the FORM1 CLASS code separate from the PARTIAL FORM1 CLASS code as used by the designer?


Regards,

John


For links to VB.Net tutorials see here.>> http://social.msdn.microsoft.com/Forums/en-US/vblanguage/thread/29f2179b-997b-4115-a96d-a0834853b835
John Anthony Oliver  Sunday, November 16, 2008 7:35 AM
Hi John!

Thanks!

Actually target:winexe is asking it to compile windows application.
target:exe does for console application (i think its default)
edit: oh yes Public Shared Sub Main()

i was just thinking about vbc when I was trying to build your application, and it worked...

In first post I have not used Drawing so its not needed (for my example class), but your class needs it since you have referenced drawing in your class

System.Drawing.Size(284, 264)

Thanks for the compliments,

btw (marked helpful),

cp.MainClass = "Form1"

cp.Win32Resource = "C:\Test.Resx"

yeah, I dint look at them since I was only thinking vbc

Thanks

Arjun Paudel
Arjun Paudel  Sunday, November 16, 2008 7:46 AM
Hi again Arjun,

What do you mean by vbc?


Regards,

John

For links to VB.Net tutorials see here.>> http://social.msdn.microsoft.com/Forums/en-US/vblanguage/thread/29f2179b-997b-4115-a96d-a0834853b835
John Anthony Oliver  Sunday, November 16, 2008 7:49 AM
visual basic compiler, you can compile application from command line if you don't have visual studio:)

Didnt you use it when .net Framework SDK was only available?

probably I had to write visual basic compiler (vbc, you might have forgotten the shortcut)




And the compiler we are using above uses the same vbc.exe tool to compile.


GUI does not let us know that, but vbc is compiling your code.




Arjun Paudel
Arjun Paudel  Sunday, November 16, 2008 8:03 AM

Hi Arjun,

O.k. thanks.

No I've never used vbc from the command line. Believe it or not.

Do you have an answer for question 3) in my post below your 2nd post please?

You have answered number 1) earlier. Thanks again. :-)
I have figured out number 2) for myself in changing the output path. :-)

Regards,

John


For links to VB.Net tutorials see here.>> http://social.msdn.microsoft.com/Forums/en-US/vblanguage/thread/29f2179b-997b-4115-a96d-a0834853b835
John Anthony Oliver  Sunday, November 16, 2008 8:14 AM
Could I still do this with the FORM1 CLASS code separate from the PARTIAL FORM1 CLASS code as used by the designer?

My first post does not use partial class...


Probably I did not understand your question, not that good in English, sorry John

Arjun Paudel
Arjun Paudel  Sunday, November 16, 2008 8:18 AM
Hi Arjun,

In Vb.Net from 2005 onwards we have the Form1.Vb file that usually starts and ends with

Public Class Form1

End Class


Then the Form1.Designer.Vb file which starts and ends with

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _

Partial Class Form1

Inherits System.Windows.Forms.Form
'Some code here.>>

End Class





To see all the files.>>

"Show All Files" "Vb.Net"



If you PASTE the two together into Notepad we have one full Vb.Net code for a single FORM.

Would there be anyway to get the compiler program to see all of the files in a project that are needed?

If we had two FORMs we would have 4 files;

Form1.Vb
Form1.Designer.Vb
Form2.Vb
Form2.Designer.Vb

The main point of my question is, how to get the code below to compile more than one file together into one EXE file?


Regards,

John

OptionStrictOn
PublicClassForm1
PrivateSubButton1_Click(ByValsenderAsSystem.Object,ByValeAsSystem.EventArgs)HandlesButton1.Click
DimSuccessAsBoolean
Success=CompileExecutable("C:\Test.Vb")
MessageBox.Show("C:\Test.Vb"&Success.ToString&ControlChars.NewLine)
EndSub
PublicSharedFunctionCompileExecutable(ByValsourceNameAsString)AsBoolean
DimsourceFileAsSystem.IO.FileInfo=NewSystem.IO.FileInfo(sourceName)
DimproviderAsSystem.CodeDom.Compiler.CodeDomProvider=Nothing
DimcompileOkAsBoolean=False
'Selectthecodeproviderbasedontheinputfileextension.
IfsourceFile.Extension.ToUpper(Globalization.CultureInfo.InvariantCulture)=".CS"Then
provider=System.CodeDom.Compiler.CodeDomProvider.CreateProvider("CSharp")
ElseIfsourceFile.Extension.ToUpper(Globalization.CultureInfo.InvariantCulture)=".VB"Then
provider=System.CodeDom.Compiler.CodeDomProvider.CreateProvider("VisualBasic")
Else
Console.WriteLine("Sourcefilemusthavea.csor.vbextension")
EndIf
IfNotproviderIsNothingThen
'Formattheexecutablefilename.
'Buildtheoutputassemblypathusingthecurrentdirectory
'and<source>_cs.exeor<source>_vb.exe.
'DimexeNameAsString=String.Format("{0}\{1}.exe",System.Environment.CurrentDirectory,sourceFile.Name.Replace(".","_"))
DimexeNameAsString=String.Format("{0}{1}.exe",sourceFile.Directory,sourceFile.Name.Replace(".","_"))
DimcpAsSystem.CodeDom.Compiler.CompilerParameters=NewSystem.CodeDom.Compiler.CompilerParameters()
'Next3linesofcoderequiredforaWINDOWS.FORMSbasedapplication.>>
Dimreferences()AsString={"System.Windows.Forms.dll","Microsoft.VisualBasic.dll","System.dll","System.Drawing.dll"}
cp.ReferencedAssemblies.AddRange(references)
cp.CompilerOptions="/target:winexe/m:Form1"
'Generateanexecutableinsteadof
'aclasslibrary.
cp.GenerateExecutable=True
'Specifytheassemblyfilenametogenerate.
cp.OutputAssembly=exeName
'Savetheassemblyasaphysicalfile.
cp.GenerateInMemory=False
'Setwhethertotreatallwarningsaserrors.
cp.TreatWarningsAsErrors=False
'Invokecompilationofthesourcefile.
DimcrAsSystem.CodeDom.Compiler.CompilerResults=provider.CompileAssemblyFromFile(cp,sourceName)
Ifcr.Errors.Count>0Then
'Displaycompilationerrors.
Console.WriteLine("Errorsbuilding{0}into{1}",sourceName,cr.PathToAssembly)
DimceAsSystem.CodeDom.Compiler.CompilerError
DimsbAsNewSystem.Text.StringBuilder
ForEachceIncr.Errors
sb.Append(ce.ToString&ControlChars.NewLine)
Nextce
MessageBox.Show(sb.ToString)
Else
'Displayasuccessfulcompilationmessage.
MessageBox.Show("Sourcebuiltintosuccessfully."&sourceName&vbTab&"to"&vbTab&cr.PathToAssembly)
EndIf
'Returntheresultsofthecompilation.
Ifcr.Errors.Count>0Then
compileOk=False
Else
compileOk=True
EndIf
EndIf
ReturncompileOk
EndFunction
EndClass

For links to VB.Net tutorials see here.>> http://social.msdn.microsoft.com/Forums/en-US/vblanguage/thread/29f2179b-997b-4115-a96d-a0834853b835
John Anthony Oliver  Sunday, November 16, 2008 9:01 AM
Hi John!
I dint get alert of your message, I understood what you mean now, Thanks
there are some work around for this too,

like if you want to compile all the files in the folder (I have removed m parameter for cp.MainClass = "Form1")
cp.CompilerOptions = "C:\myvbfiles\*.vb /target:winexe"

if you want a single designer file to include then (for previous example, for CompileAssemblyFromFile put code behind class, and put designers class here)
provider.CompileAssemblyFromFile(cp, "C:\myvbfiles\Form1.vb")
cp.CompilerOptions = "C:\myvbfiles\Form1.designers.vb /target:winexe"

if you want selected file to compile then


cp.CompilerOptions = "C:\myvbfiles\Form1.designers.vb C:\myvbfiles\From1.vb C:\myvbfiles\Form2.vb C:\myvbfiles\From2.designers.vb /target:winexe"



Arjun Paudel
Arjun Paudel  Sunday, November 16, 2008 11:32 AM
Arjun Paudel said:

Hi John!
I dint get alert of your message, I understood what you mean now, Thanks
there are some work around for this too,

like if you want to compile all the files in the folder (I have removed m parameter for cp.MainClass = "Form1")
cp.CompilerOptions = "C:\myvbfiles\*.vb /target:winexe"

if you want a single designer file to include then (for previous example, for CompileAssemblyFromFile put code behind class, and put designers class here)
provider.CompileAssemblyFromFile(cp, "C:\myvbfiles\Form1.vb")
cp.CompilerOptions = "C:\myvbfiles\Form1.designers.vb /target:winexe"

if you want selected file to compile then


cp.CompilerOptions = "C:\myvbfiles\Form1.designers.vb C:\myvbfiles\From1.vb C:\myvbfiles\Form2.vb C:\myvbfiles\From2.designers.vb /target:winexe"



Arjun Paudel




Hi again Arjun,

Thanks again. :-)

The above makes things far easier. :-D

I can now specify one common designer file and use different Form1.Vb files. :-) >>



Dim Filename As String

For index As Integer = 1 to 1000

Filename = "MyProgram" & index.ToString.PadLeft(4,"0"c) & ".Vb"

'More code.>>

Next



Then compileMyProgram0001.Vb through to MyProgram1000.Vb

For say 1000 different versions with the same Designer file as
in the request by forum user Daymere in this thread.>>

http://social.msdn.microsoft.com/Forums/en-US/vblanguage/thread/b49331ff-5cf7-4c24-bcca-ef7ea2f16068#page:1


Regards,

John

For links to VB.Net tutorials see here.>> http://social.msdn.microsoft.com/Forums/en-US/vblanguage/thread/29f2179b-997b-4115-a96d-a0834853b835
John Anthony Oliver  Sunday, November 16, 2008 9:48 PM
Um, did you guys find some solution to hide attached console from user, in order to produce only such binary, which starts Form directly, without blackbox beside? I have'nt clue how to supress it... also complete solution which I pasted for Delware is compiling Client with console beside... I willserach for solution but probably I am not as good as you two.

Regards, Matt
konikula  Tuesday, November 18, 2008 9:15 AM
konikula said:

Um, did you guys find some solution to hide attached console from user, in order to produce only such binary, which starts Form directly, without blackbox beside? I have'nt clue how to supress it... also complete solution which I pasted for Delware is compiling Client with console beside... I willserach for solution but probably I am not as good as you two.

Regards, Matt


Hi Matej,

I created a solution for compiling asingle Windows.FORM based program ( application ), not for a CONSOLE APPLICATION with the help of Arjun Paudel above.

It just compiles the code ( produces the binary ) "but does NOT start the FORM directly" , I have no need to run the COMPILED code straight away, although itcould do.

Read my post that I proposedAs Answer which is my 2nd post on this page.>>

http://social.msdn.microsoft.com/Forums/en-US/vblanguage/thread/b49331ff-5cf7-4c24-bcca-ef7ea2f16068#page:2




Regards,

John

For links to VB.Net tutorials see here.>> http://social.msdn.microsoft.com/Forums/en-US/vblanguage/thread/29f2179b-997b-4115-a96d-a0834853b835
John Anthony Oliver  Tuesday, November 18, 2008 11:15 AM
Thank you very much. If you justdelete target declaration in"cp.CompilerOptions" you get what I called "attached console" :) I have repaired tutorial code to produce file using your options, I only let "Form1" being passed through cp.MainClass property (so it has two places to pass). Thanks a lot, this helped me to move next step. So now can I move to including more files to solution.

Regards, Matej
konikula  Tuesday, November 18, 2008 2:17 PM
Most of the code provided, I see, is from the MSDN documentation. Here are links for:

Overview of Dynamic code compilation:
http://msdn.microsoft.com/en-us/library/650ax5cx.aspx

Generating Source Code and Compiling a Program from a CodeDOM Graph:

http://msdn.microsoft.com/en-us/library/saf5ce06.aspx

This includes a C# compilation from VB, but you can replace the 'provider' with: Microsoft.VisualBasic.VBCodeProvider



Compiler Command Line Parameters:
http://msdn.microsoft.com/en-us/library/w95cx9k1.aspx

You can add the command line parameters to the System.CodeDom.Compiler.CompilerParameters CompilerOptions property.

Within a few lines, you can instantiate a code compiler and create both EXEs and DLLs. Personally, I find making DLLs much less painful than trying to encapsulate all the requirements for a windows forms application, encapsulating only what is necessary to create the dynamic content. But, of course, the above posters demonstrate that compiling a windows Forms application isn't too hard - once you know how :)


Stephen J Whiteley
SJWhiteley  Tuesday, November 18, 2008 10:28 PM

SJ': thanks for summary of links, I visited and overviewed it.

Still I would be much curious, if there is some way for my Reflection-Compiler conception, which simplifies whole Daymere's problembypassing creating any resources. Possible it should be pre-compilation implemented, so that some property or rather function of class ".GetCode()$" instantiated if used in code. It would be necessary in case, that there is no option for retrieving whole code, also with method bodies, thru Reflection functionality. In this case (that is not providable nor provided), would be such function implemented as "automatic pre-compilation resources update" - if myClass.GetCode() is used, myClass is automatically refreshed by pre-compilation process in resources, and GetCode() then returns its content. This would be also possible with adding "Class" type to resources... It would shorten whole Daymere's solution into very short line transcription :)

Regards,

Matt

konikula  Tuesday, November 18, 2008 11:33 PM

You can use google to search for other answers

Custom Search

More Threads

• Converting textbox's text into Decimal
• Problem with TreeView Scrolling to the right
• Why my Alarm cannot Debug?
• EPSON ESC/POS How do I write commands through the serial port.
• Using wildcards in a string
• Searching an array
• Number must be either non-negative and less than or equal to Int32.MaxValue or -1.
• How to Override Mouse Down
• Flexible Datagrid?
• Limiting mouse movement in VB.net , clipcursor()??!?!