【问题标题】:C# Code compiled .exe doesn't runC# 代码编译的 .exe 不运行
【发布时间】:2016-09-20 16:17:03
【问题描述】:

我正在使用 CSharpCodeProvider 自己编译带有可变参数的 .exe。编译工作正常(不返回错误)并且成功但是在运行时它开始并立即退出而没有任何错误或输出。 当更改“Main”(例如改为私有或重命名)时,编译器输出没有有效的 Main 方法,因此示例代码不应该是原因。

有人对此有答案/解决方案吗?我对这个很迷茫,如果有任何有用的回应,我将不胜感激。 先谢谢了~

*编辑:

编译后的 .exe 输出:http://imgur.com/a/WBvz3

编译器:

using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Resources;
using System.Security.Cryptography;
using System.Text;
using Microsoft.CSharp;
using Packer.Properties;

namespace Packer
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            Console.WriteLine("Sample Compiler");
            Console.WriteLine(".ico-path: ");
            var icon = "E:\\sample.ico"; //Console.ReadLine();
            Console.WriteLine("> " + icon);
            Console.WriteLine("Target-exe: ");
            var target = "E:\\sample.exe"; //Console.ReadLine();
            Console.WriteLine("> " + target);
            var source = Resources.samplesource;
            // Compile with all params
            var success = CompileFromSource(source, target, icon);
            // Determine result
            Console.WriteLine(success ? "Successfully compiled." : "Compiling error.");
            if (success) Process.Start(target);
            Console.ReadLine();
        }

        private static bool CompileFromSource(string source, string output,
string icon = null, string[] resources = null)
        {
            var cParams = new CompilerParameters
            {
                GenerateInMemory = true,
                WarningLevel = 0,
                GenerateExecutable = true,
                OutputAssembly = output
            };
            var options = "/optimize+ /platform:x86 /target:winexe /unsafe";
            if (icon != null)
                options += " /win32icon:\"" + icon + "\"";
            // Set the options.
            cParams.CompilerOptions = options;
            cParams.TreatWarningsAsErrors = false;
            cParams.ReferencedAssemblies.Add("System.dll");
            cParams.ReferencedAssemblies.Add("System.Core.dll");
            cParams.ReferencedAssemblies.Add("System.Data.dll");
            // Check if the user specified any resource files. & Add them
            if (resources != null && resources.Length > 0)
            {
                // Loop through all resource files specified in the Resources[] array.
                foreach (var res in resources)
                {
                    // Add each resource file to the compiled stub.
                    cParams.EmbeddedResources.Add(res);
                }
            }
            // Dictionary variable is used to tell the compiler what we want
            var providerOptions = new Dictionary<string, string> {{"CompilerVersion", "v4.0"}};
            var results = new CSharpCodeProvider(providerOptions).CompileAssemblyFromSource(cParams, source);
            // Check if any errors occured while compiling.
            if (results.Errors.Count <= 0) return true;
            Console.WriteLine("The compiler has encountered {0} errors", results.Errors.Count);
            foreach (CompilerError err in results.Errors)
            {
                Console.WriteLine("{0}\nLine: {1} - Column: {2}\nFile: {3}", err.ErrorText, err.Line, err.Column,
                    err.FileName);
            }
            return false;
        }
    }
}

要编译的代码:

using System;
using System.Text;

namespace CC2Runner
{
    public static class Program
    {
        public static void Main(string[] args)
        {
            try
            {
                Debug.WriteLine("Sample Starting...");
                Console.WriteLine("Sample Starting...");
                ...
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
            Console.ReadLine();
        }
    }
}

【问题讨论】:

  • 你检查过事件日志吗?
  • 不,执行程序(然后立即退出)是否会在事件日志中记录任何内容?
  • 使用ILDasm,并与包含相同代码的“真实”程序进行比较,你能发现任何差异吗?
  • 只需添加 /pdb 选项即可调试生成的程序。
  • "/target:winexe"?那么一个WinForms程序呢?请改用/target:exe

标签: c# codedom csharpcodeprovider


【解决方案1】:

你已经制作了一个 WinForms 程序。

它没有控制台,也不向启动它的控制台输出任何内容。

我怎么知道?这个:

var options = "/optimize+ /platform:x86 /target:winexe /unsafe";
                                        ^^^^^^^^^^^^^^

来自csc

 /target:exe                   Build a console executable (default) (Short
                               form: /t:exe)
 /target:winexe                Build a Windows executable (Short form:
                               /t:winexe)

改用/target:exe,它应该会更好。

【讨论】:

  • 好的,这解释了很多。如果我想在之后调用具有表单的程序集,我是否必须再次考虑构造函数?
  • 好吧,您可能会回到/target:winexe,但这绝不允许(或在相反的情况下,不允许)您使用表单。主要区别在于程序是否以附加的控制台启动。如果需要,请使用/target:exe。如果您不想这样,请使用/target:winexe。不过,无论哪种情况,您都应该在 main 方法中添加适当的 Application.XYZ 方法调用。查看一个普通的 WinForms 程序,找到正确的默认语句。
  • 但是,如果您当前对是否成功编译项目的测试是它是否向控制台输出了一些东西,那么这些都不重要。如果是这种情况,您必须创建一个控制台应用程序,这是通过/target:exe 完成的。
  • 设置/target:exe暂时解决了我的问题。我现在正在整合其他程序集,如果遇到问题,请使用您的建议或发布单独的问题。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多