Click here to Skip to main content
15,907,395 members
Please Sign up or sign in to vote.
4.33/5 (3 votes)
See more:
Hi,

I've been on this for couple hours!!

I searched google and of course this site but didnt find some useful thing about adding reference programmatically!

I'm writing an application which in some part of this application I need to generate some code in application's run time and create an exe file and run that .exe gets some result from that, then cleanup everything!

My problem is I dont know how to add-in some reference.
For example, if I have something like this, when I compile generated codes I give compile error which indicates that I did not add references!!!!
// Some generated code here ...

// COMPILE ERROR : I DID NOT ADD ' SYSTEM.XML ' REFERENCE
System.Xml.XmlConvert obj = new System.Xml.XmlConvert();

// Some other generated code here ...


Can someone give me some useful and correct code/reference ???

I need help ASAP

thanks in advance ;)
Posted
Updated 6-Mar-11 21:45pm
v4
Comments
Sergey Alexandrovich Kryukov 6-Mar-11 16:06pm    
Interesting question, my 4! It won't work like that. There are other opportunities I described in my Answer; this is all you can do.
You can also give up using any dynamic assembly, which could be a sound practical solution, depending on your ultimate goals.
--SA
dariush_ha 6-Mar-11 19:21pm    
my problem definitely needs dynamic code generating, and in code generating i definitely need to using dynamic assemblies!:|
there is no other way(beside dynamic code generating) if there was i noticed:)
Sergey Alexandrovich Kryukov 6-Mar-11 20:53pm    
Can you explain the ultimate goals of the project in connection to your ideas of dynamic usage of the assembly? So far, I cannot see the use case. For example, System.Xml reference the assembly which is in .NET CAG, you just have to reference it in first place.

I gave you all the technical aspects you may possibly need. That's all you can do. On top of that, there must be the application architecture of on your technological and design. It should be considered upon the principle goals of the project.

--SA
dariush_ha 6-Mar-11 21:17pm    
I didnt say what is the purpose of this project because i thing this maybe funny:)

The project ultimate goal is design a prototype of what Visual Studio is doing !!
dariush_ha 6-Mar-11 21:25pm    
Well of course this is not a serious job:D:D

i'm just sophomore of software engineering, and this is my home work, which will take my next 3 month!:)

This is no such thing as "adding reference" to executing assembly. You have to add (load) assembly itself.

You either load all assemblies statically during compilation or load and use a new assembly during run-time. This way you can develop plug-ins to your system: you can locate the class from System.Reflection.Assembly (don't do it by name, this is unsupportable; instead, declare and use some interface a plug-in class is supposed to implement and find a class by its interface using System.Reflection.Assembly.GetTypes, alternatively, you can develop and use some assembly attribute to point out what classes to use as the plug-in implementation classes, but also use interface.) An assembly can be loaded during run time using the methods System.Reflection.Assembly.LoadFile, System.Reflection.Assembly.LoadFrom or System.Reflection.Assembly.Load. When a plug-in class is located, obtain and invoke its constructor and assign the constructed object to interface reference. Use this interface reference to work with this (dynamically loaded during run-time) assembly.

There can be a more difficult requirement, when you need to load assemblies repeatedly. This would cause a memory leak, because — attention! — it is not possible to unload assembly. This is designed so due to .NET ideology to avoid potential problems with calls to unloaded code. However, it can be done through loading a new assembly in a separate Application Domain: the whole domain can be unloaded. See the class System.AppDomain for more information. The assemblies can be loaded in the Domain using System.AppDomain.Load methods.

The AppDomain approach may need considerable design/development approach due to complete data isolation between Application Domains, so inter-domain exchange is the same inter-process communication. This task is simplified for inter-domain communications, because the class System.AppDomain provides simplified inter-process communication facilities such as System.AppDomain.SetData methods.

I've listed all of the possibilities, to best of my knowledge. One can say System.Reflection.Emit methods are also applicable. This is true but beyond the subject under discussion. Emits methods address creation and using of code during run time, not using already existing compiled assemblies.

—SA
 
Share this answer
 
v2
Comments
Bryian Tan 6-Mar-11 16:31pm    
Good feedback :)
Sergey Alexandrovich Kryukov 6-Mar-11 18:29pm    
Thank you. Most importantly, working.
--SA
dariush_ha 6-Mar-11 16:52pm    
seems wise answer, thank you:)
let me see what can i do.
i'm not accepting this answer because, there are may be other ways, let's not close this topic for a while;)
Sergey Alexandrovich Kryukov 6-Mar-11 18:37pm    
You will need to accept the answer when and if you understand it; I'll explain why:

