Como inserir um manifesto em um aplicativo do C/C++
É recomendado que o aplicativo c criando /C (ou biblioteca) têm o manifesto inserido no final binário porque esse é o comportamento correto de tempo de execução na maioria dos cenários. Por padrão, Visual Studio tentar digitar o manifesto quando o compila um projeto dos arquivos de origem; consulte Geração de manifesto no Visual Studio para obter mais informações. No entanto se um aplicativo foi criado usando o nmake, algumas alterações ao makefile existente são necessárias. Esta seção mostra como alterar makefiles existentes para inserir automaticamente o manifesto no final binário.
Duas abordagens
Há duas maneiras de inserir o manifesto dentro de um aplicativo ou de uma biblioteca.
Se você não estiver fazendo uma construção incremental você pode digitar diretamente o manifesto usando uma linha de comando semelhante ao seguinte como uma etapa de pós-compilação:
mt.exe –manifest MyApp.exe.manifest -outputresource:MyApp.exe;1
ou
mt.exe –manifest MyLibrary.dll.manifest -outputresource:MyLibrary.dll;2
(EXE 1 para 2, para uma DLL.)
Se você estiver fazendo uma construção incremental, editando diretamente o recurso como mostrado aqui desabilitará a compilação incremental e causará uma recriação completa; como consequência uma abordagem diferente deve ser executada:
Vincular binário para gerar o arquivo de MyApp.exe.manifest.
Converter o manifesto a um arquivo de recursos.
Revincule (incremental) para inserir o recurso de manifesto em binário.
Os exemplos a seguir mostram como alterar makefiles para inserir ambas as técnicas.
Antes Makefiles ()
Considere o script para MyApp.exe, um aplicativo simples de nmake criado a partir de um arquivo:
# build MyApp.exe
!if "$(DEBUG)" == "1"
CPPFLAGS=$(CPPFLAGS) /MDd
LFLAGS=$(LFLAGS) /INCREMENTAL
!else
CPPFLAGS=$(CPPFLAGS) /MD
!endif
MyApp.exe : MyApp.obj
link $** /out:$@ $(LFLAGS)
MyApp.obj : MyApp.cpp
clean :
del MyApp.obj MyApp.exe
Se esse script é executado inalterado com Visual C++, cria com êxito MyApp.exe. Também cria o arquivo de manifesto externo MyApp.exe.manifest, para uso do sistema operacional para carregar os assemblies dependentes em tempo de execução.
O script de nmake para MyLibrary.dll fique muito semelhante a:
# build MyLibrary.dll
!if "$(DEBUG)" == "1"
CPPFLAGS=$(CPPFLAGS) /MDd
LFLAGS=$(LFLAGS) /DLL /INCREMENTAL
!else
CPPFLAGS=$(CPPFLAGS) /MD
LFLAGS=$(LFLAGS) /DLL
!endif
MyLibrary.dll : MyLibrary.obj
link $** /out:$@ $(LFLAGS)
MyLibrary.obj : MyLibrary.cpp
clean :
del MyLibrary.obj MyLibrary.dll
Makefiles (depois)
Para criar com manifestos inseridos você tem que fazer quatro pequenas alterações nos makefiles originais. Para o makefile de MyApp.exe:
# build MyApp.exe
!include makefile.inc
#^^^^^^^^^^^^^^^^^^^^ Change #1. (Add full path if necessary.)
!if "$(DEBUG)" == "1"
CPPFLAGS=$(CPPFLAGS) /MDd
LFLAGS=$(LFLAGS) /INCREMENTAL
!else
CPPFLAGS=$(CPPFLAGS) /MD
!endif
MyApp.exe : MyApp.obj
link $** /out:$@ $(LFLAGS)
$(_VC_MANIFEST_EMBED_EXE)
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Change #2
MyApp.obj : MyApp.cpp
clean :
del MyApp.obj MyApp.exe
$(_VC_MANIFEST_CLEAN)
#^^^^^^^^^^^^^^^^^^^^^^^^ Change #3
!include makefile.targ.inc
#^^^^^^^^^^^^^^^^^^^^^^^^^ Change #4. (Add full path if necessary.)
Para o makefile de MyLibrary.dll:
# build MyLibrary.dll
!include makefile.inc
#^^^^^^^^^^^^^^^^^^^^ Change #1. (Add full path if necessary.)
!if "$(DEBUG)" == "1"
CPPFLAGS=$(CPPFLAGS) /MDd
LFLAGS=$(LFLAGS) /DLL /INCREMENTAL
!else
CPPFLAGS=$(CPPFLAGS) /MD
LFLAGS=$(LFLAGS) /DLL
!endif
MyLibrary.dll : MyLibrary.obj
link $** /out:$@ $(LFLAGS)
$(_VC_MANIFEST_EMBED_DLL)
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Change #2.
MyLibrary.obj : MyLibrary.cpp
clean :
del MyLibrary.obj MyLibrary.dll
$(_VC_MANIFEST_CLEAN)
#^^^^^^^^^^^^^^^^^^^^^^^^ Change #3.
!include makefile.targ.inc
#^^^^^^^^^^^^^^^^^^^^^^^^^ Change #4. (Add full path if necessary.)
Os makefiles incluem agora dois arquivos que tornam os trabalhos atuais, o makefile.inc e o makefile.targ.inc.
Crie makefile.inc e copie o seguinte nele:
# makefile.inc -- Include this file into existing makefile at the very top.
# _VC_MANIFEST_INC specifies whether build is incremental (1 - incremental).
# _VC_MANIFEST_BASENAME specifies name of a temporary resource file.
!if "$(DEBUG)" == "1"
CPPFLAGS=$(CPPFLAGS) /MDd
LFLAGS=$(LFLAGS) /INCREMENTAL
_VC_MANIFEST_INC=1
_VC_MANIFEST_BASENAME=__VC90.Debug
!else
CPPFLAGS=$(CPPFLAGS) /MD
_VC_MANIFEST_INC=0
_VC_MANIFEST_BASENAME=__VC90
!endif
####################################################
# Specifying name of temporary resource file used only in incremental builds:
!if "$(_VC_MANIFEST_INC)" == "1"
_VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res
!else
_VC_MANIFEST_AUTO_RES=
!endif
####################################################
# _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE:
!if "$(_VC_MANIFEST_INC)" == "1"
#MT_SPECIAL_RETURN=1090650113
#MT_SPECIAL_SWITCH=-notify_resource_update
MT_SPECIAL_RETURN=0
MT_SPECIAL_SWITCH=
_VC_MANIFEST_EMBED_EXE= \
if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \
if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \
rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \
link $** /out:$@ $(LFLAGS)
!else
_VC_MANIFEST_EMBED_EXE= \
if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1
!endif
####################################################
# _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily:
!if "$(_VC_MANIFEST_INC)" == "1"
_VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \
$(_VC_MANIFEST_BASENAME).auto.rc \
$(_VC_MANIFEST_BASENAME).auto.manifest
!else
_VC_MANIFEST_CLEAN=
!endif
# End of makefile.inc
####################################################
Agora crie makefile.targ.inc e copie o seguinte nele:
# makefile.targ.inc - include this at the very bottom of the existing makefile
####################################################
# Commands to generate initial empty manifest file and the RC file
# that references it, and for generating the .res file:
$(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc
$(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest
type <<$@
#include <winuser.h>
1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest"
<< KEEP
$(_VC_MANIFEST_BASENAME).auto.manifest :
type <<$@
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
</assembly>
<< KEEP
# end of makefile.targ.inc
Consulte também
Conceitos
Noções básicas sobre geração de manifesto para programas do C/C++