Affichage des articles dont le libellé est Windows. Afficher tous les articles
Affichage des articles dont le libellé est Windows. Afficher tous les articles

lundi 10 août 2020

Alternate Data Stream

Introduction.

Alternate Data Stream (ADS) est un flux de données additionnels lié à un fichier. Habituellement nous utilisons le flux principale pour lire ou écrire un fichier. Avec l'ADS nous pouvons créer des flux de données alternatifs distincts au sein d'un même fichier.

Prenons par exemple, le fichier "test.txt". Ce fichier peut contenir plusieurs textes distincts :
[Test.txt] "Je suis dans le flux principale par défaut."
[Test.txt:Flux1] "Je suis dans le flux 'Flux1'."
[Test.txt:Flux2] "Je suis dans le flux 'Flux2'."

Un peu de pratique pour comprendre tout ça ne fera pas de mal :

  • Lancez la commande "Notepad C:\test.txt", et entrez le texte "Je suis dans le flux principale par défaut.". Si vous ouvrez le fichier depuis l'explorateur vous verrez le texte que vous avez entré.
  • Lancez la commande "Notepad C:\test.txt:Flux1", et entrez le texte "Je suis dans le flux 'Flux1'". Si vous ouvrez le fichier depuis l'explorateur vous ne verrez pas le texte que vous avez entré, mais celui du du flux par défaut. Pour voir le texte du 'Flux1' vous devrez taper de nouveau la commande "Notepad C:\test.txt:Flux1".
  • Lancez la commande "Notepad C:\test.txt:Flux2", et entrez le texte "Je suis dans le flux 'Flux2'". La encore si vous ouvrez le fichier depuis l'explorateur vous ne verrez pas le texte que vous avez entré, mais celui du flux par défaut. Les textes que vous avez tapé dans le Flux1 et dans le Flux2 sont donc "cachés".

Caché ? Peut-être pas tant que ça :

  • Sous DOS, lancez la commande "Dir". Seul le fichier "test.txt" apparait.
  • Sous DOS, lancez la commande "Dir /r". Les flux "teste.txt:Flux1" et "teste.txt:Flux2" liés au fichier "test.txt" apparaissent.

A noter :

  • Les flux alternatifs ne sont possible que sur des partitions formatées en NTFS.
  • La taille des flux ne sont pas comptabilisés dans la taille totale du fichier par défaut. Un fichier de 3Ko dans l'explorateur peut très bien contenir un flux de 10Mo.

Écrire dans un flux alternatif avec Powershell 2.0.


 
#Initialisation.
$fichier = "C:\test.txt"
$flux    = "Flux1"
$cmd     = "cmd.exe"
$Txt     = "Je suis dans le flux 'Flux1'"

#Writing stream.
$arg1 = "/C ""echo $($txt) > $($fichier):$($flux)"""
start-process -filepath $cmd -ArgumentList $arg1

Lire un flux alternatif avec Powershell 2.0.


 
#Initialisation.
$fichier = "C:\test.txt"
$flux    = "Flux1"
$cmd     = "cmd.exe"

#Reading stream.
$arg2 = "/C ""more < $($fichier):$($flux)"""
$info = New-Object System.Diagnostics.ProcessStartInfo
$info.FileName = $cmd
$info.RedirectStandardOutput = $true
$info.UseShellExecute = $false
$info.Arguments = $arg2
$prcs = New-Object System.Diagnostics.Process
$prcs.StartInfo = $info
$null = $prcs.Start()
Sleep -s 1
$stdout = $prcs.StandardOutput.ReadToEnd()
Write-Host $stdout

mercredi 28 novembre 2012

Ouvrir une fenêtre avec PowerShell.

