Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Fichier .manifest sous Vista

16 réponses
Avatar
Kiriasse
Bonjour,

Dans une application écrite en VB6, j'ajoute dans le répertoire où se trouve
l'EXE de cette application le fichier MonAppli.exe.manifest (c'est un
fichier texte que l'on peut créer avec Notepad).
Cela a pour effet, sous Windows XP, de donner aux boutons de commande de
l'application MonAppli.exe le look XP (les 4 coins des boutons sont
arrondis).
Le contenu de ce fichier MonAppli.exe.manifest est le suivant :

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1"
manifestVersion="1.0">
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Editeur"
processorArchitecture="X86"
version="4.4.0.0"
/>
<description>Mes logiciels </description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
language="*"
processorArchitecture="X86"
version="6.0.0.0"
publicKeyToken="6595b64144ccf1df"
/>
</dependentAssembly>
</dependency>
</assembly>

Un utilisateur de cette appli sous Vista me dit que ça ne marche pas sous ce
nouvel O.S. : les coins des boutons restent des angles droits.
Savez-vous comment on doit procéder pour obtenir le même résultat graphique
sous Vista ?
Suffit-il de prévoir un fichier .manifest ?
Et dans ce cas, quel doit être son contenu ?
Merci d'avance pour votre aide.

6 réponses

1 2
Avatar
Jacques93
Bonjour Kiriasse,
Kiriasse a écrit :
Re-bonjour,
J'ai en fait un nouveau problème.
Comme c'est mon programme qui crée le fichier MonAppli.exe.manifest, à la
fin de la procédure de création, j'ajoute des lignes de code utilisant la
fonction SetFileTime de l'API Windows. Ce code modifie la date de création,
la date de dernière modification et la date du dernier accès. Je donne une
date antérieure à la date de la compilation de l'EXE, par exemple le 1er
janvier 2007 à 0 H.
Quand je lance l'appli depuis Visual Basic, les choses se passent comme je
m'y attends.
Mais, quand j'utilise l'EXE, la date de création devient la suivante :
lundi 1 janvier 1601, 01:14:18
En l'occurrence, cela n'a pas vraiment d'importance puisque la date qui est
prise en compte par MonAppli est la date de la dernière modification qui est
bien devenue le 1er janvier 2007 à 0 H.
Et, de toute façon, l'an 1 du XVIIe siècle est sans conteste antérieure à la
date de compilation de l'EXE.

Mais j'aimerais comprendre d'où sort cette date étrange du lundi 1 janvier
1601, 01:14:18.




L'api SetFileTime attend comme paramètre des données de type FILETIME :

Public Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type

Public Declare Function SetFileTime Lib "kernel32" Alias _
"SetFileTime" (ByVal hFile As Long, _
lpCreationTime As FILETIME, _
lpLastAccessTime As FILETIME, _
lpLastWriteTime As FILETIME) As Long

qui représentent le nombre d'intervalles de 100 nanosecondes écoulés
depuis le premier janvier 1601 12:00 A.M. en temps UTC. Donc pour la
date ça s'explique, ce qui est bizarre c'est l'heure 01:14:18, sauf si
c'est PM. Mais tu doit probablement passer une valeur incorrecte. Plus
de détails ici :

<http://msdn2.microsoft.com/en-us/library/ms724290.aspx>

Ces donnée n'étant pas aisées à manipuler, il existe l'API
'SystemTimeToFileTime' qui convertit une date du format SYSTEMTIME vers
le format FILETIME :

Public Type SYSTEMTIME
wYear As Integer
wMonth As Integer
wDayOfWeek As Integer
wDay As Integer
wHour As Integer
wMinute As Integer
wSecond As Integer
wMilliseconds As Integer
End Type

Public Declare Function SystemTimeToFileTime Lib "kernel32" Alias _
"SystemTimeToFileTime" (lpSystemTime As SYSTEMTIME, _
lpFileTime As FILETIME) As Long

--
Cordialement,

Jacques.
Avatar
Kiriasse
Merci pour cette nouvelle réponse.
Si je peux me permettre, je vous demanderais bien de jeter un oeil sur le
code que j'utilise (je l'ai récupéré pour l'essentiel sur Internet et je n'y
ai pas trouvé d'erreur -- mais je ne suis pas un professionnel de la
programmation).
Vous pouvez le récupérer en cliquant sur :
http://www.kiriasse.fr/doc_tmp/setfiletime.txt

Ce qui m'étonne, c'est que ma procédure marche bien quand on l'utilise
depuis VB alors qu'il produit ce que je vous ai expliqué quand on utilise
l'EXE après compilation.

Merci d'avance.
Jean-Claude alias Kiriasse
Avatar
Kiriasse
Merci pour cette nouvelle réponse.
Si je peux me permettre, je vous demanderais bien de jeter un oeil sur le
code que j'utilise (je l'ai récupéré pour l'essentiel sur Internet et je n'y
ai pas trouvé d'erreur -- mais je ne suis pas un professionnel de la
programmation).
Vous pouvez le récupérer en cliquant sur :
http://www.kiriasse.fr/doc_tmp/setfiletime.txt
ou bien sur
http://www.kiriasse.fr/doc_tmp/setfiletime.zip

