Skip to content

Commit 7bb70f7

Browse files
author
donald
committed
v0.3.4
1 parent fdbcc19 commit 7bb70f7

File tree

23 files changed

+756
-3
lines changed

23 files changed

+756
-3
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ thumbs.db
44
*.pssproj
55
*.sln
66
.DS_Store
7+
.Rhistory

AnyBox.psd1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
ModuleToProcess = 'AnyBox.psm1'
44

55
# Version number of this module.
6-
ModuleVersion = '0.3.3'
6+
ModuleVersion = '0.3.4'
77

88
# Supported PSEditions
99
# CompatiblePSEditions = 'Desktop'
@@ -18,7 +18,7 @@
1818
# CompanyName = 'Unknown'
1919

2020
# Copyright statement for this module
21-
Copyright = '(c) 2018 Donald Mellenbruch. All rights reserved.'
21+
Copyright = '(c) 2019 Donald Mellenbruch. All rights reserved.'
2222

2323
# Description of the functionality provided by this module
2424
Description = 'Designed to facilitate script input/output with an easily customizable WPF window.'

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file.
44

55
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
66

7+
## v0.3.4 - 2019-03-08
8+
9+
### Added
10+
11+
- Added `AnyBox.AnyBox` class to provide a new interface for building AnyBox forms, as opposed to just function calls.
12+
13+
### Changed
14+
15+
- Updated example app, `Process_Killer`, to use the new class interface.
16+
- Resolved issue #8.
17+
718
## v0.3.3 - 2018-09-25
819

920
### Removed

README.Rmd

