ค้นหาเว็บไซต์

วันศุกร์แสนสนุก: เก็บนม


ดังที่กล่าวไปแล้ว อาจมีสถานการณ์ที่คุณยังคงต้องการใช้ PowerShell แม้ว่าประสบการณ์จะน้อยกว่าความเหมาะสมก็ตาม วันนี้เรามาสนุกกัน สำหรับไคลเอ็นต์ Windows หลายเวอร์ชัน มียูทิลิตี้เล็กๆ ที่เรียกว่า Sticky Notes

นี่คือ Post-It Notes เวอร์ชันอิเล็กทรอนิกส์ จะดีกว่าไหมหากสามารถใช้ PowerShell เพื่อใช้ประโยชน์จากยูทิลิตี้นี้ได้ น่าเศร้าที่แอปพลิเคชันนี้เขียนขึ้นในลักษณะที่ไม่มีการเปิดเผยสิ่งใดที่สามารถทำให้เป็นอัตโนมัติได้ ไม่ว่าจะผ่านทาง COM หรือ .NET ดังนั้นเราจึงเหลือมาตรการที่เข้มงวดในการส่งคีย์ไปยังแอปพลิเคชัน

เช่นเดียวกับในสมัยของ VBScript การส่งคีย์ถือเป็นเรื่องเสี่ยง เนื่องจากคุณไม่สามารถรับประกันได้เสมอไปว่าแอปพลิเคชันที่เป็นปัญหาจะมีความสำคัญ แต่มาลองกัน ก่อนอื่น เราต้องเริ่มโปรแกรมง่ายๆ ด้วยการเรียกใช้คำสั่ง stikynot

ในการส่งคีย์ ฉันจะใช้ .NET Framework เพื่อความปลอดภัย ฉันจะเพิ่มชุดประกอบที่จำเป็นไว้เผื่อไว้ ไม่สำคัญว่าจะโหลดไปแล้วหรือไม่

[void] [System.Reflection.Assembly]::LoadWithPartialName("'Microsoft.VisualBasic")
[void] [System.Reflection.Assembly]::LoadWithPartialName("'System.Windows.Forms")

ตอนนี้เพื่อเปิดใช้งานหน้าต่าง คุณสามารถทำได้โดยใช้ชื่อหน้าต่าง

PS D:\temp> get-process stikynot | select mainwindowtitle

MainWindowTitle
---------------
Sticky Notes

หรือรหัสกระบวนการ ฉันจะใช้ชื่อเรื่อง

[Microsoft.VisualBasic.Interaction]::AppActivate("Sticky Notes")

ขณะที่หน้าต่างมีโฟกัส ฉันสามารถส่งกุญแจไปที่หน้าต่างได้

[System.Windows.Forms.SendKeys]::SendWait("Get milk")

และนั่นคือทั้งหมดที่มีให้! Sticky Notes มีแป้นพิมพ์ลัดจำนวนหนึ่งที่คุณสามารถส่งได้โดยใช้เทคนิคนี้ ฉันพบหน้าเว็บที่http://www.door2windows.com/list-of-all-keyboard-shortcuts-for-sticky-notes-in-windows-7/ ซึ่งมีรายการหลายหน้า

แต่คุณก็รู้ว่าฉันจะไม่หยุดอยู่แค่นี้ ฉันสร้างโมดูลชื่อ StickyNotes

#requires -version 3.0

#StickyNotes.psm1

<#
a set of functions for using Sticky Notes in Windows

