私は、社内のエンタープライズWebアプリケーションをアップグレードするという任務を負いました。ユーザーがデータを入力すると、Webアプリがカスタムのwinforms EXE(自己解凍型/インストーラー型のアプリ)をコンパイルし、Webサイトがそれをダウンロードとして提供します。
最近、このカスタムコンパイルされたインストーラーがWindows 7で互換性エラー/警告を表示することを知りました。いくつかの調査の結果、Windows7との互換性を指定するアプリケーションマニフェストを提供する必要があることがわかりました。
関連リンク:
- Windows7の互換性エラーについて詳しく説明しているStackoverflowの記事
- アプリケーションマニフェストで必要なものを詳しく説明しているMSDNの記事
- コンパイラオプションの設定方法を示すサンプルコード
これは、カスタム/動的にコンパイルされたコードとアプリケーションマニフェストを使った初めての経験です。
このアプリは(単一のコードファイルといくつかの埋め込みリソースから)オンザフライでコンパイルされるため、プロジェクトにマニフェストを追加することはできません。そこで、コンパイラの「/ 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が呼び出されるのか、またはこれをトラブルシューティングするために他に何を確認できるのかわかりません。どんな助けでもいただければ幸いです。