尝试使用 Codedom 生成代码时出错

发布于 2024-11-18 13:51:37 字数 6201 浏览 1 评论 0原文

我的目标:通过使用 CodeDom 创建一个 Windows 窗体应用程序(可执行)。我的意思是我想要一个表单(表单后面有一些代码)并将其转换为可执行文件(就好像我进入 Visual Studio 并单击“构建”>“构建文件”)。不可否认,我在网上找到了这个示例,并且对它进行了轻微的修改。我在尝试生成此代码时遇到错误 - 我以前从未见过的错误。此外,我在 Google 上找不到这些错误(奇怪吧?)...

这是我收到的错误: 不支持元素类型 System.CodeDom.CodeExpression。 参数名称:e

我在以下行中收到此错误:

CodeProvider.GenerateCodeFromCompileUnit(Unit, writer, new CodeGeneratorOptions());

这是我的完整代码:

{

     CodeDomProvider CodeProvider = CodeDomProvider.CreateProvider("CSharp");

         // Create the Unit
     CodeCompileUnit Unit = new CodeCompileUnit();

    // Define a namespace and add Imports statements
    CodeNamespace Namespaces = new CodeNamespace("Test.CreateForm");
        Namespaces.Imports.Add(new CodeNamespaceImport("System"));
        Namespaces.Imports.Add(new CodeNamespaceImport("System.Drawing"));
        Namespaces.Imports.Add(new CodeNamespaceImport("System.Windows.Forms"));
        Namespaces.Imports.Add(new CodeNamespaceImport("System.Xml"));
        Namespaces.Imports.Add(new CodeNamespaceImport("System.Data"));

        Unit.Namespaces.Add(Namespaces);

    // Declare the type including base type
    CodeTypeDeclaration MyType = new CodeTypeDeclaration("Form1");
        MyType.IsClass = true;
        MyType.TypeAttributes = System.Reflection.TypeAttributes.Public;
        MyType.BaseTypes.Add("System.Windows.Forms.Form");

        Namespaces.Types.Add(MyType);

    // Create the constructor and add code
     CodeConstructor Constructor = new CodeConstructor();

    Constructor.Statements.Add(
      new CodeMethodInvokeExpression(
      new CodeThisReferenceExpression(),"InitializeComponent", new CodeExpression() {}));

        Constructor.Attributes = MemberAttributes.Public ;

    MyType.Members.Add(Constructor);

    // Declare component container
    MyType.Members.Add(new CodeMemberField("System.ComponentModel.IContainer", "components"));



   //  Implement the Dispose method
    CodeMemberMethod DisposeMethod = new CodeMemberMethod();

    DisposeMethod.Name = "Dispose";
    DisposeMethod.Attributes = MemberAttributes.Family;

    DisposeMethod.Parameters.Add(
        new CodeParameterDeclarationExpression(
        typeof(Boolean), "disposing"));

    CodeConditionStatement Statement = new CodeConditionStatement();
    Statement.Condition = new CodeArgumentReferenceExpression("disposing");

    CodeConditionStatement TrueStatement = new CodeConditionStatement();
    TrueStatement.Condition = 
      new CodeBinaryOperatorExpression(
        new CodeArgumentReferenceExpression("components"),
        CodeBinaryOperatorType.IdentityInequality,
        new CodePrimitiveExpression(null));

    TrueStatement.TrueStatements.Add(
      new CodeMethodInvokeExpression(
        new CodeFieldReferenceExpression(null,
            "components"), "Dispose", new CodeExpression() {}));

    Statement.TrueStatements.Add(TrueStatement);

    DisposeMethod.Statements.Add(Statement);

    DisposeMethod.Statements.Add(new CodeMethodInvokeExpression( new CodeBaseReferenceExpression(), "Dispose",  new CodeArgumentReferenceExpression[] 
        {new CodeArgumentReferenceExpression("disposing")}));

   MyType.Members.Add(DisposeMethod);


    // InitializeComponent
   CodeMemberMethod InitializeMethod = new CodeMemberMethod();

   InitializeMethod.Name = "InitializeComponent";
   InitializeMethod.Attributes = MemberAttributes.Private;

   InitializeMethod.CustomAttributes.Add(
     new CodeAttributeDeclaration(
       "System.Diagnostics.DebuggerStepThrough"));

   InitializeMethod.Statements.Add(
     new CodeAssignStatement(
       new CodeFieldReferenceExpression(
         new CodeThisReferenceExpression(), "components"),
           new CodeObjectCreateExpression(
             new CodeTypeReference(
               typeof(System.ComponentModel.Container)),
               new CodeExpression() { })));

   MyType.Members.Add(InitializeMethod);

    // Main entry point
    CodeEntryPointMethod MainMethod = new CodeEntryPointMethod();
    MainMethod.Name = "Main";
    MyType.Members.Add(MainMethod);

    //Add mouse move event
    CodeMemberEvent eventstate = new CodeMemberEvent();
    eventstate.Name = "MouseMove";
    eventstate.Attributes = MemberAttributes.Final | MemberAttributes.Public;
    eventstate.Type = new CodeTypeReference("System.Windows.Forms.MouseEventHandler");
    MyType.Members.Add(eventstate);

    string OutputName = "Some.cs";

    try
    {

        CodeGeneratorOptions options = new CodeGeneratorOptions();
        options.BlankLinesBetweenMembers = true;
        options.ElseOnClosing = false;
        options.BracingStyle = "C";

        // This is what we'll write the generated code to
        IndentedTextWriter writer = new IndentedTextWriter(new StreamWriter(OutputName, false), "  ");
        try
        {
            CodeProvider.GenerateCodeFromCompileUnit(Unit, writer, new CodeGeneratorOptions());
            writer.Close();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
            writer.Close();
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }

    // Create the compiler options
    // Include referenced assemblies
    CompilerParameters Options = new CompilerParameters();
    Options.GenerateExecutable = true;
    Options.OutputAssembly = "TestForm1.exe";
    Options.CompilerOptions = "/target:winexe";
    Options.MainClass = "Test.CreateForm.Form1";

    string[] referenceAssemblies = { "System.dll", "System.Data.dll", "System.Drawing.dll", "System.Windows.Forms.dll", "System.XML.dll" };

    Options.ReferencedAssemblies.AddRange(referenceAssemblies);

    //Build and look for compiler errors
    CompilerResults Result = CodeProvider.CompileAssemblyFromFile(Options, "Some.cs");

    if (Result.Errors.Count > 0) 
    {
        foreach(CompilerError ce in Result.Errors)
        {
            Console.WriteLine(ce.ErrorText);
        }

    }
    else
    {
        Console.WriteLine("compiled successfully");
    }

    Console.WriteLine("press enter to continue");
    Console.ReadLine();
    }

My goal: To create a windows form application (executable) through the use of CodeDom. By this I mean I would like a form (with some code behind the form) and turn it into an executable file (as if I had gone into Visual Studio and clicked "Build" > "Build File"). Admittingly, I found this example online and I have since lightly modified it. I am getting errors while trying to generate this code - errors that I have never seen before. Furthermore, I could not find these errors on Google (odd right?)...

Here is the error I am getting:
Element type System.CodeDom.CodeExpression is not supported.
Parameter name: e

I am getting this error on the following line:

CodeProvider.GenerateCodeFromCompileUnit(Unit, writer, new CodeGeneratorOptions());

Here is my full code:

{

     CodeDomProvider CodeProvider = CodeDomProvider.CreateProvider("CSharp");

         // Create the Unit
     CodeCompileUnit Unit = new CodeCompileUnit();

    // Define a namespace and add Imports statements
    CodeNamespace Namespaces = new CodeNamespace("Test.CreateForm");
        Namespaces.Imports.Add(new CodeNamespaceImport("System"));
        Namespaces.Imports.Add(new CodeNamespaceImport("System.Drawing"));
        Namespaces.Imports.Add(new CodeNamespaceImport("System.Windows.Forms"));
        Namespaces.Imports.Add(new CodeNamespaceImport("System.Xml"));
        Namespaces.Imports.Add(new CodeNamespaceImport("System.Data"));

        Unit.Namespaces.Add(Namespaces);

    // Declare the type including base type
    CodeTypeDeclaration MyType = new CodeTypeDeclaration("Form1");
        MyType.IsClass = true;
        MyType.TypeAttributes = System.Reflection.TypeAttributes.Public;
        MyType.BaseTypes.Add("System.Windows.Forms.Form");

        Namespaces.Types.Add(MyType);

    // Create the constructor and add code
     CodeConstructor Constructor = new CodeConstructor();

    Constructor.Statements.Add(
      new CodeMethodInvokeExpression(
      new CodeThisReferenceExpression(),"InitializeComponent", new CodeExpression() {}));

        Constructor.Attributes = MemberAttributes.Public ;

    MyType.Members.Add(Constructor);

    // Declare component container
    MyType.Members.Add(new CodeMemberField("System.ComponentModel.IContainer", "components"));



   //  Implement the Dispose method
    CodeMemberMethod DisposeMethod = new CodeMemberMethod();

    DisposeMethod.Name = "Dispose";
    DisposeMethod.Attributes = MemberAttributes.Family;

    DisposeMethod.Parameters.Add(
        new CodeParameterDeclarationExpression(
        typeof(Boolean), "disposing"));

    CodeConditionStatement Statement = new CodeConditionStatement();
    Statement.Condition = new CodeArgumentReferenceExpression("disposing");

    CodeConditionStatement TrueStatement = new CodeConditionStatement();
    TrueStatement.Condition = 
      new CodeBinaryOperatorExpression(
        new CodeArgumentReferenceExpression("components"),
        CodeBinaryOperatorType.IdentityInequality,
        new CodePrimitiveExpression(null));

    TrueStatement.TrueStatements.Add(
      new CodeMethodInvokeExpression(
        new CodeFieldReferenceExpression(null,
            "components"), "Dispose", new CodeExpression() {}));

    Statement.TrueStatements.Add(TrueStatement);

    DisposeMethod.Statements.Add(Statement);

    DisposeMethod.Statements.Add(new CodeMethodInvokeExpression( new CodeBaseReferenceExpression(), "Dispose",  new CodeArgumentReferenceExpression[] 
        {new CodeArgumentReferenceExpression("disposing")}));

   MyType.Members.Add(DisposeMethod);


    // InitializeComponent
   CodeMemberMethod InitializeMethod = new CodeMemberMethod();

   InitializeMethod.Name = "InitializeComponent";
   InitializeMethod.Attributes = MemberAttributes.Private;

   InitializeMethod.CustomAttributes.Add(
     new CodeAttributeDeclaration(
       "System.Diagnostics.DebuggerStepThrough"));

   InitializeMethod.Statements.Add(
     new CodeAssignStatement(
       new CodeFieldReferenceExpression(
         new CodeThisReferenceExpression(), "components"),
           new CodeObjectCreateExpression(
             new CodeTypeReference(
               typeof(System.ComponentModel.Container)),
               new CodeExpression() { })));

   MyType.Members.Add(InitializeMethod);

    // Main entry point
    CodeEntryPointMethod MainMethod = new CodeEntryPointMethod();
    MainMethod.Name = "Main";
    MyType.Members.Add(MainMethod);

    //Add mouse move event
    CodeMemberEvent eventstate = new CodeMemberEvent();
    eventstate.Name = "MouseMove";
    eventstate.Attributes = MemberAttributes.Final | MemberAttributes.Public;
    eventstate.Type = new CodeTypeReference("System.Windows.Forms.MouseEventHandler");
    MyType.Members.Add(eventstate);

    string OutputName = "Some.cs";

    try
    {

        CodeGeneratorOptions options = new CodeGeneratorOptions();
        options.BlankLinesBetweenMembers = true;
        options.ElseOnClosing = false;
        options.BracingStyle = "C";

        // This is what we'll write the generated code to
        IndentedTextWriter writer = new IndentedTextWriter(new StreamWriter(OutputName, false), "  ");
        try
        {
            CodeProvider.GenerateCodeFromCompileUnit(Unit, writer, new CodeGeneratorOptions());
            writer.Close();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
            writer.Close();
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }

    // Create the compiler options
    // Include referenced assemblies
    CompilerParameters Options = new CompilerParameters();
    Options.GenerateExecutable = true;
    Options.OutputAssembly = "TestForm1.exe";
    Options.CompilerOptions = "/target:winexe";
    Options.MainClass = "Test.CreateForm.Form1";

    string[] referenceAssemblies = { "System.dll", "System.Data.dll", "System.Drawing.dll", "System.Windows.Forms.dll", "System.XML.dll" };

    Options.ReferencedAssemblies.AddRange(referenceAssemblies);

    //Build and look for compiler errors
    CompilerResults Result = CodeProvider.CompileAssemblyFromFile(Options, "Some.cs");

    if (Result.Errors.Count > 0) 
    {
        foreach(CompilerError ce in Result.Errors)
        {
            Console.WriteLine(ce.ErrorText);
        }

    }
    else
    {
        Console.WriteLine("compiled successfully");
    }

    Console.WriteLine("press enter to continue");
    Console.ReadLine();
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

不爱素颜 2024-11-25 13:51:37

在很多情况下,您都会创建一个空的 CodeExpression,例如在构造函数代码中:

        // Create the constructor and add code
        CodeConstructor Constructor = new CodeConstructor();

        Constructor.Statements.Add(
          new CodeMethodInvokeExpression(
          new CodeThisReferenceExpression(), "InitializeComponent", new CodeExpression() { }));

如果您不想向该方法传递任何参数(上面的代码就是这种情况),则只需不要传递任何内容 (CodeMethodInvokeExpression构造函数接受一个 params[] 数组,因此如果您不传递任何内容,则意味着它接收一个空数组):

        // Create the constructor and add code
        CodeConstructor Constructor = new CodeConstructor();

        Constructor.Statements.Add(
          new CodeMethodInvokeExpression(
            new CodeThisReferenceExpression(),
            "InitializeComponent"));

You have many instances where you create an empty CodeExpression, such as in the constructor code:

        // Create the constructor and add code
        CodeConstructor Constructor = new CodeConstructor();

        Constructor.Statements.Add(
          new CodeMethodInvokeExpression(
          new CodeThisReferenceExpression(), "InitializeComponent", new CodeExpression() { }));

If you don't want to pass any parameters to the method (which is the case in the code above), simply don't pass anything (CodeMethodInvokeExpression constructor takes a params[] array, so if you don't pass anything, it means that it receives an empty array):

        // Create the constructor and add code
        CodeConstructor Constructor = new CodeConstructor();

        Constructor.Statements.Add(
          new CodeMethodInvokeExpression(
            new CodeThisReferenceExpression(),
            "InitializeComponent"));
撧情箌佬 2024-11-25 13:51:37

如果上面的代码没有吐出所需的代码,请确保您关闭了 IndentedTextWriter 例如 writer.Close() 享受..

in case above code is not spitting the required code make sure you are closed the IndentedTextWriter e.g. writer.Close() enjoy..

山色无中 2024-11-25 13:51:37
CodeMemberMethod DisposeMethod = new CodeMemberMethod();
DisposeMethod.Name = "Dispose";
DisposeMethod.ReturnType = new CodeTypeReference(typeof(void));
DisposeMethod.Attributes = MemberAttributes.Override | MemberAttributes.Private;
DisposeMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(bool), "disposing"));
myDesignerClass.Members.Add(DisposeMethod);

CodeConditionStatement cstif2 = new CodeConditionStatement();
CodeExpression dis = new CodeVariableReferenceExpression("disposing");
CodeExpression comp = new CodeVariableReferenceExpression("components");

cstif2.Condition = new CodeBinaryOperatorExpression(dis, CodeBinaryOperatorType.BooleanAnd, new CodeBinaryOperatorExpression(dis, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)));
CodeExpression dispos = new CodeMethodInvokeExpression(comp, "Dispose", new CodeExpression[] { });
cstif2.TrueStatements.Add(dispos);
DisposeMethod.Statements.Add(cstif2);
CodeExpression bdispos = new CodeMethodInvokeExpression(new CodeBaseReferenceExpression(), "Dispose", new CodeExpression[] { });
DisposeMethod.Statements.Add(bdispos);
CodeMemberMethod DisposeMethod = new CodeMemberMethod();
DisposeMethod.Name = "Dispose";
DisposeMethod.ReturnType = new CodeTypeReference(typeof(void));
DisposeMethod.Attributes = MemberAttributes.Override | MemberAttributes.Private;
DisposeMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(bool), "disposing"));
myDesignerClass.Members.Add(DisposeMethod);

CodeConditionStatement cstif2 = new CodeConditionStatement();
CodeExpression dis = new CodeVariableReferenceExpression("disposing");
CodeExpression comp = new CodeVariableReferenceExpression("components");

cstif2.Condition = new CodeBinaryOperatorExpression(dis, CodeBinaryOperatorType.BooleanAnd, new CodeBinaryOperatorExpression(dis, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)));
CodeExpression dispos = new CodeMethodInvokeExpression(comp, "Dispose", new CodeExpression[] { });
cstif2.TrueStatements.Add(dispos);
DisposeMethod.Statements.Add(cstif2);
CodeExpression bdispos = new CodeMethodInvokeExpression(new CodeBaseReferenceExpression(), "Dispose", new CodeExpression[] { });
DisposeMethod.Statements.Add(bdispos);
国际总奸 2024-11-25 13:51:37

CodeExpression 后面的 () 替换为 [],错误就会消失。

Replace () after CodeExpression with [] and error will vanish.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文