Ce qui m'étonne, c'est que ma procédure marche bien quand on l'utilise
depuis VB alors qu'il produit ce que je vous ai expliqué quand on utilise
l'EXE après compilation.

Merci d'avance.
Jean-Claude alias Kiriasse
Avatar
Jacques93
Kiriasse a écrit :
Merci pour cette nouvelle réponse.
Si je peux me permettre, je vous demanderais bien de jeter un oeil sur le
code que j'utilise (je l'ai récupéré pour l'essentiel sur Internet et je n'y
ai pas trouvé d'erreur -- mais je ne suis pas un professionnel de la
programmation).
Vous pouvez le récupérer en cliquant sur :
http://www.kiriasse.fr/doc_tmp/setfiletime.txt
ou bien sur
http://www.kiriasse.fr/doc_tmp/setfiletime.zip

Ce qui m'étonne, c'est que ma procédure marche bien quand on l'utilise
depuis VB alors qu'il produit ce que je vous ai expliqué quand on utilise
l'EXE après compilation.




Je n'ai pas d'explication sur cette différence de comportement entre
l'IDE VB et l'EXE. J'ai bien le même résultat que toi avec l'exe
(année 01).

Le problème semble provenir de la déclaration de l'API SetFileDate :

Public Declare Function SetFileTime Lib "kernel32" _
(ByVal hFile As Long, _
lpCreationTime As Any, _
lpLastAccessTime As Any,_
lpLastWriteTime As Any) As Long

qui normalemennt devrait être :

Public Declare Function SetFileTime Lib "kernel32" _
(ByVal hFile As Long, _
lpCreationTime As FILETIME, _
lpLastAccessTime As FILETIME, _
lpLastWriteTime As FILETIME) As Long

mais cette déclaration ne permet pas de passer 0 en argument, il faut
passer 3 dates valides, et donc récupérer les dates si on ne veut pas
toutes les modifier. C'est possible avec l'API GetFileTime.

Autre remarque, les minutes ne sont pas renseignées, elles restent donc
à 00. Par ailleurs, comme tu modifie les trois dates tu peux appeler la
fonction FileSetDate une seule fois avec :

FileSetDate RepCour & "Rafale.exe.manifest", _
"01/01/2007 " & Right$(Now, 8), _
True, True, True


Voici le code modifié et qui fonctionne correctement dans l'IDE VB et en
EXE :

' ------------------------------------------------------------------------
' ============================== ' MODULE
' Déclarations

Option Explicit

Public Type FILETIME
LowDateTime As Long
HighDateTime As Long
End Type


Public Type SYSTEMTIME
Year As Integer
Month As Integer
DayOfWeek As Integer
Day As Integer
Hour As Integer
Minute As Integer
Second As Integer
Milliseconds As Integer
End Type

Public Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" _
(ByVal lpFileName As String, _
ByVal dwDesiredAccess As Long, _
ByVal dwShareMode As Long, _
ByVal lpSecurityAttributes As Long, _
ByVal dwCreationDisposition As Long, _
ByVal dwFlagsAndAttributes As Long, _
ByVal hTemplateFile As Long) As Long

Public Declare Function SetFileTime Lib "kernel32" _
(ByVal hFile As Long, _
lpCreationTime As FILETIME, _
lpLastAccessTime As FILETIME, _
lpLastWriteTime As FILETIME) As Long

Public Declare Function SystemTimeToFileTime Lib "kernel32" _
(lpSystemTime As SYSTEMTIME, lpFileTime As FILETIME) As Long

Public Declare Function CloseHandle Lib "kernel32" _
(ByVal hObject As Long) As Long

Public Declare Function LocalFileTimeToFileTime Lib "kernel32" _
(lpLocalFileTime As FILETIME, lpFileTime As FILETIME) As Long

Public Declare Function GetFileTime Lib "kernel32" _
(ByVal hFile As Long, _
lpCreationTime As FILETIME, _
lpLastAccessTime As FILETIME, _
lpLastWriteTime As FILETIME) As Long

' ================================================== ' MODULE
Public Function FileSetDate( _
ByVal sFileName As String, _
ByVal dFileDate As Date, _
Optional bSetCreationTime As Boolean = False, _
Optional bSetLastAccessedTime As Boolean = False, _
Optional bSetLastModified As Boolean = False _
) As Boolean

Const GENERIC_WRITE = &H40000000, OPEN_EXISTING = 3
Const FILE_SHARE_READ = &H1, FILE_SHARE_WRITE = &H2

Dim lhwndFile As Long
Dim tSystemTime As SYSTEMTIME
Dim tLocalTime As FILETIME, tFileTime As FILETIME

Dim CreationTime As FILETIME
Dim LastAccessTime As FILETIME
Dim LastWriteTime As FILETIME

tSystemTime.Year = Year(dFileDate)
tSystemTime.Month = Month(dFileDate)
tSystemTime.Day = Day(dFileDate)
tSystemTime.DayOfWeek = Weekday(dFileDate) - 1
tSystemTime.Hour = Hour(dFileDate)
tSystemTime.Minute = Minute(dFileDate)
tSystemTime.Second = Second(dFileDate)
tSystemTime.Milliseconds = 0