You see, even if your use a different approach, it will surely be beyond your Question. (The question is very interesting.) You wanted to add reference during run time, but the only relevant technique is adding (loading) assembly during run-time. All other methods will be at the level of application re-design based on giving up the dynamic (run-time) assembly.

Practically, your overwork can be better that dynamic method (easier, more reliable, etc.), but you see, when you accept the Answer, the main criteria is answering your original Question, not practical options beyond the topic of the Question.

If you want to discuss something beyond that, ask another Question...
Isn't that fair enough?

--SA
dariush_ha 6-Mar-11 18:41pm    
fair enough;)
//'This is the very small sample of creating runtime executable and adding references to it.
public static void Main(string[] arguements)
{
System.Text.StringBuilder lScript = new System.Text.StringBuilder();
lScript.Append("Public Class TestVB" + Environment.NewLine);
lScript.Append("Public Shared Sub Main()" + Environment.NewLine);
lScript.Append("System.Windows.Forms.MessageBox.Show(\"Hello World!\")" + Environment.NewLine);
lScript.Append("End Sub" + Environment.NewLine);
lScript.Append("End Class" + Environment.NewLine);
string tempPath = System.IO.Path.GetTempFileName();
System.IO.StreamWriter streamWriter = null;
streamWriter = System.IO.File.CreateText(tempPath);
streamWriter.Write(lScript.ToString());
streamWriter.Flush();
streamWriter.Close();
System.CodeDom.Compiler.CompilerResults comResult = null;
System.CodeDom.Compiler.CompilerErrorCollection compErrors = new System.CodeDom.Compiler.CompilerErrorCollection();
Microsoft.VisualBasic.VBCodeProvider codeProvider = new Microsoft.VisualBasic.VBCodeProvider();
System.CodeDom.Compiler.CompilerParameters compilerParameters = new System.CodeDom.Compiler.CompilerParameters();
compilerParameters.ReferencedAssemblies.Add("System.dll");
compilerParameters.ReferencedAssemblies.Add("System.Windows.Forms.dll");
compilerParameters.GenerateExecutable = true;
compilerParameters.TreatWarningsAsErrors = false;
comResult = codeProvider.CompileAssemblyFromFile(compilerParameters, tempPath);
compErrors = comResult.Errors;
System.Text.StringBuilder errors = new System.Text.StringBuilder();
foreach (System.CodeDom.Compiler.CompilerError comError in comResult.Errors)
{
errors.Append(comError.ToString());
}
Console.WriteLine(errors.ToString());
Console.ReadKey();
Assembly myapplication = comResult.CompiledAssembly;
System.Diagnostics.ProcessStartInfo info = new System.Diagnostics.ProcessStartInfo(System.IO.Directory.GetParent(tempPath).FullName + @"\" + myapplication.ManifestModule.Name);
System.Diagnostics.Process.Start(info);
}
 
Share this answer
 
v3
Comments
dariush_ha 9-Mar-11 17:33pm    
Thanks alot, u ease this for me alot;)
my problem was i wouldn't put ".dll" at the end of adding namespaces!:)
dariush_ha 12-Mar-11 17:39pm    
i generate codes, but the problem is when i launch the compiled .exe file i get 'console backgournded ' form app!! where i generate codes in order to create a Form application!!

any idea to avoid this kind of problems??[ i googled but the given results are foggy!!:) ]
avigodse 15-Mar-11 11:31am    
This example is just console level application, and by replacing windows form in place of class, will give you desired output. By default this will work as a console application with windows forms support.
zingoraa 23-Mar-11 8:06am    
i hv been looking 4 same snipet. thx a tons.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900