【问题标题】:Unable to include a manifest in my dynamically compiled c# app无法在我的动态编译的 C# 应用程序中包含清单
【发布时间】:2012-07-09 15:40:23
【问题描述】:

我刚刚负责升级内部企业 Web 应用程序。用户输入一些数据,然后网络应用程序编译一个自定义的 winforms EXE(自解压器/安装程序类型的应用程序),然后网站将其作为下载提供。

我们最近了解到这个自定义编译的安装程序在 Windows 7 中显示了一个兼容性错误/警告。经过一些研究后,我了解到我需要提供一个应用程序清单来指定与 Windows 7 的兼容性:

相关链接:

这是我对自定义/动态编译代码和应用程​​序清单的第一次体验。

由于此应用程序是动态编译的(从单个代码文件和一些嵌入式资源),我不能只将清单添加到我的项目中。所以我在编译时使用了编译器的“/win32manifest”编译选项来引用manifest文件。

这里是来自自定义“存档编译器”类的一些代码,它实际执行编译:(我只添加了应用程序清单部分)

public void CompileArchive(string archiveFilename, bool run1stItem, string iconFilename)
{
    CodeDomProvider csc = new CSharpCodeProvider();
    CompilerParameters cp = new CompilerParameters();

    cp.GenerateExecutable = true;
    cp.OutputAssembly = archiveFilename;
    cp.CompilerOptions = "/target:winexe";

    // Custom option to run a file after extraction  
    if (run1stItem) {
        cp.CompilerOptions += " /define:RUN_1ST_ITEM";
    }
    if (!string.IsNullOrEmpty(iconFilename)) {
        cp.CompilerOptions += " /win32icon:" + iconFilename;
    }
    cp.ReferencedAssemblies.Add("System.dll");
    cp.ReferencedAssemblies.Add("System.Windows.Forms.dll");

    // Add application manifest to specify operating system compatibility (to fix compatibility warning in Windows 7)
    string AppManifestPath = Path.Combine( System.Web.HttpContext.Current.Server.MapPath( "~/Content/" ), "CustomInstaller.exe.manifest" );
    if ( File.Exists( AppManifestPath ) ) {
        cp.CompilerOptions += string.Format( " /win32manifest: \"{0}\"", AppManifestPath );
    }

    // Add compressed files as resource
    cp.EmbeddedResources.AddRange(filenames.ToArray()); 

    // Compile standalone executable with input files embedded as resource
    CompilerResults cr = csc.CompileAssemblyFromFile(cp, sourceCodeFilePath);

    // yell if compilation error
    if (cr.Errors.Count > 0) {
        string msg = "Errors building " + cr.PathToAssembly;
        foreach (CompilerError ce in cr.Errors) { msg += Environment.NewLine + ce.ToString(); }
        throw new ApplicationException(msg);
    }
}

但是,当我编译时,我一直遇到这个错误:

错误构建 D:\Projects\MySolution\WebAppName\App_Data\MyUsername\CustomInstaller.exe 错误 CS2007:无法识别的选项:'/win32manifest:'

除了声明此参数存在且有效的文章外,我无法找到有关此的信息。 Web 应用程序位于 Visual Studio 2010 中,并在框架 2.0 上运行。动态编译的应用程序也引用了 .net 2.0(使用反编译器验证)。我不确定调用什么 EXE 来执行编译,或者我可以检查什么来解决这个问题。任何帮助将不胜感激。

【问题讨论】:

    标签: c# dynamic compiler-construction compiler-errors manifest


    【解决方案1】:

    可能需要删除此行中/win32manifest:\"{0}\" 之间的空格cp.CompilerOptions += string.Format( " /win32manifest: \"{0}\"", AppManifestPath );

    没有空间它可以正常工作,当我添加空间时,就像在你的代码中一样,我有错误:

    Errors building C:\Projects\Services\Services.WebUI\Binaries\install\temp\codedom.exe
    error CS2005: Missing file specification for '/win32manifest:' option
    warning CS2008: No source files specified
    

    【讨论】:

      【解决方案2】:

      /win32manifest 开关的 MSDN 文档页面最早适用于 Visual Studio 2008。所以也许它是在 .NET v3.5 中添加的。

      您可以在 CSharpCodeProvider 构造函数中指定“CompilerVersion”。

      我必须坚持使用 .NET 2.0,所以我将使用 mt.exe 方法。

      【讨论】:

        【解决方案3】:

        经过更多研究,我了解了mt.exe,这是一个用于添加应用程序清单的简单命令行实用程序。我将exe的副本放入我的Web项目中,然后在应用程序编译后添加代码以调用此过程:

        //Add an application manifest using mt.exe
        System.Diagnostics.Process process = new System.Diagnostics.Process();
        System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
        startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
        startInfo.FileName = Path.Combine( System.Web.HttpContext.Current.Server.MapPath( "~/Content/" ), "mt.exe" );
        string AppManifestPath = Path.Combine( System.Web.HttpContext.Current.Server.MapPath( "~/Content/" ), "CustomInstaller.exe.manifest" );
        startInfo.Arguments = string.Format( "-nologo -manifest \"{0}\" -outputresource:\"{1};#1\"", AppManifestPath, cp.OutputAssembly );
        process.StartInfo = startInfo;
        process.Start();
        process.WaitForExit( 10000 ); //wait until finished (up to 10 sec)
        

        这成功地将我的清单快速轻松地添加到编译的 EXE 中。我还发现了这个Manifest Viewer,它可以很容易地验证我的清单内容。

        【讨论】:

        • mt.exe 是 Windows SDK 工具,在没有安装 VS 的机器上通常不可用。
        • 是的,我碰巧在我的机器上安装了 SDK,所以我从那里得到了一个 EXE 的副本,这很方便。那些不需要的人必须先获得 SDK。仅将 EXE 复制到我的项目中工作正常,它在 Web 服务器上运行没有问题。
        猜你喜欢
        • 1970-01-01
        • 2017-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-19
        相关资源
        最近更新 更多