Solved

Compiling programatically; how to add system references to code?

Posted on 2013-11-14
21
299 Views
Last Modified: 2013-11-15
I found this really well-done example of how to programatically compile code at:

http://support.microsoft.com/kb/304655

I wanted to make one small modification; instead of outputting the error to Console, I wanted to use MessageBox.  I added the reference "using System.Windows.Forms;" right after the using System reference.

When I ran the build, I got this exception: Line number 2, Error Number: CS0234, 'The type or namespace name 'Windows' does not exist in the namespace 'System' (are you missing an assembly reference?);

How can I get the compile to add this reference to the compile?
0
Comment
Question by:FrancineTaylor
  • 9
  • 8
  • 4
21 Comments
 
LVL 22

Expert Comment

by:p_davis
Comment Utility
Did you add a reference to your project's references node?
0
 
LVL 22

Expert Comment

by:p_davis
Comment Utility
If you started a console application you would have to do that
0
 
LVL 1

Author Comment

by:FrancineTaylor
Comment Utility
The example itself is being run from a Windows form, so the executing project definitely has System.Windows.Forms.

It seems like the CodeDomProvider needs to be told to add the reference?
0
 
LVL 22

Expert Comment

by:p_davis
Comment Utility
I'm sorry, I guess that I got confused by the use of the word console.... i thought it was a console application.
0
 
LVL 22

Expert Comment

by:p_davis
Comment Utility
I will take a look at the site posted.
0
 
LVL 22

Expert Comment

by:p_davis
Comment Utility
ok the project that you are compiling is a console app
0
 
LVL 22

Expert Comment

by:p_davis
Comment Utility
so i'm guessing that the reference to the system.windows .form isn't registered with it
0
 
LVL 1

Author Comment

by:FrancineTaylor
Comment Utility
How would I modify the example given by the site to show the Hello World message in a MessageBox?  Would it be a modification in the text string pasted into the text box of the windows form running the compile?

Or is there some modification that needs to be done to the code-behind in the Build Click event?
0
 
LVL 22

Expert Comment

by:p_davis
Comment Utility
could you possibly post what you have for code?
0
 
LVL 1

Author Comment

by:FrancineTaylor
Comment Utility
Here's the static method that I tried to create using the example at the site:

            public static string CompileCode(string codeToCompile, string pathToCompileTo, bool RunAfterCompiling)
            {
                  CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp");
                  string Output = pathToCompileTo;

                  System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
                  //Make sure we generate an EXE, not a DLL
                  parameters.GenerateExecutable = true;
                  parameters.OutputAssembly = Output;
                  CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, codeToCompile);

                  string error = null;
                  if (results.Errors.Count > 0)
                  {
                        StringBuilder sb = new StringBuilder();
                        foreach (CompilerError CompErr in results.Errors)
                        {
                              sb.AppendLine("Line number " + CompErr.Line +
                                                ", Error Number: " + CompErr.ErrorNumber +
                                                ", '" + CompErr.ErrorText + ";" +
                                                Environment.NewLine + Environment.NewLine);
                        }
                        error = sb.ToString();
                  }
                  else
                  {
                        //If we clicked run then launch our EXE
                        if (RunAfterCompiling) Process.Start(Output);
                  }
                  return error;
            }
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 1

Author Comment

by:FrancineTaylor
Comment Utility
private static string ProgramHelloWorldWindows()
            {
                  string value =
                        @"using System;

                        namespace HelloWorld
                        {
                              /// <summary>
                              /// Summary description for Class1.
                              /// </summary>
                              class HelloWorldClass
                              {
                                    static void Main(string[] args)
                                    {
                                          System.Windows.Forms.MessageBox.Show('Hello World');
                                    }
                              }
                        }
                        ";
                  return value.Replace("'", Helper.DoubleQuote);
            }
0
 
LVL 1

Author Comment

by:FrancineTaylor
Comment Utility
And here's how I'm calling it:

string error = CompileCode(ProgramHelloWorldConsole(), @"c:\mystuff", true);
0
 
LVL 22

Expert Comment

by:p_davis
Comment Utility
thank you for posting what you have but...
i am sorry, i will have to examine this tomorrow.... got to get the kids.
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
Comment Utility
I added the reference "using System.Windows.Forms;"
That's not adding a reference. That is simply importing a namespace. You need to "Add Reference" to the System.Windows.Forms.dll in order to gain access to the MessageBox class, as p_davis mentioned.
0
 
