|
|
Comments and Discussions
|
|
 |

|
Congratulations and Thanks a lot!!
|
|
|
|

|
Hi Jim,
Thanks for your interesting article. Though something isn't exactly clear for me. The compilation occurs only in memory? That's to say nothing is saved to the hard disk. Is that right?
Thanks,
Nikolaos
|
|
|
|

|
Hi
I need access from dynamically created assembly to Host application friend class (this class dynamically create assembly).
It is possible to add to DynamicallyCreatedAssembly reference to Host application, but it must be as public.
Is it possible to access to no public class?
Regards
|
|
|
|

|
Great article, thanks.
One problem I have with a console (formless) application is how to access a method outside the compiled class, eg Module1.FunctionA() or ClassXYZ.FunctionB(), all of which are declared Public.
I'm getting the error BC30451, Name 'FunctionA' is not declared when I try to call it from the compiled function. The same goes if I prefix the call with ConsoleApplication1, Module1 or ClassXYZ. They're all unrecognized.
Is there a way I can get the thing to
- compile inside the Module1 namespace
- or import, reference, or pass in args() the module, the class or at least a sub/function?
My code looks like:
Public Module Module1
Public Function A
End Function
...
Public Class XYZ
Public Function B
End Function
Sub Whatever
CompileAndRun()
End Sub
...
End Class
End Module
Project options shows:
Assembly name is server
Root namespace is ConsoleApplication1
Startup object is ConsoleApplication1.Module1
Rather than using args() As String, I'm using As Object, so I should be able to pass anything to the compiled function.
Solved
At Mike's Code Blog, here, he writes: "tell the compiler what extra assemblies we want to reference. The most general method I've found so far is simply to reference all of the assemblies that our parent program references, as well as the parent assembly itself":
Dim executingAssembly As System.Reflection.Assembly
executingAssembly = System.Reflection.Assembly.GetExecutingAssembly()
params.ReferencedAssemblies.Add(executingAssembly.Location)
for each assemblyName As System.Reflection.AssemblyName _
in executingAssembly.GetReferencedAssemblies()
params.ReferencedAssemblies.Add(System.Reflection.Assembly.Load(assemblyName).Location)
Next
However, the parent program assembly 'server' has *not* been added, so add it here (path will need changing):
params.ReferencedAssemblies.Add(System.Reflection.Assembly.LoadFile _
("c:\MGServer\server\bin\debug\server.exe").Location)
Many thanks,
Eric T
modified on Tuesday, October 6, 2009 5:41 PM
|
|
|
|

|
I am working on project for a company and i will like to compile the program and send it to the company to install. please how to go about it.
usman
|
|
|
|

|
Following your excellent example I created an application which successfully performs functions on a dynamically compiled assembly.
The compiled assembly also calls back to the Entry assembly to execute shared functions. However I cannot get it to access a windows forms control on the Entry assembly.
So I tried creating an unshared function on the Entry assembly and called it back from the dynamic assembly.
This appeared to work inasmuch as I could single step through the called function in the Entry assembly and it appeared to add an entry to a list box control and to append some text to a textbox. But on return Nothing was visible in either control! I tried adding a me.refresh but that didn't help either
Any ideas?
|
|
|
|

|
Hi Jim,
Great article.
I would like to pass an array to the StaticMethod, so I tried changing the StaticMethod like this:
Public Shared Function StaticMethod(ByVal Arg() As String) As String
Doing this give a "Missing Method Exception"
Any ideas?
Thank you,
Tom
|
|
|
|

|
Jim,
I just migrated your project to VS2005 without any problems and successfully integrate your sample code into an application that generates custom lot numbers for batch production.
Thanks for the wonderfully comprehensive example...it has saved me ooodles of time.
Scott
|
|
|
|

|
Is there a way that I can use a class that I have created in the current project? Inside the assembly?
|
|
|
|