' --- Open the file to get the filehandle
lhwndFile = CreateFile(sFileName, GENERIC_WRITE, _
FILE_SHARE_READ Or FILE_SHARE_WRITE, _
ByVal 0&, OPEN_EXISTING, 0, 0)
If lhwndFile Then
' --- File opened
' --- Convert system time to local time
SystemTimeToFileTime tSystemTime, tLocalTime

' --- Convert local time to GMT
LocalFileTimeToFileTime tLocalTime, tFileTime
' ---Change date/time property of the file
FileSetDate = True
If bSetCreationTime Then
GetFileTime lhwndFile, CreationTime, LastAccessTime, LastWriteTime
FileSetDate = FileSetDate And CBool(SetFileTime(lhwndFile, _
tFileTime, _
LastAccessTime, _
LastWriteTime))
End If
If bSetLastAccessedTime Then
GetFileTime lhwndFile, CreationTime, LastAccessTime, LastWriteTime
FileSetDate = FileSetDate And CBool(SetFileTime(lhwndFile, _
CreationTime, _
tFileTime, _
LastWriteTime))
End If
If bSetLastModified Then
GetFileTime lhwndFile, CreationTime, LastAccessTime, LastWriteTime
FileSetDate = FileSetDate And CBool(SetFileTime(lhwndFile, _
CreationTime, _
LastAccessTime, _
tFileTime))
End If

' --- Close the file handle
Call CloseHandle(lhwndFile)
End If
End Function
' --------------------------------------------------------------------------

--
Cordialement,

Jacques.
Avatar
Kiriasse
Merci. Cette fois, effectivement, la procédure fonctionne et mon EXE modifie
bien correctement les 3 dates du fichier manifest.

MAIS je suis déçu car :
- L'utilisateur de mon logiciel m'avait dit qu'en donnant à l'EXE (tel qu'il
était initialement), à l'aide de l'utilitaire que vous m'aviez indiqué, des
dates postérieures à celle de la création du fichier manifest, il obtenait
bien le look Vista.
- Sans modifier les dates de l'EXE avec l'utilitaire, avec le nouvel EXE que
je lui ai envoyé qui change les dates du fichier manifest, il n'obtient pas
le look Vista.

Pourtant, dans les deux cas, les dates du fichier manifest sont antérieures
à celles de l'EXE. Il semblerait donc que, pour obtenir le look Vista, on
doive changer la date de l'EXE et non celle du manifest.
Peut-être me faudra-t-il créer un sous-programme EXE qui modifiera les dates
de MonAppli.exe.
Diable ! Tout cela est bien tracassier...
Je me demande si joindre le fichier manifest au programme d'installation ne
serait pas la meilleure solution.
À moins de mettre ce fichier dans le fichier RES (de ressources). Mais
peut-on récupérer un fichier inclus dans le fichier de ressources sans
recréer ce fichier (ce qui ferait renaître le même problème) ?
Kiriasse
Répondant à

== "Jacques93"
Je n'ai pas d'explication sur cette différence de comportement entre
l'IDE VB et l'EXE. J'ai bien le même résultat que toi avec l'exe
(année 01).

Le problème semble provenir de la déclaration de l'API SetFileDate :

(...)
Avatar
Jacques93
Kiriasse a écrit :
Merci. Cette fois, effectivement, la procédure fonctionne et mon EXE modifie
bien correctement les 3 dates du fichier manifest.

MAIS je suis déçu car :
- L'utilisateur de mon logiciel m'avait dit qu'en donnant à l'EXE (tel qu'il
était initialement), à l'aide de l'utilitaire que vous m'aviez indiqué, des
dates postérieures à celle de la création du fichier manifest, il obtenait
bien le look Vista.
- Sans modifier les dates de l'EXE avec l'utilitaire, avec le nouvel EXE que
je lui ai envoyé qui change les dates du fichier manifest, il n'obtient pas
le look Vista.

Pourtant, dans les deux cas, les dates du fichier manifest sont antérieures
à celles de l'EXE. Il semblerait donc que, pour obtenir le look Vista, on
doive changer la date de l'EXE et non celle du manifest.



Effectivement en regardant le problème lié à l'API SetFileTime, j'ai
perdu de vue le fait que c'est le changement de la date de l'exe qui
force la réinitialisation du cache, et non pas le manifest :-(

Peut-être me faudra-t-il créer un sous-programme EXE qui modifiera les dates
de MonAppli.exe.



c'est une option ...

Diable ! Tout cela est bien tracassier...
Je me demande si joindre le fichier manifest au programme d'installation ne
serait pas la meilleure solution.



Personnellement, je ferais comme ça.

À moins de mettre ce fichier dans le fichier RES (de ressources). Mais
peut-on récupérer un fichier inclus dans le fichier de ressources sans
recréer ce fichier (ce qui ferait renaître le même problème) ?



Là ça risque d'être un peu lourd.

--
Cordialement,

Jacques.
1 2