LVL 1

Author Comment

by:FrancineTaylor
Comment Utility
I don't see a System.Windows.Forms.dll mentioned in the example.  I understand about adding references to projects.  If I simply wanted to write a program with the Hello World code in it, modifying that to use the windows.forms namespace would be simple.

However, if you'll look at the example (the original one at the link) you will see that the "program" is just a string of text pasted into a textbox and run through the CodeDomProvider.  The code used in the example includes the System namespace, but when the System.Windows.Forms namespace is added, it doesn't find that namespace.

All I'm trying to do is modify the code example given at the link which I mentioned in my original question, replacing the Console.Writeline with a MessageBox.Show.  I want to know how to make the Forms namespace available to the CodeDomProvider when it compiles that text string.

Can that be done?  If so, how?
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
Comment Utility
You don't see the System.Windows.Forms.dll mentioned in the example because it's a console application. Console applications don't typically use Forms components, but they can. In order to use those components, you have to reference that DLL. If you want to show a MessageBox, then you need to reference the DLL that contains it. That is what has been stated throughout this thread.
0
 
LVL 1

Author Comment

by:FrancineTaylor
Comment Utility
I'm sorry, perhaps I'm not understanding what you are trying to tell me.  *What* is a console application?  The program represented in the string? (see ProgramHelloWorldWindows() above)

If so, how would I modify that piece of code to make it not a console application?  What piece of code would I paste into the text box of the form created by the steps given in the example.

Let me step through my understanding of what is going on in the example.

I have a windows form application.  It has a form.  The form has a text box and a button marked "Run".  I paste the following code into the text box and click the "Run" button:

using System;

namespace HelloWorld
{
      /// <summary>
      /// Summary description for Class1.
      /// </summary>
      class HelloWorldClass
      {
            static void Main(string[] args)
            {
                  Console.WriteLine("Hello World!");
                  Console.ReadLine();
            }
      }
}

The click event grabs the code out of the text box, runs it through the compiler, creating an executable, which it then executes, causing the same effect as if a console application had been run for the two lines of code above.  Is that interpretation correct?

In order for that executable to bring up a message box instead of running a message to Console, how should I alter the embedded code?

I created a windows forms application that does nothing but bring up a message box with "Hello World" in it.  Here's what the code looks like.

using System;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
      static class Program
      {
            [STAThread]
            static void Main()
            {
                  MessageBox.Show("Hello World");
            }
      }
}

To understand what I am asking:

Build the simple compiler using the steps here: http://support.microsoft.com/kb/304655

Paste the above code into the text box.  Click the Build button.

This error appears in the second text box: Line number 1, Error Number: CS0234, 'The type or namespace name 'Windows' does not exist in the namespace 'System' (are you missing an assembly reference?);

Now...how do I fix the code so that it doesn't throw the error?  Do I need to modify something in the text which is pasted in?  Or do I need to modify the code in the Build_Click event so that the CodeDomProvider includes the appropriate reference when it is compiling the code?
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
Comment Utility
Is the message box that you are trying to show in the application that is running, or that is being compiled?
0
 
LVL 1

Author Comment

by:FrancineTaylor
Comment Utility
This is the code which I paste into the text box.
--------------------------------------------------------------------------------------------------------------------------
using System;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
      static class Program
      {
            [STAThread]
            static void Main()
            {
                  MessageBox.Show("Hello World");
            }
      }
}
------------------------------------------------------------------------------------------------------------------------

When I click the Build button, this pasted code is grabbed and run through the compiler to create an executable.

The problem seems to be that the compiler has not been told to include the System.Windows.Forms .dll when it compiles the code.  I want to know how to do that.
0
 
LVL 74

Accepted Solution

by:
käµfm³d   👽 earned 500 total points
Comment Utility
OK, see if the example I posted here:

http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_26805504.html#a34848988

makes sense. I did exactly what you are talking about here. Line 27 is where I am actually including the assembly references.
0
 
LVL 1

Author Comment

by:FrancineTaylor
Comment Utility
OK, thank you!  That is exactly what I was asking for.

I used this code to add in a bunch of references:

foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
{
      parameters.ReferencedAssemblies.Add(asm.Location);
}

Overkill, I know, but I'm okay with that for now.  Thanks again...
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Suggested Solutions

Summary: Persistence is the capability of an application to store the state of objects and recover it when necessary. This article compares the two common types of serialization in aspects of data access, readability, and runtime cost. A ready-to…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now