|
I am developing a web application in which i am using This "SYSTEM.CODEDOM.COMPILER" namespace which provide with the Csharpprovider to compile the c#program on the fly...it is working fine.....
Problem:
Since this is a web application,if we try to access the application through the browser(INTERNET EXPLOER)and compile the program, it gives me an error saying that access is denied for the file c:\windows\system32\*.tmp.
plsssssssss help me out with this........
|
|
|
|

|
Hi Dude It's a Great Work Thank You
but how i can save the compiled code to .exe File??????
|
|
|
|

|
Hi. Nice article dude!
I'm just wondering if you (i) can do something similar for a pocket pc device.
ie Use a desktop component to generate some form code which can be uploaded to the pocket pc and then 'loaded'.
The method i am current using is to build a 'form description file' which is interpretted by the pda at runtime and used to generate a form on the fly.
If this question is not up your alley, perhaps one of your neighbours might know?!
Cheers,
James.
|
|
|
|

|
How do i write a common procedure in vb.net or asp.net so that i can use it across the project. I dont want to creat a class and instantiate it.
thanks in advance
I have been working in VB6 for quiet some time and latetly ventured into VB.Net and ASP.Net
|
|
|
|
|

|
Hi Jim:
Please help!
I read your article here. I have a simliar task. I am building a web application which can do scheduled build for CS or VB projects. CS project is building fine, but my VB projects build alwasy fails. It seems can't find the references of the .net frame work.
http://www.codeproject.com/vb/net/DotNetCompilerArticle.asp#xx671845xx
Below is my code: the build error is very clear that the references were not taken into account.
build errors:
================
BUILD FAILED FOR JackTestVB
PRIMARY ERROR MESSAGE -
D:\BuildManager\JACKVB\JackTestVB\Global.asax.vb(31,0) : error BC30002: Type 'EventArgs' is not defined.
D:\BuildManager\JACKVB\JackTestVB\Global.asax.vb(35,0) : error BC30002: Type 'EventArgs' is not defined.
D:\BuildManager\JACKVB\JackTestVB\Global.asax.vb(39,0) : error BC30002: Type 'EventArgs' is not defined.
D:\BuildManager\JACKVB\JackTestVB\Global.asax.vb(43,0) : error BC30002: Type 'EventArgs' is not defined.
D:\BuildManager\JACKVB\JackTestVB\Global.asax.vb(47,0) : error BC30002: Type 'EventArgs' is not defined.
D:\BuildManager\JACKVB\JackTestVB\Global.asax.vb(51,0) : error BC30002: Type 'EventArgs' is not defined.
D:\BuildManager\JACKVB\JackTestVB\Global.asax.vb(55,0) : error BC30002: Type 'EventArgs' is not defined.
my code to build for both C# or VB projects
==================================
public bool CompileCSharpVBDotNetProject( String[] sRefPaths )
{
bool bRet = false;
int i = 0;
int j = 0;
String sReference = "";
String[] sFilArr = new String[FilesList.Count];
FileInfo FilInf = new FileInfo( sFullPath );
CSharpCodeProvider CSProv = null;
VBCodeProvider VBProv = null;
ICodeCompiler iCodeComp = null;
CompilerResults CompRes = null;
CompilerParameters Params = new CompilerParameters();
Params.OutputAssembly = sBinaryBuildTarget + "\\" + sBinaryFileName;
Params.TreatWarningsAsErrors = bTreatWarningsAsErrors;
Params.WarningLevel = iWarningLevel;
// SHACK-UP REFERENCES ...
for( i = 0; i < ReferenceList.Count; i++ )
{
sReference = "";
for( j = 0; j < sRefPaths.GetLength( 0 ); j++ )
{
sReference = sRefPaths[j] + "\\" + ReferenceList[i].ToString();
if( File.Exists( sReference ) )
break;
}
if( sReference.Trim() != "" )
Params.ReferencedAssemblies.Add( sReference );
}
//hard code dll refereencs to test VB compiler (did not work)
// Params.ReferencedAssemblies.Add("System.dll");
// Params.ReferencedAssemblies.Add("System.Drawing.dll");
// Params.ReferencedAssemblies.Add("System.Data.dll");
// Params.ReferencedAssemblies.Add("System.Web.dll");
// Params.ReferencedAssemblies.Add("System.XML.dll");
// SET COMPLETE PATH FOR EACH FILE ...
for( i = 0; i < FilesList.Count; i++ )
{
sFilArr[i] = FilInf.DirectoryName + "\\" + FilesList[i].ToString();
}
if( iBinaryType == BINARY_TYPE_DLL )
Params.GenerateExecutable = false;
else
Params.GenerateExecutable = true;
try
{
switch( iProjectType )
{
case TYPE_CSHARP:
CSProv = new CSharpCodeProvider();
iCodeComp = CSProv.CreateCompiler();
CompRes = iCodeComp.CompileAssemblyFromFileBatch( Params, sFilArr );
break;
case TYPE_VBNET:
VBProv = new VBCodeProvider();
iCodeComp = VBProv.CreateCompiler();
CompRes = iCodeComp.CompileAssemblyFromFileBatch( Params, sFilArr );
break;
}
for( i = 0; i < CompRes.Errors.Count; i++ )
{
ErrorList.Add( CompRes.Errors[i] );
if( CompRes.Errors[i].IsWarning )
bHasWarnings = true;
else
bHasErrors = true;
}
for( i = 0; i < CompRes.Output.Count; i++ )
{
OutputList.Add( CompRes.Output[i] );
}
if( CompRes.NativeCompilerReturnValue == 0 ||( bHasWarnings && !bHasErrors ) )
bRet = true;
else
bRet = false;
}
catch( DirectoryNotFoundException ex )
{
sErrorMessage = ex.Message;
bRet = false;
}
catch( FileLoadException ex )
{
sErrorMessage = ex.Message;
bRet = false;
}
catch( FileNotFoundException ex )
{
sErrorMessage = "FILE INCLUDED IN .NET PROJECT FILE IS NOT UNDER SOURCE CONTROL. " + ex.Message;
bRet = false;
}
if( CSProv != null )
CSProv.Dispose();
return bRet;
}
|
|
|
|

