2012-07-09 68 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方法。