Question [Function] Récupération des types mime
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
-
- Messages : 6311
- Remerciements reçus 68
[code:1]
################################################################################
#
# Nom : Get-TypeMime
# Récupère, dans la base de registre, les codages des types de fichiers (MIME)
#
# Version : 0.1
# Auteur : Laurent Dardenne
# Date : le 02/06/2008
#
################################################################################
Function Get-TypeMime()
{ #Récupère les formats MIME
Push-Location
cd HKLM:\SOFTWARE\Classes
#On ne prend que les clés portant sur une extension de fichier sauf celles contenant '*' qui
#renvoient sur la même liste
dir \".*\"|Where {!($_.Name -match \"\*\"«»)}|`
#Pour chaque clés on parcourt la liste des propriétés
#Seul nous intéresse les clés ayant la propriété \"Content Type\"
Foreach {get-itemproperty -path $_.PSPath|Foreach {if ($_.\"Content Type\" -ne $null«») {$_}} }|`
#On récupére le couple extension, mimeType dans une hastable (.bmp,image/bmp)
Foreach {$Result=@{}} {$Result.($_.PSChildName)=$_.'Content type'} {$Result}
Pop-Location
}[/code:1]
Usage :
[code:1]
$Mime=Get-TypeMime
Dir |Where-Object { ($_.PSIsContainer -eq 0)} |% { if ($Mime.($_.Extension) -match \"^(.*)/(.*)$\"«»)
{$Current=$_
switch ($matches[1])
{
\"text\" {\"Texte : $Current\"}
\"image\" {\"Image : $Current\"}
\"application\" {\"Exécutable : $Current\"}
\"audio\" {\"Audio : $Current\"}
default {\"Mime inexistant\"}
}
}
}
[/code:1]
Reste un pb, un fichier peut porter une extension qui ne soit pas en phase avec sont contenu. Par exemple un fichier .doc peut être un fichier texte ou un fichier MS-Word. Dans ce cas voir l’analyse du fichier via l’API FindMimeFromData ...<br><br>Message édité par: Laurent Dardenne, à: 24/06/08 21:20
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Arnaud Petitjean
-
- Hors Ligne
- Modérateur
-
Merci pour ton script, nous le mettrons dans la bibliothèque prochainement. En attendant, pourrais-tu stp donner un ou deux exemples d'utilisations et nous dire dans quel cas il peut être utile ?
Cordialement,
Arnaud
MVP PowerShell et créateur de ce magnifique forum
Auteur de 6 livres PowerShell aux éditions ENI
Fondateur de la société Start-Scripting
Besoin d'une formation PowerShell ?
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
-
- Messages : 6311
- Remerciements reçus 68
Arnaud écrit:
Le projet suivant www.codeplex.com/paws utilise une liste de constantes, j'ai préféré une approche dynamique.et nous dire dans quel cas il peut être utile ?
Si on souhaite effectuer un traitement selon le contenu d'un fichier, i.e. comment l'interpréter.
On peut vouloir ne copier que les images d'un répertoire, sans se préoccuper des extensions de fichiers.
Le mime est \"une sorte de typage du contenu\". Mais cela ne fonctionne que pour quelques cas : \"text\",\"image\".
Arnaud écrit:
A l'origine je recherchais un moyen pour déterminer le contenu d'un fichier afin de créer un fichier de ressource :pourrais-tu stp donner un ou deux exemples d'utilisations
[code:1]Get-ChildItem * | Where-Object { ($_.PSIsContainer -eq 0)| ConvertTo-Resource|Create-Resource (join-path $pwd Tst1.resources)[/code:1]
Et ça fonctionne !
Je peux donc automatiser la création de fichiers de ressources avec qq limites, ce sera un outil complémentaire au script de conversion de WinForm.
Le code de création de ressources utilisant les types mime :
[code:1]
process
{
$Current=$_
if ($Current -is [System.IO.FileInfo])
{ write-Debug (\"File extension : {0}\" -F $Current.Extension)
write-Debug (\"Mime : {0}\" -F $global:Mime.($Current.Extension))
#Extrait le champ 'discrete-type' du type Mime correspondant à l'extension du fichier courant
if ($global:Mime.($Current.Extension) -match \"^(.*)/(.*)$\"«»)
{ write-Debug (\"Match extension : {0}\" -F $matches[1])
switch ($matches[1]) {
#RFC : discrete-type := \"text\" / \"image\" / \"audio\" / \"video\" /\"application\" / extension-token
\"image\" { #Lit les données de l'image à partir du fichier
$Image=[System.Drawing.Image]::FromFile($Current.FullName)
$Data=@{
Name=$Current.Name
#L'image doit être dupliquée sinon l'appel à Dispose supprime l'objet
#Ces objets devront dont être supprimés manuellement
Value=$Image.Clone()
ResourceType=(&$sbFindImageFormat $Image.RawFormat.Guid)
}#$Data
$Image.Dispose()
}
\"text\" {...
[/code:1]
Je suis en train de finaliser ces scripts et de rédiger un tutoriel sur la gestion des ressources et des flux ADS.
C'est vrai que ce n'est pas tout à fait un script d'administration
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Arnaud Petitjean
-
- Hors Ligne
- Modérateur
-
Merci pour ces précisions utiles
Je t'avouerais n'avoir rien compris aux fichiers de ressources associés aux Winforms; mais bon je n'ai pas trop cherché...
D'après ce que j'ai vu dans la dernière mouture du convertisseur de Winforms tu fais appelle à un exe pour convertir ce fichiers ? Peut-être devrions nous ouvrir un autre fil de discussion pour en parler ?
Arnaud
MVP PowerShell et créateur de ce magnifique forum
Auteur de 6 livres PowerShell aux éditions ENI
Fondateur de la société Start-Scripting
Besoin d'une formation PowerShell ?
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
-
- Messages : 6311
- Remerciements reçus 68
Je suis d'accord, si tu veux des détails sur les fichier de resources et leurs implémentation sous Convert-Form pas de pb.Peut-être devrions nous ouvrir un autre fil de discussion pour en parler ?
Je te laisse ouvrir le post
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
-
- Messages : 6311
- Remerciements reçus 68
[code:1]
if ($_.\"Content Type\" -ne \"\"«»)
[/code:1]
on doit tester sur la valeur $null :
[code:1]
if ($_.\"Content Type\" -ne $null)
[/code:1]
Sinon la hastable contient des entrées vides...
Arnaud écrit:
Pour info :D'après ce que j'ai vu dans la dernière mouture du convertisseur de Winforms tu fais appelle à un exe pour convertir ce fichiers ?
Pour définir ce qu'est une ressource (msdn.microsoft.com/fr-fr/library/f45fce5x.aspx ) :
«Une ressource est une donnée non exécutable qui est déployée logiquement avec une application. Une ressource peut être affichée dans une application sous la forme d'un message d'erreur ou comme faisant partie de l'interface utilisateur. Les ressources peuvent contenir des données sous plusieurs formes, telles que des chaînes, des images et des objets rendus persistants. Le stockage de vos données dans un fichier de ressources vous permet de changer les données sans avoir à recompiler l'intégralité de votre application. Pour écrire des objets rendus persistants dans un fichier de ressources, les objets doivent être sérialisables.»
Pour le script Convert-Form, il faut regarder la fonction CompileRessources dans le fichier PackageConvert-Form.ps1.
Cette fonction permet à l'aide de l'outil du sdk .net Resgen.exe de compiler un fichier de déclaration de ressources (.resx) en un fichier binaire (.resources).
Les deux sont structurés, le premier est un fichier xml
Le second est un fichier binaire contenant +- une hastable, l'accés à une resource se faisant par un nom.<?xml version=\"1.0\" encoding=\"utf-8\"?>
<root>
<!--
Microsoft ResX Schema
...
<data name=\"button1.Image\" type=\"System.Drawing.Bitmap, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">
...
On peut voir avec un éditeur HEX que le début du fichier binaire contient les clés puis les données.
Donc lors de la conception d'un projet Winform sous Visual Studio, l'ajout d'une image dans un composant crée une entrée dans le fichier de resources (.rsx).
Comme ici on n'utilise pas le code compilé mais le code C# du designer on doit créer ce fichier de resource (binaire) sous PowerShell.
Dans le script principal on recherche les occurences de la classe ComponentResourceManager :
[code:1]
#Contrôle la présence d'un composant de gestion de ressources (images graphique principalement)
if ($IsUsedResources -eq $false){
$crMgr=[regex]::match($Components[$i],\"\s= new System\.ComponentModel\.ComponentResourceManager\(typeof\((.*)\)\);$\"«»)
if ($crMgr.success){
$IsUsedResources = $True
$Components[$i]=AjouteGestionRessources
continue
}
[/code:1]
A partir de là on sait si un fichier WinForm utilise ou non un fichier de resource. Comme il existe un fichier de resource par WinForm on connaît directement le nom du fichier à générer.
Lors de la génération du fichier .ps1 on place en début de script l'appel de la création d'une hastable avec les données du fichier de ressource, voir la function AjouteGestionRessources :
[code:1]
#Gestion du fichier des ressources
`$Reader = new-Object System.Resources.ResourceReader(\"`$RessourcesPath\"«»)
`$Ressources=@{}
`$Reader.GetEnumerator()|% {`$Ressources.(`$_.Name)=`$_.value}
[/code:1]
Reste à insérer les accès aux ressources :
[code:1]
#Traite les ressources images
If ($IsUsedResources)
{ #Todo : factoriser l'expression
$Ligne = $Ligne -replace \"^(.*)= (\(\(System.Drawing.Image\)\(resources.GetObject\(`\"«»)(.*)`\"\)\)\)$\", '$1= [System.Drawing.Image] $Ressources[\"$3\"]'
$Ligne = $Ligne -replace \"^(.*)= (\(\(System.Drawing.Icon\)\(resources.GetObject\(`\"«»)(.*)`\"\)\)\)$\", '$1= [System.Drawing.Icon] $Ressources[\"$3\"]'
}
[/code:1]
Ici $1 et $3 sont des références au groupes de l'expression réguliéres (cf. parenthèses) et non pas à des variables PS.
Donc le code C# suivant
[code:1]
this.button1.Image = ((System.Drawing.Image)(resources.GetObject(\"button1.Image\"«»)));
[/code:1]
devient
[code:1]
$button1.Image = [System.Drawing.Image] $Ressources[\"button1.Image\"]
[/code:1]
Visual Studio caste la ressource en une instance de classe image car toutes les images sont vues, à partir du fichier de ressource, comme des Bitmap.
D'où la méthode Get-ImageFormat
Un fichier de ressource pouvant être utilisé pour la localisation :
[code:1]
#Test-Localisation
#passer une hashtable à convert
$htEnglish=@{Bienvenue=\"Hello\"}
$htGerman=@{Bienvenue=\"Hallo\"}
$htSpanish=@{Bienvenue=\"Hola\"}
$htFrench=@{Bienvenue=\"Salut\"}
$resName=\"Eng\"
$FileName=(join-path $pwd $resName+\".resources\"«»)
$htEnglish|ConvertTo-Resource -FromHashTable|Create-Resource $FileName
$Msg=Read-Resources $FileName
$Msg.\"Bienvenue\" #Affiche Hello
[/code:1]
-$FromHashTable indique que l'on crée une ressource pour chaque éléments des objets de type HashTable.
Dans ce cas l'objet Hashtable ne pourra pas être reconstruit via Read-Resources. Par défaut pour les objets de type HashTable on crée une seule ressource.
On peut utiliser les fichiers satellite mais mon approche moins académique simplifie, je pense, la mise en oeuvre.
Quitte a utiliser une information de culture au lieu d'un nom arbitraire.
C'est ce propose +- la version 2 de PowerShell dans cet exemple .
Voilà, j'ai ajouté ce texte dans la documentation pour la prochaine version de Convert-Form.<br><br>Message édité par: Laurent Dardenne, à: 24/06/08 21:36
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Vous êtes ici :
-
Accueil
-
forum
-
PowerShell
-
Contributions à la communauté
- [Function] Récupération des types mime