|
This looks quite useful. And, by the way, you also cleared up a problem I have been having on another issue: those pesky flags in the Invoke Member call. I didn't understand their real significance until I read your article.
|
|
|
|

|
how to execute a function (hav to pass arguments) in an assembly in vb.net?
i tried out the code u hav given..but the missingmethods exception kept comin!! kindly someone help me out.
k.uma
|
|
|
|

|
I generate my new assembly in memory per your example but I need to create an instance of an object within my currently executing assembly. The problem I have is that since it is a desktop app I don't get a dll when I compile I get a .exe. I tried adding this to the referenced assemblies and no luck. Without the reference I get that it can not define the class. Any ideas?
|
|
|
|

|
Hi, can anybody help me in getting the reports in excelsheet from VB.NET
Previously i tried throwing the page response to excelsheet on the fly but now my requirement is to update the existing excelsheet and display it to the user.
I am using the following code, which i got from net but my application is giving an error "Access Denied" while creating the instance of Application object itself.
Dim appGDCTracker As New Application
appGDCTracker.set_Visible(0, True)
Dim cwbGDCTracker As Workbooks = appGDCTracker.Workbooks
Dim wbGDCTracker As _Workbook = cwbGDCTracker.Add(XlWBATemplate.xlWBATWorksheet)
Dim wbsGDCTracker As Sheets = wbGDCTracker.Worksheets
Dim wsVAMSIncidentData As _Worksheet
Dim rRange As Range = wbGDCTracker.get_Range("A1", "E1")
Dim array2(5) As Integer
Dim i As Integer
For i = 0 To (array2.GetLength(0)) - 1
array2(i) = i + 1
Next i
Dim args2(1) As [Object]
args2(0) = array2
rRange.GetType().InvokeMember("Value", , Nothing, rRange, args2)
Let me get the help asap.
Thanks in advance for the help !!!
with regards
Amit
|
|
|
|

