Solved

Compiling programatically; how to add system references to code?

Posted on 2013-11-14
21
309 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Salesforce Has Never Been Easier

Improve and reinforce salesforce training & adoption using WalkMe's digital adoption platform. Start saving on costly employee training by creating fast intuitive Walk-Thrus for Salesforce. Claim your Free Account Now

 
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

SharePoint Admin?

Enable Your Employees To Focus On The Core With Intuitive Onscreen Guidance That is With You At The Moment of Need.

Question has a verified solution.

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

Article by: Ivo
C# And Nullable Types Since 2.0 C# has Nullable(T) Generic Structure. The idea behind is to allow value type objects to have null values just like reference types have. This concerns scenarios where not all data sources have values (like a databa…
This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

732 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