2012-07-09 70 views
2

我刚刚负责升级内部企业Web应用程序。用户输入一些数据,然后Web应用程序编译一个自定义Winforms EXE(自解压器/安装程序类型的应用程序),然后该网站将其作为下载提供。无法在我的动态编译的c#应用程序中包含清单

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

相关链接:

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

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

下面是从自定义一些代码“存档编译器”类,它实际编译:(我只添加应用程序清单部分)

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); 
    } 
} 

然而,当我编译,我把遇到了此问题:

Errors building D:\Projects\MySolution\WebAppName\App_Data\MyUsername\CustomInstaller.exe error CS2007: Unrecognized option: '/win32manifest:'

我有这个麻烦查找信息,比其他的文章,其状态,这个参数存在且有效。该Web应用程序在Visual Studio 2010中,并运行在框架2.0上。动态编译的应用程序也引用.net 2.0(通过反编译器进行验证)。我不确定EXE被调用来执行编译,还有什么我可以检查来解决这个问题。任何帮助,将不胜感激。

回答

0

经过更多研究,我了解了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,这可以很容易地验证我的清单的内容。

+0

mt.exe是一个Windows SDK工具,它通常在没有安装VS的计算机上可用。 – 2012-07-09 17:29:15

+0

是的,我碰巧在我的机器上安装了SDK,所以我从那里得到了一个EXE的副本,这很方便。那些不需要首先获得SDK的人。将EXE复制到我的项目中效果很好,它在Web服务器上运行并没有问题。 – 2012-07-12 13:24:54

2

可能需要在这行删除/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 
1

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

您可以在CSharpCodeProvider构造函数中指定“CompilerVersion”。我将不得不坚持.NET 2.0,所以我要使用mt.exe方法。