|
That is some nice code. Well done. An idea might be to make a control inheriting from richtextbox to write the code in, that could pop up listboxes of properties and methods, and color the statements blue, underline errors, etc.
|
|
|
|

|
I changed your article and wrote this piece of code:
private bool Compile(ArrayList sourceList,ArrayList referencesList)
{
bool bResult = false;
Microsoft.VisualBasic.VBCodeProvider provider;
System.CodeDom.Compiler.ICodeCompiler compiler;
System.CodeDom.Compiler.CompilerParameters compilerparams;
System.CodeDom.Compiler.CompilerResults results;
compilerparams = new System.CodeDom.Compiler.CompilerParameters();
compilerparams.GenerateInMemory = false;
compilerparams.TreatWarningsAsErrors = false;
compilerparams.WarningLevel = 4;
compilerparams.IncludeDebugInformation = false;
// Prepare the Sources list
string[] sources = (string[]) sourceList.ToArray(typeof(string));
//Put any references you need here
string[] refs = (string[])referencesList.ToArray(typeof(string));
compilerparams.ReferencedAssemblies.AddRange(refs);
provider = new Microsoft.VisualBasic.VBCodeProvider();
compiler = provider.CreateCompiler();
results = compiler.CompileAssemblyFromSourceBatch(compilerparams,sources);
// If there are any errros, Fire the Event by sending the CompilerResults Info whcih will be
// caught in the Code Editor.
if (results.Errors.Count != 0 )
{
bResult = false;
// Hanlde Errors.
}
else
{
bResult = true;
m_Assembly = results.CompiledAssembly;
}
return bresult;
}
For the First time , If I sent 4 files , the Compiler compiles and gives me the Assembly without any problem.
Next Time, if I add another file and send 5 files, it compiles the 5 files very well , but when I tried to access the CompiledAssembly, it is rising the following EXception "File or assembly name xl0oo7b2.dll, or one of its dependencies, was not found."
at System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Boolean isStringized, Evidence assemblySecurity, Boolean throwOnFileNotFound, Assembly locationHint, StackCrawlMark& stackMark)
at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Boolean stringized, Evidence assemblySecurity, StackCrawlMark& stackMark)
at System.Reflection.Assembly.Load(AssemblyName assemblyRef, Evidence assemblySecurity)
at System.CodeDom.Compiler.CompilerResults.get_CompiledAssembly()
at System.CodeDom.Compiler.CompilerResults.get_CompiledAssembly()
Any idea?: :doh
SARADHI
SARADHI
|
|
|
|

|
I changed your article and wrote this piece of code:
private bool Compile(ArrayList sourceList,ArrayList referencesList)
{
bool bResult = false;
Microsoft.VisualBasic.VBCodeProvider provider;
System.CodeDom.Compiler.ICodeCompiler compiler;
System.CodeDom.Compiler.CompilerParameters compilerparams;
System.CodeDom.Compiler.CompilerResults results;
compilerparams = new System.CodeDom.Compiler.CompilerParameters();
compilerparams.GenerateInMemory = false;
compilerparams.TreatWarningsAsErrors = false;
compilerparams.WarningLevel = 4;
compilerparams.IncludeDebugInformation = false;
// Prepare the Sources list
string[] sources = (string[]) sourceList.ToArray(typeof(string));
//Put any references you need here
string[] refs = (string[])referencesList.ToArray(typeof(string));
compilerparams.ReferencedAssemblies.AddRange(refs);
provider = new Microsoft.VisualBasic.VBCodeProvider();
compiler = provider.CreateCompiler();
results = compiler.CompileAssemblyFromSourceBatch(compilerparams,sources);
// If there are any errros, Fire the Event by sending the CompilerResults Info whcih will be
// caught in the Code Editor.
if (results.Errors.Count != 0 )
{
bResult = false;
// Hanlde Errors.
}
else
{
bResult = true;
m_Assembly = results.CompiledAssembly;
}
return bresult;
}
For the First time , If I sent 4 files , the Compiler compiles and gives me the Assembly without any problem.
Next Time, if I add another file and send 5 files, it compiles the 5 files very well , but when I tried to access the CompiledAssembly, it is rising the following EXception "File or assembly name xl0oo7b2.dll, or one of its dependencies, was not found."
at System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Boolean isStringized, Evidence assemblySecurity, Boolean throwOnFileNotFound, Assembly locationHint, StackCrawlMark& stackMark)
at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Boolean stringized, Evidence assemblySecurity, StackCrawlMark& stackMark)
at System.Reflection.Assembly.Load(AssemblyName assemblyRef, Evidence assemblySecurity)
at System.CodeDom.Compiler.CompilerResults.get_CompiledAssembly()
at System.CodeDom.Compiler.CompilerResults.get_CompiledAssembly()
Any idea?: :doh
SARADHI
|
|
|
|