Learn more:
 PowerShell in Depth: An Administrator's Guide (http://www.manning.com/jones6/)
 PowerShell Deep Dives (http://manning.com/hicks/)
 Learn PowerShell in a Month of Lunches (http://manning.com/jones3/)
 Learn PowerShell Toolmaking in a Month of Lunches (http://manning.com/jones4/)
 

  ****************************************************************
  * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED *
  * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK.  IF   *
  * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, *
  * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING.             *
  ****************************************************************

#>


#load necessary assemblies just in case
[void] [System.Reflection.Assembly]::LoadWithPartialName("'Microsoft.VisualBasic")
[void] [System.Reflection.Assembly]::LoadWithPartialName("'System.Windows.Forms")

#sleep interval to allow stikynot process to start
$sleep = 150

#private function for formatting the note

Function _FormatNote {

[cmdletbinding(DefaultParameterSetName="__AllParameterSets")]

Param(
[string]$Text,
[switch]$Bold,
[switch]$Italic,
[switch]$Underline,
[Parameter(ParameterSetName="Center")]
[switch]$Center,
[Parameter(ParameterSetName="Right")]
[switch]$Right,
[switch]$Append
)

Write-verbose "Activating note"
#grab the program
[Microsoft.VisualBasic.Interaction]::AppActivate("Sticky Notes")

#add formatting
if ($Bold) {
    [Microsoft.VisualBasic.Interaction]::AppActivate("Sticky Notes")
    [System.Windows.Forms.SendKeys]::SendWait("^b")
}
if ($Italic) {
    [Microsoft.VisualBasic.Interaction]::AppActivate("Sticky Notes")
    [System.Windows.Forms.SendKeys]::SendWait("^i")
}
if ($Underline) {
    [Microsoft.VisualBasic.Interaction]::AppActivate("Sticky Notes")
    [System.Windows.Forms.SendKeys]::SendWait("^u")
}
if ($Center) {
    [Microsoft.VisualBasic.Interaction]::AppActivate("Sticky Notes")
    [System.Windows.Forms.SendKeys]::SendWait("^e")
}
if ($Right) {
    [Microsoft.VisualBasic.Interaction]::AppActivate("Sticky Notes")
    [System.Windows.Forms.SendKeys]::SendWait("^r")
}

if ($append) {
    #jump to the end of existing text
    Write-verbose "Appending"
    [Microsoft.VisualBasic.Interaction]::AppActivate("Sticky Notes")
    [System.Windows.Forms.SendKeys]::SendWait("{Down}")
} 

#send the text
if ($text) {
 #copy text to clipboard and paste it. Faster than trying to send keys
 $text | clip
  [Microsoft.VisualBasic.Interaction]::AppActivate("Sticky Notes")
  [System.Windows.Forms.SendKeys]::SendWait("^v")
  [Microsoft.VisualBasic.Interaction]::AppActivate("Sticky Notes")
  #give the paste a moment to complete
  start-sleep -Milliseconds 50
  [System.Windows.Forms.SendKeys]::SendWait("{Enter}")
 
 
} #if $text

[Microsoft.VisualBasic.Interaction]::AppActivate("Sticky Notes")
Start-Sleep -Milliseconds 50
[System.Windows.Forms.SendKeys]::SendWait("{Down}")

Write-Verbose "Finished formatting note"
} #end private function

Function New-StickyNote {

<#
.Synopsis
Create a new sticky note.
.Description
This command will create a new sticky note. You can specify additional formatting options.
.Parameter Center
Align text center. The default is left.
.Parameter Right
Align text right. The default is left.
.Example
PS C:\> new-stickynote "pickup milk on the way home" -bold
.Notes
Last Updated: Sept. 25, 2014
Version     : 0.9

#>

[cmdletbinding(DefaultParameterSetName="__AllParameterSets")]
Param(
[Parameter(position=0,Mandatory=$True,HelpMessage="Enter text for the sticky note")]
[string]$Text,
[switch]$Bold,
[switch]$Italic,
[switch]$Underline,
[Parameter(ParameterSetName="Center")]
[switch]$Center,
[Parameter(ParameterSetName="Right")]
[switch]$Right
)

Write-Verbose "Starting $($MyInvocation.MyCommand)"

#if Sticky Note is already running switch to Add-StickyNote

$proc = Get-Process -Name stikynot -ErrorAction SilentlyContinue
if ($proc) {
  Write-Verbose "Sticky Note already running. Calling Add-StickyNote"
  Add-StickyNote @PSBoundParameters
  #bail out of this function
  Return
}
else {
#start the program
Try {
    Write-Verbose "Starting new process"
    Start-Process stikynot
    #give it a moment to complete
    Write-Verbose "Sleeping $sleep ms"
    Start-Sleep -Milliseconds $sleep
}
catch {
    Throw
}

} #if $proc

#format the note
_FormatNote @PSBoundParameters

#return focus to originating app
[Microsoft.VisualBasic.Interaction]::AppActivate($pid)

Write-Verbose "Ending $($MyInvocation.MyCommand)"
} #end function

Function Add-StickyNote {

<#
.Synopsis
Add a new sticky note.
.Description
This command will create a add sticky note. You can specify additional formatting options. If there are no existing sticky notes, this command will create one.
.Parameter Center
Align text center. The default is left.
.Parameter Right
Align text right. The default is left.
.Example
PS C:\> add-stickynote "pickup milk on the way home" -bold
.Notes
Last Updated: Sept. 25, 2014
Version     : 0.9

#>

[cmdletbinding(DefaultParameterSetName="__AllParameterSets")]
Param(
[Parameter(position=0,Mandatory=$True,HelpMessage="Enter text for the sticky note")]
[string]$Text,
[switch]$Bold,
[switch]$Italic,
[switch]$Underline,
[Parameter(ParameterSetName="Center")]
[switch]$Center,
[Parameter(ParameterSetName="Right")]
[switch]$Right
)

Write-Verbose "Starting $($MyInvocation.MyCommand)"

#start the program if not running
Try {
    if (-Not (Get-Process -Name stikynot -ErrorAction SilentlyContinue)) {
        Write-Verbose "Starting Sticky Note"
        Start-Process stikynot
        #give it a moment to complete
         Write-Verbose "Sleeping $sleep ms"
        Start-Sleep -Milliseconds $sleep
       $Existing = $False
    }
    else {
         #create a flag to know that I can use an existing process
         Write-Verbose "Re-using existing Sticky Note Process"
        $Existing = $True
    }
        #grab the program
        [Microsoft.VisualBasic.Interaction]::AppActivate("Sticky Notes")
   
}
catch {
    Throw
}

If ($Existing) {
    #Add a new note
    Write-Verbose "Add a new note"
    [System.Windows.Forms.SendKeys]::SendWait("^n")
    Start-sleep -Milliseconds $sleep
}

#format the note
_FormatNote @PSBoundParameters

#return focus to originating app
[Microsoft.VisualBasic.Interaction]::AppActivate($pid)

Write-Verbose "Ending $($MyInvocation.MyCommand)"


} #end function

Function Set-StickyNote {

<#
.Synopsis
Set text and style for a sticky note.
.Description
This command will set the text and style for a sticky note. If there are multiple notes, this command will set the one that has focus, which you must do manually. The default is the last note created.

The style parameters like Bold behave more like toggles. If text is already in bold than using -Bold will turn it off and vice versa.
.Parameter Center
Align text center. The default is left.
.Parameter Right
Align text right. The default is left.
.Parameter Append
Append your text to the end of the note. Otherwise existing text will be replaced
.Example
PS C:\> set-stickynote "pickup milk on the way home" -bold -underline -append
.Notes
Last Updated: Sept. 25, 2014
Version     : 0.9

#>

[cmdletbinding(DefaultParameterSetName="__AllParameterSets")]
Param(
[Parameter(position=0)]
[string]$Text,
[switch]$Bold,
[switch]$Italic,
[switch]$Underline,
[Parameter(ParameterSetName="Center")]
[switch]$Center,
[Parameter(ParameterSetName="Right")]
[switch]$Right,
[switch]$Append
)

Write-Verbose "Starting $($MyInvocation.MyCommand)"

#start the program if not running
Try {
     #grab the program
     [Microsoft.VisualBasic.Interaction]::AppActivate("Sticky Notes")
    #select existing text
    [System.Windows.Forms.SendKeys]::SendWait("^a")
}
catch {
    Throw
}

#format the note
_FormatNote @PSBoundParameters

#return focus to originating app
[Microsoft.VisualBasic.Interaction]::AppActivate($pid)

Write-Verbose "Ending $($MyInvocation.MyCommand)"


} #end function

Function Remove-StickyNote {

<#
.Synopsis
Remove a new sticky note.
.Description
This command will remove the sticky note that has focus. If you have more than one note, the last one created has focus, unless you manually select a different one.

If you kill the stikynot process, the next time you create a note, any previously created notes will return.

.Example
PS C:\> remove-stickynote 

.Notes
Last Updated: Sept. 25, 2014
Version     : 0.9

#>

[cmdletbinding(SupportsShouldProcess)]
Param()

Write-Verbose "Starting $($MyInvocation.MyCommand)"

$proc= Get-Process stikynot -ErrorAction Stop
if ($proc) {
    #grab the program
    [Microsoft.VisualBasic.Interaction]::AppActivate("Sticky Notes")
    if ($PSCmdlet.ShouldProcess(($proc| Out-String).Trim())) {
        [System.Windows.Forms.SendKeys]::SendWait("^d")
    } #whatif
}
else {
    Write-Verbose "No sticky notes seem to be running"
}

#return focus to originating app
[Microsoft.VisualBasic.Interaction]::AppActivate($pid)

Write-Verbose "Ending $($MyInvocation.MyCommand)"


} #end function

#define aliases
Set-Alias -Name rn -Value Remove-StickyNote
Set-Alias -Name an -Value Add-StickyNote
Set-Alias -Name sn -Value Set-StickyNote
Set-Alias -Name nn -Value New-StickyNote

Export-ModuleMember -Alias * -Function "*-StickyNote"

โมดูลประกอบด้วยฟังก์ชันต่างๆ มากมายสำหรับการสร้าง เพิ่ม การตั้งค่า และการลบบันทึกย่อช่วยเตือน ส่วนที่ยุ่งยากคือการกำหนดเวลาให้ถูกต้อง คุณอาจต้องปรับค่าสลีปบางค่า หรือเตรียมพร้อมที่จะรันคำสั่งอีกครั้ง ฉันจะไม่สร้างกระบวนการที่สำคัญต่อภารกิจใดๆ ก็ตามที่ใช้เทคนิคการส่งคีย์เนื่องจากไม่น่าเชื่อถือ แต่รับรองว่าสนุกแน่!

คุณอาจใช้มันเช่นนี้:

start-job { 
$paramHash = @{
 LogName = "System"
 newest = 10
 ComputerName = "chi-dc01","chi-dc02","chi-dc04","chi-core01","chi-hvr2"
 EntryType = "Error","warning"
}

Get-EventLog @paramHash
New-StickyNote "The event log job has completed" -Bold

} 

ในตอนท้ายของคำสั่ง จะมีข้อความแจ้งเตือนปรากฏขึ้นเพื่อแจ้งให้คุณทราบว่าการกระทำเสร็จสิ้นแล้ว คุณอาจเห็นข้อผิดพลาดเกี่ยวกับกระบวนการที่ขาดหายไป แต่คุณสามารถเพิกเฉยได้ หรือบางทีคุณอาจแค่ต้องการคำเตือนให้ไปรับขนมปังก้อนนั้นหรือลูกของคุณระหว่างทางกลับบ้าน

บางครั้ง PowerShell ไม่ใช่เครื่องมือที่ดีที่สุดสำหรับงาน แต่ฉันคิดว่ามันสนุกได้เสมอ แจ้งให้เราทราบว่าคุณคิดอย่างไรกับโครงการเล็ก ๆ ของฉัน

มีวันหยุดสุดสัปดาห์ที่ดี.

บทความที่เกี่ยวข้อง