.net - Compile a non-commandline application using CodeDomProvider? -
i've written simple function automate compilation of single exe assembly embedded resource:
public shared function compileassembly(byval codeprovider codedomprovider, byval isexecutable boolean, byval targetfile string, optional byval resources ienumerable(of string) = nothing, optional byval code string = "") compilerresults dim cp new compilerparameters cp ' generate exe or dll. .generateexecutable = isexecutable ' set assembly file name generate. .outputassembly = targetfile ' set compiler argument optimize output. .compileroptions = "/optimize" ' specify class contains main method of executable. if codeprovider.supports(generatorsupport.entrypointmethod) .mainclass = "mainclass" end if ' set embedded resource file of assembly. if codeprovider.supports(generatorsupport.resources) andalso resources isnot nothing .embeddedresources.addrange(resources.toarray) end if end return codeprovider.compileassemblyfromsource(cp, code) end function
the problem need compile non-commandline application, class provide method should executed when app runs:
dim sourcecode string = <a> public class mainclass sub mainmethod() ' when app executed... end sub end class </a>.value
but can't find way it.
i can compile console applications because codeprovider seems needs entrypoint, able compile this, not want:
dim sourcecode string = <a> module mainmodule sub main() end sub end module </a>.value
how needs?.
i want share working codedomprovider compiler routine:
imports system.codedom.compiler namespace tools public notinheritable class codedomutil ''' <summary> ''' specifies <see cref="compilerparameters"></see> target assembly. ''' </summary> public enum targetassembly integer ''' <summary> ''' command line interface executable. ''' </summary> cli = 0 ''' <summary> ''' graphical user interface executable. ''' </summary> gui = 1 ''' <summary> ''' dynamic-link library. ''' </summary> dll = 2 end enum ''' <remarks> ''' ***************************************************************** ''' title : compile assembly (from reaource). ''' author: elektro ''' date : 14-june-2015 ''' usage : ''' ''' using vbcodeprovider new microsoft.visualbasic.vbcodeprovider ''' ''' dim resultvb compilerresults = ''' codedomutil.compileassembly(codeprovider:=vbcodeprovider, ''' targetassembly:=codedomutil.targetassembly.dll, ''' targetfile:="c:\vb assembly.dll", ''' resources:={"c:\myresources.resx"}, ''' referencedassemblies:={"system.dll"}, ''' mainclassname:="mainnamespace.mainclass", ''' sourcecode:=<a> ''' imports system ''' ''' namespace mainnamespace ''' ''' public notinheritable mainclass ''' ''' end class ''' ''' end namespace ''' </a>.value) ''' ''' dim warnings ienumerable(of compilererror) = ''' ce compilererror in resultvb.errors.cast(of compilererror)() ''' ce.iswarning ''' ''' dim errors ienumerable(of compilererror) = ''' ce compilererror in resultvb.errors.cast(of compilererror)() ''' not ce.iswarning ''' ''' each war compilererror in warnings ''' debug.writeline(string.format("{0}| warning: {1}", war.errornumber, war.errortext)) ''' next war ''' ''' each err compilererror in errors ''' debug.writeline(string.format("{0}| error: {1}", err.errornumber, err.errortext)) ''' next err ''' ''' end using ''' ----------------------------------------------------------------- ''' using cscodeprovider new microsoft.csharp.csharpcodeprovider ''' ''' dim resultcs compilerresults = ''' codedomutil.compileassembly(codeprovider:=cscodeprovider, ''' targetassembly:=codedomutil.targetassembly.dll, ''' targetfile:="c:\c# assembly.dll", ''' resources:={"c:\myresources.resx"}, ''' referencedassemblies:={"system.dll"}, ''' mainclassname:="mainnamespace.mainclass", ''' sourcecode:=<a> ''' using system; ''' ''' namespace mainnamespace ''' { ''' class mainclass ''' { ''' ''' } ''' } ''' </a>.value) ''' ''' dim warnings ienumerable(of compilererror) = ''' ce compilererror in resultcs.errors.cast(of compilererror)() ''' ce.iswarning ''' ''' dim errors ienumerable(of compilererror) = ''' ce compilererror in resultcs.errors.cast(of compilererror)() ''' not ce.iswarning ''' ''' each war compilererror in warnings ''' debug.writeline(string.format("{0}| warning: {1}", war.errornumber, war.errortext)) ''' next war ''' ''' each err compilererror in errors ''' debug.writeline(string.format("{0}| error: {1}", err.errornumber, err.errortext)) ''' next err ''' ''' end using ''' ***************************************************************** ''' </remarks> ''' <summary> ''' compiles .net assembly executable or link library. ''' </summary> ''' <param name="codeprovider">the code provider.</param> ''' <param name="targetassembly">the kind of assembly generate.</param> ''' <param name="targetfile">the target file create.</param> ''' <param name="resources">the embedded resources (if any).</param> ''' <param name="referencedassemblies">the referenced assemblies (if any).</param> ''' <param name="mainclassname">the code compile (if any).</param> ''' <param name="sourcecode">the sourcecode compile (if any).</param> ''' <exception cref="exception">the current codedomprovider not support resource embedding.</exception> ''' <exception cref="notimplementedexception">default sourcecode not implemented specified codedomprovider. please, set sourcecode yourself.</exception> ''' <returns>the results of compiler operation.</returns> public shared function compileassembly(byval codeprovider codedomprovider, byval targetassembly targetassembly, byval targetfile string, optional byval resources ienumerable(of string) = nothing, optional byval referencedassemblies ienumerable(of string) = nothing, optional byval mainclassname string = "mainnamespace.mainclass", optional byval sourcecode string = nothing) compilerresults ' set default assembly reference. if referencedassemblies nothing referencedassemblies = {"system.dll"} end if dim cp new compilerparameters cp ' set compiler arguments. select case targetassembly case codedomutil.targetassembly.gui .compileroptions = "/optimize /target:winexe" case else .compileroptions = "/optimize" end select ' generate exe or dll. .generateexecutable = (targetassembly <> codedomutil.targetassembly.dll) ' save assembly physical file. .generateinmemory = false ' generate debug information (pdb). .includedebuginformation = false ' set assembly file name generate. .outputassembly = targetfile ' add assembly reference. .referencedassemblies.addrange(referencedassemblies.toarray) ' set temporary files collection. ' tempfilecollection stores temporary files generated during build in current directory. .tempfiles = new tempfilecollection(tempdir:=io.path.gettemppath(), keepfiles:=true) ' set whether treat warnings errors. .treatwarningsaserrors = false ' set level @ compiler should start displaying warnings. ' 0 - turns off emission of warning messages. ' 1 - displays severe warning messages. ' 2 - displays level 1 warnings plus certain, less-severe warnings, such warnings hiding class members. ' 3 - displays level 2 warnings plus certain, less-severe warnings, such warnings expressions evaluate true or false. ' 4 - displays level 3 warnings plus informational warnings. default warning level @ command line. .warninglevel = 3 ' set embedded resource file of assembly. if codeprovider.supports(generatorsupport.resources) andalso (resources isnot nothing) .embeddedresources.addrange(resources.toarray) elseif (not codeprovider.supports(generatorsupport.resources)) andalso (resources isnot nothing) throw new exception(message:="the current codedomprovider not support resource embedding.") end if ' specify class contains main method of executable. if codeprovider.supports(generatorsupport.entrypointmethod) .mainclass = mainclassname if (typeof codeprovider microsoft.visualbasic.vbcodeprovider) andalso (string.isnullorempty(sourcecode)) andalso .generateexecutable sourcecode = <a> imports system namespace mainnamespace module mainclass sub main() end sub end module end namespace </a>.value elseif (typeof codeprovider microsoft.visualbasic.vbcodeprovider) andalso (string.isnullorempty(sourcecode)) andalso not .generateexecutable sourcecode = <a> imports system namespace mainnamespace public notinheritable mainclass end class end namespace </a>.value elseif (typeof codeprovider microsoft.csharp.csharpcodeprovider) andalso (string.isnullorempty(sourcecode)) andalso .generateexecutable sourcecode = <a> using system; namespace mainnamespace { class mainclass { static void main(string[] args) { } } } </a>.value elseif (typeof codeprovider microsoft.csharp.csharpcodeprovider) andalso (string.isnullorempty(sourcecode)) andalso not .generateexecutable sourcecode = <a> using system; namespace mainnamespace { class mainclass { } } </a>.value elseif string.isnullorempty(sourcecode) throw new notimplementedexception(message:="default sourcecode not implemented specified codedomprovider. please, specify sourcecode.") end if end if end return codeprovider.compileassemblyfromsource(cp, sourcecode) end function ''' <remarks> ''' ***************************************************************** ''' title : compile assembly (from file). ''' author: elektro ''' date : 14-june-2015 ''' usage : ''' ''' using vbcodeprovider new microsoft.visualbasic.vbcodeprovider ''' ''' dim resultvb compilerresults = ''' codedomutil.compileassembly(codeprovider:=vbcodeprovider, ''' targetassembly:=codedomutil.targetassembly.dll, ''' sourcefile:="c:\sourcecode.vb", ''' targetfile:="c:\vb assembly.dll", ''' resources:={"c:\myresources.resx"}, ''' referencedassemblies:={"system.dll"}, ''' mainclassname:="mainnamespace.mainclass") ''' ''' dim warnings ienumerable(of compilererror) = ''' ce compilererror in resultvb.errors.cast(of compilererror)() ''' ce.iswarning ''' ''' dim errors ienumerable(of compilererror) = ''' ce compilererror in resultvb.errors.cast(of compilererror)() ''' not ce.iswarning ''' ''' each war compilererror in warnings ''' debug.writeline(string.format("{0}| warning: {1}", war.errornumber, war.errortext)) ''' next war ''' ''' each err compilererror in errors ''' debug.writeline(string.format("{0}| error: {1}", err.errornumber, err.errortext)) ''' next err ''' ''' end using ''' ----------------------------------------------------------------- ''' using cscodeprovider new microsoft.csharp.csharpcodeprovider ''' ''' dim resultcs compilerresults = ''' codedomutil.compileassembly(codeprovider:=cscodeprovider, ''' targetassembly:=codedomutil.targetassembly.dll, ''' sourcefile:="c:\sourcecode.cs", ''' targetfile:="c:\cs assembly.dll", ''' resources:={"c:\myresources.resx"}, ''' referencedassemblies:={"system.dll"}, ''' mainclassname:="mainnamespace.mainclass") ''' ''' dim warnings ienumerable(of compilererror) = ''' ce compilererror in resultcs.errors.cast(of compilererror)() ''' ce.iswarning ''' ''' dim errors ienumerable(of compilererror) = ''' ce compilererror in resultcs.errors.cast(of compilererror)() ''' not ce.iswarning ''' ''' each war compilererror in warnings ''' debug.writeline(string.format("{0}| warning: {1}", war.errornumber, war.errortext)) ''' next war ''' ''' each err compilererror in errors ''' debug.writeline(string.format("{0}| error: {1}", err.errornumber, err.errortext)) ''' next err ''' ''' end using ''' ***************************************************************** ''' </remarks> ''' <summary> ''' compiles .net assembly executable or link library. ''' </summary> ''' <param name="codeprovider">the code provider.</param> ''' <param name="targetassembly">the kind of assembly generate.</param> ''' <param name="sourcefile">the source file compile.</param> ''' <param name="targetfile">the target file create.</param> ''' <param name="resources">the embedded resources (if any).</param> ''' <param name="referencedassemblies">the referenced assemblies (if any).</param> ''' <param name="mainclassname">the code compile (if any).</param> ''' <exception cref="exception">the current codedomprovider not support resource embedding.</exception> ''' <returns>the results of compiler operation.</returns> public shared function compileassembly(byval codeprovider codedomprovider, byval targetassembly targetassembly, byval sourcefile string, byval targetfile string, optional byval resources ienumerable(of string) = nothing, optional byval referencedassemblies ienumerable(of string) = nothing, optional byval mainclassname string = "mainnamespace.mainclass") compilerresults ' set default assembly reference. if referencedassemblies nothing referencedassemblies = {"system.dll"} end if dim cp new compilerparameters cp ' set compiler arguments. select case targetassembly case codedomutil.targetassembly.gui .compileroptions = "/optimize /target:winexe" case else .compileroptions = "/optimize" end select ' generate exe or dll. .generateexecutable = (targetassembly <> codedomutil.targetassembly.dll) ' save assembly physical file. .generateinmemory = false ' generate debug information (pdb). .includedebuginformation = false ' set assembly file name generate. .outputassembly = targetfile ' add assembly reference. .referencedassemblies.addrange(referencedassemblies.toarray) ' set temporary files collection. ' tempfilecollection stores temporary files generated during build in current directory. .tempfiles = new tempfilecollection(tempdir:=io.path.gettemppath(), keepfiles:=true) ' set whether treat warnings errors. .treatwarningsaserrors = false ' set level @ compiler should start displaying warnings. ' 0 - turns off emission of warning messages. ' 1 - displays severe warning messages. ' 2 - displays level 1 warnings plus certain, less-severe warnings, such warnings hiding class members. ' 3 - displays level 2 warnings plus certain, less-severe warnings, such warnings expressions evaluate true or false. ' 4 - displays level 3 warnings plus informational warnings. default warning level @ command line. .warninglevel = 3 ' set embedded resource file of assembly. if codeprovider.supports(generatorsupport.resources) andalso (resources isnot nothing) .embeddedresources.addrange(resources.toarray) elseif (not codeprovider.supports(generatorsupport.resources)) andalso (resources isnot nothing) throw new exception(message:="the current codedomprovider not support resource embedding.") end if ' specify class contains main method of executable. if codeprovider.supports(generatorsupport.entrypointmethod) .mainclass = mainclassname end if end return codeprovider.compileassemblyfromfile(cp, {sourcefile}) end function end class end namespace
Comments
Post a Comment