Lines changed: 356 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,356 @@
1+
---
2+
title: "AnyBox"
3+
output:
4+
md_document:
5+
toc: true
6+
toc_depth: 3
7+
variant: markdown_strict+backtick_code_blocks
8+
pandoc_args: ["--atx-headers"]
9+
---
10+
11+
```{r setup, include=FALSE}
12+
knitr::opts_chunk$set(echo = TRUE, eval=FALSE, engine='bash',
13+
engine.path = list('bash'="C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe"))
14+
```
15+
16+
# *Message Box, Input Box*, <u>AnyBox</u>
17+
18+
Read this on [GitHub](https://github.com/dm3ll3n/AnyBox) or [my site](https://www.donaldmellenbruch.com/project/AnyBox/).
19+
20+
## Overview
21+
22+
Creating forms in Powershell can be tedious, from aligning the content just right to wiring up events. Thankfully, when it comes to GUIs for Powershell scripts, a simple message box or input box usually does the trick. The problem is that the not-so-built-in offerings for Powershell are extremely limited in (1) features and (2) customization.
23+
24+
Message box:
25+
26+
```{powershell, eval=FALSE}
27+
Add-Type -AssemblyName PresentationFramework
28+
29+
[System.Windows.MessageBox]::Show('hello world', 'MessageBoxDemo')
30+
```
31+
32+
![](imgs/0a.PNG)
33+
34+
Input box:
35+
36+
```{powershell, eval=FALSE}
37+
[Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')
38+
39+
[Microsoft.VisualBasic.Interaction]::InputBox('interesting input', 'InputBoxDemo')
40+
```
41+
42+
![](imgs/0b.PNG)
43+
44+
Neither of these approaches are customizable beyond the essentials; they are focused purely on their limited functional. They're also not very Powershell-esque. If you want anything more, you'll have to create it yourself. A few options exist to make the creation of a custom form simpler (form designers), but the learning curve can be steep for a non-developer Powershell users (e.g., engineers, admins), and it is a tedious task even for the Powershell experts.
45+
46+
AnyBox was developed to satisfy both the need for simplicity and advanced customization when creating appealing WPF forms in Windows Powershell.
47+
48+
## How to get it
49+
50+
Install AnyBox from the [Powershell Gallery](https://www.powershellgallery.com/packages/AnyBox) with:
51+
52+
```{powershell, eval=FALSE}
53+
Install-Module -Name 'AnyBox'
54+
```
55+
56+
Then, load it with:
57+
58+
```{powershell}
59+
Import-Module AnyBox
60+
```
61+
62+
## Message Box
63+
64+
Simple message box with AnyBox:
65+
66+
```{powershell}
67+
Show-AnyBox -Title 'MessageBoxDemo' -Message 'hello world' -Buttons 'OK'
68+
```
69+
70+
![](imgs/01.PNG)
71+
72+
Center the content and increase font size:
73+
74+
```{powershell}
75+
Show-AnyBox -Title 'MessageBoxDemo' -Message 'hello world' -FontSize 14 -ContentAlignment 'Center' -Buttons 'OK'
76+
```
77+
78+
![](imgs/02.PNG)
79+
80+
Add more buttons:
81+
82+
```{powershell}
83+
Show-AnyBox -Title 'MessageBoxDemo' -Message 'hello world' -FontSize 14 -ContentAlignment 'Center' -Buttons 'Yes','No','Maybe?'
84+
```
85+
86+
![](imgs/03.PNG)
87+
88+
Change the modal frame and set the window topmost:
89+
90+
```{powershell}
91+
Show-AnyBox -Title 'MessageBoxDemo' -Message 'hello world' -FontSize 14 -ContentAlignment 'Center' -Buttons 'Yes','No','Maybe?' -WindowStyle 'ToolWindow' -Topmost
92+
```
93+
94+
![](imgs/04.PNG)
95+
96+
Make it gnarly:
97+
98+
```{powershell}
99+
Show-AnyBox -Title 'MessageBoxDemo' -Message 'hello world' -FontSize 14 -ContentAlignment 'Center' -Buttons 'Yes','No','Maybe?' -Topmost `
100+
-Icon 'Warning' -BackgroundColor 'Black' -FontColor 'Orange' -FontFamily 'Comic Sans MS'
101+
```
102+
103+
![](imgs/05.PNG)
104+
105+
## Input Box
106+
107+
Simple input box with AnyBox:
108+
109+
```{powershell}
110+
Show-AnyBox -Title 'InputBoxDemo' -Prompt "what's your name?" -Buttons 'Cancel','Submit'
111+
```
112+
113+
![](imgs/06.PNG)
114+
115+
Add more prompts and a comment:
116+
117+
```{powershell}
118+
Show-AnyBox -Title 'InputBoxDemo' -Prompts "what's your name?","what's your number?" -Buttons 'Cancel','Submit' -Comment '* responses are confidential'
119+
```
120+
121+
![](imgs/07.PNG)
122+
123+
> The next couple of examples jump ahead a bit, but to give you an idea of what's possible...
124+
125+
Multi-line input:
126+
127+
```{powershell}
128+
Show-AnyBox -Title 'InputBoxDemo' -Buttons 'Cancel','Submit' -Prompts @(
129+
New-AnyBoxPrompt -Message 'Query:' -LineHeight 5
130+
)
131+
```
132+
133+
![](imgs/08.PNG)
134+
135+
Grouped prompts and collapsible prompts:
136+
137+
```{powershell}
138+
Show-AnyBox -Title 'InputBoxDemo' -Buttons 'Cancel','Submit' -MinWidth 100 -Prompts @(
139+
New-AnyBoxPrompt -Group 'Connection Info' -Message 'SQL Instance:'
140+
New-AnyBoxPrompt -Group 'Connection Info' -Message 'User Name:'
141+
New-AnyBoxPrompt -Group 'Connection Info' -Message 'Password:' -InputType Password
142+
New-AnyBoxPrompt -Group 'Query' -LineHeight 5 -Collapsible
143+
)
144+
```
145+
146+
![](imgs/09.PNG)
147+
148+
## AnyBox
149+
150+
AnyBox makes a fine replacement for your typical message box and input box, and it can do a lot more. So much so that, given a long list of parameters, it may be more intuitive to "build" the AnyBox top-down rather than calling the function with a long list of parameters. For example, the two functions below produce the same AnyBox:
151+
152+
```{powershell}
153+
Show-AnyBox -Icon 'Question' -Title 'AnyBoxDemo' -Prompts "what's your name?","what's your number?" -FontSize 14 -ContentAlignment 'Center' -Buttons 'Yes','No','Maybe?' -DefaultButton 'Yes' -CancelButton 'No' -ButtonRows 2 -Topmost
154+
```
155+
156+
*or*
157+
158+
```{powershell}
159+
Import-Module AnyBox
160+
161+
$anybox = New-Object AnyBox.AnyBox
162+
163+
$anybox.Icon = 'Question'
164+
$anybox.Title = 'AnyBoxDemo'
165+
$anybox.Prompts = 'what''s your name?','what''s your number?'
166+
$anybox.FontSize = 14
167+
$anybox.ContentAlignment = 'Center'
168+
$anybox.Buttons = 'Yes','No','Maybe?'
169+
$anybox.DefaultButton = 'Yes'
170+
$anybox.CancelButton = 'No'
171+
$anybox.ButtonRows = 2
172+
$anybox.Topmost = $true
173+
174+
$anybox | Show-AnyBox
175+
```
176+
177+
![](imgs/10.PNG)
178+
179+
> Note: the later syntax was introduced in AnyBox v0.3.4.
180+
181+
### Prompts
182+
183+
AnyBox offers many different prompt types. The typical prompt `Text`, shown in the examples above, is used when the value for "-Prompts" is a string. As you'll see, `Text` can be represented as a text box, combo box, or set of radio buttons. To use other prompt types and make customizations to individual prompts, use `New-AnyBoxPrompt`.
184+
185+
```{powershell}
186+
Import-Module AnyBox
187+
188+
$anybox = New-Object AnyBox.AnyBox
189+
190+
$anybox.Prompts = @(
191+
# typical text prompt, but with default value.
192+
New-AnyBoxPrompt -InputType Text -Message "what's your name?" -DefaultValue 'donald'
193+
# typical text prompt, but with validation (must be all numeric).
194+
New-AnyBoxPrompt -InputType Text -Message "what's your number?" -ValidateScript { $_ -match '^[0-9]+$' }
195+
# sets are shown as drop-down lists.
196+
New-AnyBoxPrompt -InputType Text -Message "what's your favorite color?" -ValidateSet 'red','blue','green' -DefaultValue 'blue'
197+
# or sets of radio buttons.
198+
New-AnyBoxPrompt -InputType Text -Message "what's your favorite fruit?" -ValidateSet 'apple','banana','tomato?' -DefaultValue 'banana' -ShowSetAs Radio
199+
# date input.
200+
New-AnyBoxPrompt -InputType Date -Message "what's your birthday?" -DefaultValue '1970-01-01'
201+
# secure string input.
202+
New-AnyBoxPrompt -InputType Password -Message "what's your SSN?"
203+
# file input
204+
New-AnyBoxPrompt -InputType FileOpen -Message "Upload supporting documents:"
205+
# link input
206+
New-AnyBoxPrompt -InputType Link -Message "Terms & Conditions" -DefaultValue 'www.donaldmellenbruch.com'
207+
# checkbox (boolean) input.
208+
New-AnyBoxPrompt -InputType Checkbox -Message "I have read the terms & conditions" -DefaultValue $false
209+
)
210+
211+
$anybox.ContentAlignment = 'Center'
212+
$anybox.Buttons = 'Cancel','Submit'
213+
$anybox.Icon = 'Question'
214+
215+
$anybox | Show-AnyBox
216+
```
217+
218+
![](imgs/11.PNG)
219+
220+
### Buttons
221+
222+
To create a customized button, use `New-AnyBoxButton`. There are a few pre-made action buttons that can be created from a template, such as `'CopyMessage'`, which will copy the displayed message to the clipboard.
223+
224+
```{powershell}
225+
Import-Module AnyBox
226+
227+
$anybox = New-Object AnyBox.AnyBox
228+
229+
$anybox.Icon = 'Error'
230+
$anybox.Message = 'Process.exe exited with code -1.'
231+
232+
$anybox.Buttons = @(
233+
New-AnyBoxButton -Text 'Close' -IsCancel
234+
New-AnyBoxButton -Template 'CopyMessage'
235+
New-AnyBoxButton -Text 'Retry' -IsDefault
236+
)
237+
238+
$anybox | Show-AnyBox
239+
```
240+
241+
![](imgs/12.PNG)
242+
243+
### Data Grid
244+
245+
In addition to messages, prompts, and buttons, AnyBox can present a data grid, complete with a search bar.
246+
247+
```{powershell}
248+
Import-Module AnyBox
249+
250+
$anybox = New-Object AnyBox.AnyBox
251+
252+
$anybox.Title = 'Windows Services'
253+
$anybox.ContentAlignment = 'Center'
254+
$anybox.MaxHeight = 600
255+
256+
$anybox.GridData = Get-Service | Select-Object Status, Name, DisplayName
257+
258+
$anybox.Buttons = @(
259+
New-AnyBoxButton -Text 'Close'
260+
New-AnyBoxButton -Template 'ExploreGrid'
261+
New-AnyBoxButton -Template 'SaveGrid'
262+
)
263+
264+
$anybox | Show-AnyBox
265+
```
266+
267+
![](imgs/13.PNG)
268+
269+
> Suppress the grid search bar by setting `$anybox.NoGridSearch=$true`
270+
271+
### Handling Input
272+
273+
Getting a message to users is only half the battle. Handling their responses is the other half, and AnyBox makes that easier too.
274+
275+
After an AnyBox window closes, it returns a hashtable of user inputs (if any). The hashtable will contain a key for each prompt and each button. By default, prompt keys are named "Input_#", where `#` is index of the prompt in the order they were defined (starting from 0). Buttons, by default, are named by their text. To override the corresponding key name, specify a `-Name` for the prompt/button when defining it with `New-AnyBoxPrompt`/`New-AnyBoxButton`. Names cannot contain spaces.
276+
277+
```{powershell}
278+
Import-Module AnyBox
279+
280+
$anybox = New-Object AnyBox.AnyBox
281+
282+
$anybox.Prompts = 1..3 | ForEach-Object { New-AnyBoxPrompt -Message "Prompt $_" -Name "Prompt_$_" }
283+
$anybox.Buttons = 1..3 | ForEach-Object { New-AnyBoxButton -Text "Button $_" -Name "Button_$_" }
284+
285+
$response = $anybox | Show-AnyBox
286+
287+
$response
288+
```
289+
290+
![](imgs/14.PNG)
291+
292+
##
293+
## Name Value
294+
## ---- -----
295+
## Prompt_3 also, text
296+
## Button_1 False
297+
## Prompt_2 moar text
298+
## Prompt_1 some text
299+
## Button_3 True
300+
## Button_2 False
301+
302+
To examine the output for a specific prompt/button (here, `Prompt_1`):
303+
304+
```{powershell, eval=FALSE}
305+
$response['Prompt_1']
306+
```
307+
308+
To see which button was clicked, iterate over the hashtable.
309+
310+
```{powershell, eval=FALSE}
311+
$response.Keys | Where-Object { $_ -like 'Button_*' -and $response[$_] -eq $true }
312+
```
313+
314+
A similar method of iterating over the responses, which will return an array of key-value pairs that match a condition.
315+
316+
```{powershell, eval=FALSE}
317+
$response.GetEnumerator() | Where-Object { $_.Name -like 'Prompt_*' -and $_.Value -like '*' }
318+
```
319+
320+
So, a simple AnyBox workflow could look something like:
321+
322+
```{powershell}
323+
Import-Module AnyBox
324+
325+
# build the AnyBox
326+
$anybox = New-Object AnyBox.AnyBox
327+
328+
$anybox.Prompts = New-AnyBoxPrompt -Name 'name' -Message "what's your name?" -ValidateNotEmpty
329+
330+
$anybox.Buttons = @(
331+
New-AnyBoxButton -Name 'cancel' -Text 'Cancel' -IsCancel
332+
New-AnyBoxButton -Name 'submit' -Text 'Submit' -IsDefault
333+
)
334+
335+
# show the AnyBox; collect responses.
336+
$response = $anybox | Show-AnyBox
337+
338+
# act on responses.
339+
if ($response['submit'] -eq $true) {
340+
$name = $response['name']
341+
Show-AnyBox -Message "Hello $name!" -Buttons 'OK'
342+
}
343+
else {
344+
Show-AnyBox -Message "Ouch!" -Buttons 'OK'
345+
}
346+
```
347+
348+
![](imgs/15.PNG) -----> ![](imgs/16.PNG)
349+
350+
## More resources
351+
352+
This guide was reworked as of AnyBox v0.3.4. More extensive docs exist at:
353+
354+
https://www.donaldmellenbruch.com/doc/anybox/
355+
356+
Cheers!

0 commit comments

Comments
 (0)