|
First of all, great code! Everything was working fine for me until I started to add my own functions. Was hoping you could shed some light.
The code compiles without errors, and here is the exact compiled code:
Public Class Sample
Private mPropertyValue As String = ""
Public Shared Function StaticFunction(ByVal Arg As String) As String
Return Arg.ToUpper()
End Function
Public Function SampleFunction(ByVal Arg As String) As String
Return Arg.ToUpper()
End Function
Public Property SampleProperty() As String
Get
Return mPropertyValue
End Get
Set(ByVal Value As String)
mPropertyValue = Value
End Set
End Property
Public Function WriteMe(ByVal Arg As String) as String
Return Arg.toString
End Function
End Class
The error ocurrs in this line:
rslt = scriptType.InvokeMember("WriteMe", _
System.Reflection.BindingFlags.InvokeMethod Or _
System.Reflection.BindingFlags.Public Or _
System.Reflection.BindingFlags.Static, _
Nothing, Nothing, args)
And it returns this error:
System.MissingMethodException: Method Sample.WriteMe not found. at System.RuntimeType.InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters) at System.Type.InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args) at aspxExecuteCode.WebForm1.cmdGo_Click(Object sender, EventArgs e) in c:\inetpub\wwwroot\aspxExecuteCode\WebForm1.aspx.vb:line 189
Any clue? I thought it was like the old compilation still existed after compile and wasn't picking up the new one, but not sure where to start there, so I renamed the names of the functions and again, the old ones worked and new did not.
I did notice that I wasn't able to insert a try, catch, end try, but thought it may be due to the same problem ocurring here.
Also wondering if it is possible to compile ASPX pages or atleast a class that uses the response and request objects.
|
|
|
|

|
First of all, I have learned a lot about VB.NET compiling options from your excellent code. I just have one question about compiling code with embedded resources:
I created a test program with only one Form1 which has an icon embedded into resource Form1.resx. I tried to compile codes in Form1.vb, however unsuccessful because the embedded resource wasn't found. How would I do this?
Thanks.
|
|
|
|

|
I was searching for something like that for quite a while. This is a great start in building a scripting framework for my current project. You are godsent indeed!
Thank you for sharing this.
|
|
|
|

|
Hi, This is one of the finest pieces of code I have come across. Kudos for the good work.
|
|
|
|

|
Thanks for submitting such a decent piece of code. Was working on a similar project, and trying to link the referenced assembly with the host application somehow. Is there a way to add objects to the referenced assembly so I can modify them in the assembly and reference them in the application?
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
|
Compile .NET code programmatically, in memory, then use the resulting assembly to instantiate an object of a class, access its properties and methods, and call a static function.
| Type | Article |
| Licence | |
| First Posted | 19 Nov 2003 |
| Views | 231,227 |
| Bookmarked | 113 times |
|
|