Solved

Compiling programatically; how to add system references to code?

Posted on 2013-11-14
21
308 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
ID: 39649249
Did you add a reference to your project's references node?
0
 
LVL 22

Expert Comment

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

Author Comment

by:FrancineTaylor
ID: 39649268
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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 22

Expert Comment

by:p_davis
ID: 39649277
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
ID: 39649278
I will take a look at the site posted.
0
 
LVL 22

Expert Comment

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

Expert Comment

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

Author Comment

by:FrancineTaylor
ID: 39649311
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
ID: 39649350
could you possibly post what you have for code?
0
 
LVL 1

Author Comment

by:FrancineTaylor
ID: 39649390
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
 
LVL 1

Author Comment

by:FrancineTaylor
ID: 39649393
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
ID: 39649397
And here's how I'm calling it:

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

Expert Comment

by:p_davis
ID: 39649402
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 75

Expert Comment

by:käµfm³d 👽
ID: 39650385
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
ID: 39651695
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 75

Expert Comment

by:käµfm³d 👽
ID: 39651729
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
ID: 39651871
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 75

Expert Comment

by:käµfm³d 👽
ID: 39651888
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
ID: 39651908
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 75

Accepted Solution

by:
käµfm³d   👽 earned 500 total points
ID: 39651943
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
ID: 39652033
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

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: Najam
Having new technologies does not mean they will completely replace old components.  Recently I had to create WCF that will be called by VB6 component.  Here I will describe what steps one should follow while doing so, please feel free to post any qu…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

679 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