2

Мне просто поручили обновить внутреннее веб-приложение предприятия. Пользователь вводит некоторые данные, а затем веб-приложение компилирует пользовательский winforms EXE (тип самораспаковывающегося/установочного приложения), а затем веб-сайт обслуживает его как загрузку.Невозможно включить манифест в мое динамически скомпилированное приложение C#

Недавно мы узнали, этот обычай скомпилированные установки отображает ошибку совместимости/предупреждение в Windows 7. После некоторых исследований я узнал, что мне нужно будет предоставить манифест приложения, который определяет совместимость с Windows 7:

Ссылки по теме:

Это мой первый опыт использования пользовательского/динамически скомпилированного кода и проявлений приложений.

Поскольку это приложение скомпилировано «на лету» (из одного файла кода и некоторых встроенных ресурсов), я не могу просто добавить манифест в свой проект. Поэтому я использовал параметр компилятора «/ win32manifest» для ссылки на файл манифеста при компиляции.

Вот немного кода от обычая «Архив Compiler» класс, который на самом деле делает компиляцию: (я только добавил часть манифеста приложения)

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:'

У меня проблемы при поиске информации по этому вопросу, кроме статей, которые утверждают, что этот параметр существует и действует. Веб-приложение находится в visual studio 2010 и работает на платформе 2.0. Динамически скомпилированное приложение ссылается на .net 2.0 (проверено с помощью декомпилятора). Я не уверен, что EXE вызывается для выполнения компиляции или что еще я могу проверить, чтобы устранить эту проблему. Любая помощь будет оценена по достоинству.

ответ

0

После дополнительных исследований я узнал о mt.exe, который представляет собой простую утилиту командной строки для добавления манифеста приложений. Я положил копию еха в мой вебе-проект, а затем добавил код для вызова этого процесса после того, как приложение было составлено:

//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. –

+0

true, мне довелось установить SDK на моей машине, поэтому я получил оттуда копию EXE, что было удобно. Те, кому это не нужно, сначала должны получить SDK. Копирование только EXE в мой проект работало нормально, он работал на веб-сервере без проблем. –

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.

Вы можете указать «CompilerVersion» в конструкторе CSharpCodeProvider.

Мне нужно будет придерживаться .NET 2.0, поэтому я собираюсь использовать подход mt.exe.

Смежные вопросы