A l'époque où je faisais un peu de C, coder une fenêtre était une vraie galère. En PowerShell en 4 lignes c'est réglé XD.

 
#Ouvre une fenêtre simple.
[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$form = New-Object Windows.Forms.Form
$form.text = "Fenêtre vide"                     #Titre de la fenêtre.
$form.Size = New-Object Drawing.Point 200,200   #Taille de la fenêtre.
$form.ShowDialog()                              #Affiche le tout.

#Fin.

Dans ce premier exemple j'ai mis le minimum pour monter à quel point c'est simple. Mais on ne va pas s'arrêter là. Dans l'exemple suivant je vais prendre en compte toutes les options que j'ai utilisées dernièrement.

 
#Fenêtre et options.
[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$form = New-Object Windows.Forms.Form
$form.Size = New-Object Drawing.Point 200,200
$form.text = "Fenêtre avec options" #Titre de la fenêtre.
$form.ControlBox = 1                #Affiche les contrôles (haut/droite).
$form.MaximizeBox = 1               #Active le contrôle Agrandir (haut/droite).
$form.MinimizeBox = 1               #Active le contrôle Réduire (haut/droite).
$form.ShowIcon = 1                  #Affiche l'icone (haut/gauche).
$form.ShowInTaskbar = 1             #Affiche la fenêtre dans la bar des tâches.
$form.TopMost = 0                   #Affiche la fenêtre toujours au premier plan.
$form.backcolor = "white"           #Couleur du fond de la fenêtre.
$form.FormBorderStyle = "Sizable"   #Style du bord de la fenêtre*.

#Charge une image de fond dans la fenêtre
$form.BackgroundImage = [system.drawing.image]::FromFile("C:\fond.jpg")
$form.BackgroundImageLayout = 0         #Mode d'affichage de l'image**.

#Charge une icone personalisée (en haut à gauche).
$form.Icon = [system.drawing.icon]::ExtractAssociatedIcon("C:\icon.ico")

#Configurer la touche ESC pour fermer la fenêtre.
$form.KeyPreview = $True
$form.Add_KeyDown({if ($_.KeyCode -eq "Escape") {$form.Close()}})

#Affiche le tout.
$form.ShowDialog()

#Fin.
     *FormBorderStyle : None, FixedSingle, Fixed3D, FixedDialog, Sizable, FixedToolWindow, SizableToolWindow.
     **BackgroundImageLayout : 0 = en haut a gauche, 1 = répétable, 2 = centré, 3 = étiré, 4 = étiré (rapport fixe).


Astuce : L'option "TopMost" n'est active que pour une seul fenêtre à la fois. Si vous l'utilisez sur plusieurs fenêtres, seul la première sera prise en compte. Cette option se comporte en faite comme un jeton. Il faut d'abord libérer le jeton avant de pouvoir le réutiliser. L'astuce est donc de remettre l'option "TopMost" de la fenêtre parent à 0 avant d'appeler la fenêtre fille avec l'option "TopMost" à 1. A la fermeture de la fenêtre fille, il faut réattribuer le jeton (TopMost = 1) à la fenêtre parent.

Il est possible de créer des fenêtres transparentes en PowerShell. Pour cela, il existe 2 options. La première option "Opacity" permet de rendre toute la fenêtre et ses contrôles translucides.

 
#Ouvre une fenêtre avec l'option "Opacity".
[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$form = New-Object Windows.Forms.Form
$form.Size = New-Object System.Drawing.Size(300,220)
$form.text = "Opacity"  
$form.BackColor = "White"
$form.FormBorderStyle = "None"

#Active l'option Opacity.
#1 = opaque, 0 = totalement transparent.
$Form.Opacity = 0.8

#Bouton Close.
$bouton1 = New-Object Windows.Forms.Button
$bouton1.Location = New-Object Drawing.Point 100,85
$bouton1.Size = New-Object System.Drawing.Size(100,50)
$bouton1.text = "Close"
$bouton1.add_click({ $form.Close() })

#Attache les contrôles à la fenêtre.
$form.controls.add($bouton1)

#Affiche le tout.
$form.ShowDialog()

#Fin.

La seconde option "TransparencyKey" permet de définir une couleur qui sera totalement transparente. Les autres couleurs de la fenêtre resteront visibles.

 
#Ouvre une fenêtre avec l'option TransparencyKey.
[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$form = New-Object Windows.Forms.Form
$form.Size = New-Object System.Drawing.Size(300,220)
$form.text = "TransparencyKey"
$form.BackColor = "White"
$form.FormBorderStyle = "None"

#Active l'option TransparencyKey.
$form.BackColor = "Magenta"
$form.TransparencyKey = "Magenta"

#Bouton Close.
$bouton1 = New-Object Windows.Forms.Button
$bouton1.Location = New-Object Drawing.Point 100,85
$bouton1.Size = New-Object System.Drawing.Size(100,50)
$bouton1.text = "Close"
$bouton1.BackColor = "White"
$bouton1.add_click({ $form.Close() })

#Attache les contrôles à la fenêtre.
$form.controls.add($bouton1)

#Affiche le tout.
$form.ShowDialog()

#Fin.

L'option "Opacity" et "TransparencyKey" peuvent être utilisées ensemble.

L'option "StartPosition" permet de définir la position initiale de la fenêtre.

 
#Positionner une fenêtre simple.
[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$form = New-Object Windows.Forms.Form
$form.text = "Fenêtre vide"                     #Titre de la fenêtre.
$form.Size = New-Object Drawing.Point 200,200   #Taille de la fenêtre.
$form.StartPosition = "CenterParent"            #Position de la fenêtre*.
$form.ShowDialog()                              #Affiche le tout.

#Fin.
     *StartPosition : Manual, CenterScreen, WindowsDefaultLocation, WindowsDefaultBounds, CenterParent.

Pour définir la position de le fenêtre plus finement, il faut utiliser l'option "Location" conjointement avec "StartPosition".

 
$x = 200
$y = 200

#Ouvre une fenêtre simple.
[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$form = New-Object Windows.Forms.Form
$form.text = "Fenêtre vide"                      #Titre de la fenêtre.
$form.Size = New-Object Drawing.Point 200,200    #Taille de la fenêtre.
$formA.StartPosition = "Manual"                  #Position de la fenêtre.
$formA.Location = New-Object Drawing.Point $x,$y #Position de la fenêtre.
$form.ShowDialog()                               #Affiche le tout.

#Fin.

Pour afficher la fenêtre dans l'écran secondaire, nous allons récupérer l'offset de l’écran secondaire à partir de [System.Windows.Forms.Screen]::AllScreens.

 
#Récupére l'offset de l'écran secondaire.
$infos = [System.Windows.Forms.Screen]::AllScreens
foreach($info in $infos)
 {
   if ($info.Primary -eq $false)
     {
       $OffSetX = [int]($info.WorkingArea.Left)
       $OffSetY = [int]($info.WorkingArea.Top)
     }
 }

#Position de la fenêtre dans l'écran secondaire.
$x = $OffSetX + 200
$y = $OffSetY + 200

#Ouvre une fenêtre simple.
[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$form = New-Object Windows.Forms.Form
$form.text = "Fenêtre vide"                      #Titre de la fenêtre.
$form.Size = New-Object Drawing.Point 200,200    #Taille de la fenêtre.
$form.StartPosition = "Manual"                   #Position de la fenêtre.
$form.Location = New-Object Drawing.Point $x,$y  #Position de la fenêtre.
$form.ShowDialog()                               #Affiche le tout.

#Fin.