2

私は、社内のエンタープライズWebアプリケーションをアップグレードするという任務を負いました。ユーザーがデータを入力すると、Webアプリがカスタムのwinforms EXE(自己解凍型/インストーラー型のアプリ)をコンパイルし、Webサイトがそれをダウンロードとして提供します。

最近、このカスタムコンパイルされたインストーラーがWindows 7で互換性エラー/警告を表示することを知りました。いくつかの調査の結果、Windows7との互換性を指定するアプリケーションマニフェストを提供する必要があることがわかりました。

関連リンク:

これは、カスタム/動的にコンパイルされたコードとアプリケーションマニフェストを使った初めての経験です。

このアプリは(単一のコードファイルといくつかの埋め込みリソースから)オンザフライでコンパイルされるため、プロジェクトにマニフェストを追加することはできません。そこで、コンパイラの「/ win32manifest」コンパイラオプションを使用して、コンパイル時にマニフェストファイルを参照しました。

これは、実際にコンパイルを行うカスタムの「ArchiveCompiler」クラスのコードです:(アプリケーションマニフェストの部分のみを追加しました)

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アプリはVisualStudio2010にあり、フレームワーク2.0で実行されます。動的にコンパイルされたアプリは、.net 2.0も参照します(逆コンパイラーで検証されます)。コンパイルを実行するためにどのEXEが呼び出されるのか、またはこれをトラブルシューティングするために他に何を確認できるのかわかりません。どんな助けでもいただければ幸いです。

4

3 に答える 3

3

/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
于 2013-07-04T12:37:28.437 に答える
1

/ win32manifestスイッチのMSDNドキュメントページは、最も古いVisualStudio2008用に存在します。したがって、おそらく.NETv3.5で追加されました。

CSharpCodeProviderコンストラクターで「CompilerVersion」を指定できます。

.NET 2.0を使用する必要があるため、mt.exeアプローチを使用します。

于 2014-01-07T07:22:32.703 に答える
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にマニフェストがすばやく簡単に追加されます。また、このマニフェストビューアを見つけたので、マニフェストの内容を簡単に確認できました。

于 2012-07-09T16:41:15.603 に答える