Archives mensuelles : janvier 2015

Personnaliser l’image d’arrière-plan du Bureau

Voici comment personnaliser l’arrière-plan du bureau avec Powershell, sans avoir ni  à rebooter ni à se relogger.

Nous allons nous servir d’une fonction qui se trouve dans User32.Dll et qui s’appelle SystemParametersInfo et la déclarer dans un namespace qu’on appellera Params  :

Ensuite nous définissons quelques constantes:

L’opération est un changement de l’image en arrière plan du bureau:

Les paramètres sont un changement du fichier INI qui déclare l’image à placer ainsi que l’envoi d’un événement Windows qui alertera Explorer du changement. Explorer gère l’image d’arrière plan.

On combine ces deux valeur avec un bit OR pour créer un bitmask.

Définissons maintenant l’image qu’on veut charger dans une variable:

Finalement on appelle la fonction SystemParamInfo sans oublier le namespace [Params]:

Voici le script en entier:

Pour plus d’info voir ce lien vers MSDN.

Partager ce contenu

Images dans un document Word

Les images dans cet article sont des bitmaps (raster image) et non les graphes vectoriels ou autres Smartgraphs.

Il y a deux façon de définir une image dans Word: les images alignées au texte et les images flottante. En fonction du cas, ces images ne sont pas stockées de la même façon dans le document. Dans le premier cas les images sont stockeés dans l’objet InlineShapes, dans le second elles sont stockées dans Shapes (shapes veut dire formes).

De plus Shapes et InlineShapes n’ont pas la même définition d’une image.

Dans l’exemple qui suit, nous allons vérifier si des images sont stockées dans un document Word.

Démarrons Word et ouvrons un document Word existant:

Comme mentionné, les deux variables membres de $doc qui nous intéressent sont $doc.Shapes et $doc.InlineShapes (images flottantes et images alignées).

Nous pourrions utiliser la variable membre de ces deux objets appelé Count, et savoir si des formes sont stockées. Si Count est plus grand que 1, nous avons des formes, mais nous ne savons pas s’il s’agît d’images.

Nous devons alors itérer à travers les formes stockées et vérifier leur type.

Pour les images alignées le type à trouver sera [Microsoft.Office.Interop.Word.WdInlineShapeType]::wdInlineShapePicture.

Pour les images flottantes le type à trouver sera [Microsoft.Office.Core.MsoShapeType]::msoPicture.

 

 

Pour trouver d’autres types de formes, il suffit de regarder les autres valeurs des enumerateurs Microsoft.Office.Interop.Word.WdInlineShapeType et Microsoft.Office.Core.MsoShapeType. La technique est la même.

Partager ce contenu

Présence d’un paramètre

Voici comment vérifier la présence d’un paramètre pour une fonction, ou un script.

Généralement on décrit une fonction de la façon suivante:

Dans le cas de la fonction MaFonction il peut être utile de vérifier si le paramètre $MyBool (My Bool, pas ma boule! ) est présent ou non.

Pour ceci il faut s’appuyer sur la variable automatique $PSBoundParameters dont la méthode ContainsKey retourne un booléen.

Une variable automatique, est une variable créée et gérée par Powershell, il en existe de toutes sortes et permettent par exemple de connaitre par exemple la disposition du stack d’appel des fonctions, ou la ligne du script en cours d’exécution, ou encore le résultat de la dernière commande.

Voici un exémple:

Partager ce contenu

Taille d’un répertoire revisité

 

Lorsque j’ai répondu à une question sur Stack Overflow concernant la récupération de la taille d’un répertoire, j’ai réalisé qu’en plus de la méthode classique qui consiste à calculer la taille du répertoire en fonction de la taille des fichiers qu’il contient (et dont j’avais écrit à ce propos ici), et bien, il y a une autre méthode bien plus rapide à coder, en utilisant un objet de type: Scripting.FileSystemObject.

Avec cet objet nous pouvons appeler la méthode GetFolder ce qui nous rend un objet COM qui contient la méthode Size. Cette méthode nous donne la taille du répertoire voulu.

Du coup j’ai écrit une fonction qui permet de récupérer les répertoires dont la taille est au moins celle demandée (en GB dans le code ci-dessous).

 

Pour l’exécuter il suffit de l’appeler ainsi, par exemple:

Partager ce contenu

Remplacer des caractères avec Regex

Imaginons la chaîne de caractères suivante:

Maintenant utilisons l’opérateur -replace pour remplacer les caractères « ef » avec les caractères « ** ».

Ceci nous donne le résultat suivant: « abc** d ** e ** 123 ». Toutes les instances de « ef » sont remplacées.

Or si nous ne voulions pas remplacer toutes les instances de « ef » mais que la première, nous pouvons le faire ainsi:

Cette commande transforme la chaîne ‘ef’ en un objet regex, et appelle la méthode Replace de la classe. Cette méthode prend trois arguments:

  1. la chaîne input à evaluer
  2. la chaîne utilisée pour remplacer les occurrences trouvées
  3. le nombre d’occurrences à remplacer

Cette commande nous donne le résultat suivant: « abc** d ef e ef 123 »

Maintenant essayons de ne remplacer que la dernière occurrence de ‘ef’ dans la chaîne.

Pour ceci nous allons utiliser une expression régulière un peu plus compliquée:

 Cette expression ‘ef(?!.*ef)’ veut dire ceci: remplacer la chaîne ‘ef’ dont les caractères suivants ne contiennent pas à nouveau la chaîne ‘ef’, donc la dernière: (?!.*ef)

Et le résultat est : « abcef d ef e ** 123 »

Partager ce contenu

Les performances d’un tri d’array

Le tri d’array permet de réordonner les éléments d’un array en fonction de la valeur d’un élément. On trie en ordre croissant ou décroissant ceci pour rendre plus lisible ces données.

Lorsque un array contient des centaines de milliers d’éléments il est important de comprendre les différentes techniques de triage ainsi on peut optimiser les performances.

Pour les besoins de cet article, créons un array avec 2500 éléments. Pour cela nous créons un object de type PSCustomObject avec un attribut et nous répétons l’opération 2500 fois pour créer l’array:

Maintenant effectuons différents triages en mesurant les performances.

Commençons en utilisant la cmdlet Sort-Object:

Le temps mesuré en secondes est de: 0.1217965

Maintenant au lieu d’utiliser la cmdlet Sort-Object, utilisons la méthode Reverse() de la classe [Array]:

 

Le temps mesuré en secondes est de: 0.0002594

Une énorme différence!

Créons maintenant une collection de type System.Collections.ArrayList. Les collections contrairement aux arrays classiques ont une particularité, elles sont modifiables, alors que les array de type System.array ne le sont pas, on les appelle immuables. Ceci veut dire que pour ajouter un élément à un array on doit en créer un nouveau objet. Alors que pour une collection, on peut allégrement ajouter et enlever des éléments en utilisant toujours le même objet.

Effectuons maintenant un tri et mesurons le temps:

Le temps mesuré en secondes est de: 0.0002459

Encore une amélioration par rapport à [array]::Reverse(), mais pas si significative que ça.

Nous n’avons pas mesuré le temps passé à créer les collections et array. Et la création d’une collection sera toujours plus rapide. Si nous avons des centaines de milliers d’éléments à traiter une collection sera plus rapide qu’un array.

Partager ce contenu