How to check if a window is open in Eclipse RCP, with RCPTT - eclipse-rcp

I have an ECL script developed in RCPTT, to test an RCP application. During the test, it sets some settings and save it. When the test press "OK", an information window can open to inform user that this change need to rebuild the project.
My problem is that this window will not always shown. If in the workspace where the test run, this window has already been opened, and the option "Remmenber my decision" has been set, then it won't open.
I want to put a if in my test to handle the both cases. It should be something like :
if [/* what can i put here ?*/] {
get-window Settings | get-button Yes | click
}
How to write such a condition ?
Can I do something like if [get-window Settings | verify-true ] or if [ not [get-window Settings | verify-error ] ] ?
Edit: By using the "record snippet" tool, I've arrived to something like :
with [get-window Settings] {
get-property "isEnabled()" | equals true | verify-true
get-property "isVisible()" | equals true | verify-true
}
Which property is the good one tu use in my case ? Enable, Visible or both ?

Use try-catch in such cases:
try {
get-window Settings | get-button Yes | click
} -catch {
// Verify that the window was missing (and not some other problem)
verify-error -command {get-window Settings}
}

Related

Powershell code errors when executed using 'Run with PowerShell' but runs OK in PS Editor

Work continues on migrating my HTA to an XAML-based, PowerShell-driven form...
When I run my script inside PSE, the hiding/unhiding of grids using the 'Visibility' property, driven from the user selecting a drop-down item, works great. However, if I run it using Explorer's 'Run with PowerShell' context menu, or from a PS command prompt, I get the error "The property 'Visibility' cannot be found on this object" when the drop-down selection changes.
For completeness, here's the function which is in an imported .PSM1 file:
Function cmbDeploymentPurpose_OnSelectionChanged($Form, $SelectedValue){
If ($SelectedValue.ToString() -eq "System.Windows.Controls.ComboBoxItem: Available")
{
$grdDeploymentSettings_Available.Visibility = "Visible"
$grdDeploymentSettings_Required.Visibility = "Hidden"
$grdScheduling_Required.Visibility = "Hidden"
}
ElseIf ($SelectedValue.ToString() -eq "System.Windows.Controls.ComboBoxItem: Required")
{
$grdDeploymentSettings_Available.Visibility = "Hidden"
$grdDeploymentSettings_Required.Visibility = "Visible"
$grdScheduling_Required.Visibility = "Visible"
}
}
and here's the relevant event creation:
$cmbDeploymentPurpose.Add_SelectionChanged({cmbDeploymentPurpose_OnSelectionChanged $Form $cmbDeploymentPurpose.SelectedValue}.GetNewClosure())
In each case, the user credentials are the same.

Setting StrongAuthenticationUserDetails PhoneNumber for AzureAD via Powershell?

That title really flows.
When setting up computers for use with Azure Active Directory, we would have IT do initial setup and config. This included the first sign in and joining to Azure Active Directory. When signing in it forces you to select a verification method. We would use our desk phone or cell phone for ease.
The time has come for us to update that second factor phone number. I know of a way to manually do it via the Azure AD Web UI, but I am looking for a scripted way to set that number in PowerShell.
Here is how I retrieve the number via PowerShell.
Get-msoluser -UserPrincipalName "email#emailaddress.com" | Select-Object -ExpandProperty StrongAuthenticationUserDetails
That code returns this info:
ExtensionData : System.Runtime.Serialization.ExtensionDataObject
AlternativePhoneNumber :
Email :
OldPin :
PhoneNumber : +1 5554445555
Pin :
However, there seems to be no similar option for setting the StrongAuthenticationUserDetails.
All my searches just turned up how to bulk enable 2-factor authentication, which is not what I want to do. I want to leave the StrongAuthentication the same while only updating the phone number.
As I said in comment, it appears there is read-only access for powershell.
There is even opened ticket for that on Azure feedback.
There is a plan to do it, but no ETA. My guess is that you will have to wait if you want to use powershell only.
As workaround, you could use powershell & watir for .NET OR Watin with Watin recorder to automatize it via Internet Explorer. As I don't have a testing Azure; I can not create workable code for you.
Using Watin and powershell - you could check: https://cmille19.wordpress.com/2009/09/01/internet-explorer-automation-with-watin/
The following text and code, I wanted to backup it here, was taken from the above page (all credits to the author):
Next click the record button and click the HTML element you want to
automate. Then stop the WatIN recorder and click copy code to
clipboard icon. This will produce some C# code that just needs to be
translated into PowerShell:
// Windows
WatiN.Core.IE window = new WatiN.Core.IE();
// Frames
Frame frame_sd_scoreboard = window.Frame(Find.ByName("sd") && Find.ByName("scoreboard"));
// Model
Element __imgBtn0_button = frame_sd_scoreboard.Element(Find.ByName("imgBtn0_button"));
// Code
__imgBtn0_button.Click();
window.Dispose();
So, I now know the name of the button and that it is 3 frames deep. A
little WatIN object exploration later, I came up with the follow
script, which clicks a button every 50 mintues.
#Requires -version 2.0
#powershell.exe -STA
[Reflection.Assembly]::LoadFrom( "$ProfileDirLibrariesWatiN.Core.dll" ) | out-null
$ie = new-object WatiN.Core.IE("https://sd.acme.com/CAisd/pdmweb.exe")
$scoreboard = $ie.frames | foreach {$_.frames } | where {$_.name –eq ‘sd’} | foreach {$_.frames } | where {$_.name –eq ‘scoreboard’}
$button = $scoreboard.Element("imgBtn0_button")
while ($true)
{
$button.Click()
#Sleep for 50 minutes
[System.Threading.Thread]::Sleep(3000000)
}
Disclaimer: the code is provided as-is. It might happen that it'll stop working in case MS changes Azure Portal interface.
I'm using the following Greasemonkey script to update alternate email and phone (phone can be updated via Graph API now so the script will be useful for email only):
// ==UserScript==
// #name Unnamed Script 548177
// #version 1
// #grant none
// #namespace https://portal.azure.com
// ==/UserScript==
(function(){
document.addEventListener('keydown', function(e) {
// press alt+shift+g
if (e.keyCode == 71 && e.shiftKey && !e.ctrlKey && e.altKey && !e.metaKey) {
const url = document.URL;
const regex = /https:\/\/portal.azure.com\/#blade\/Microsoft_AAD_IAM\/UserDetailsMenuBlade\/UserAuthMethods\/userId\/[\w-]+\/adminUnitObjectId[\/]*\?\w+=(\d{9})&\w+=([\w\.-#]+)/;
const params = url.match(regex);
const allAuthRows = document.getElementsByClassName('ext-userauthenticationmethods-section-row');
const authRowsArray = Array.from(allAuthRows);
let emailRow;
let phoneRow;
let i;
for (i =0; i < authRowsArray.length; i++) {
if (authRowsArray[i].childNodes[1].childNodes[1].childNodes[0].data === 'Email') {
emailRow = authRowsArray[i]
}
if (authRowsArray[i].childNodes[1].childNodes[1].childNodes.length > 1) {
if (authRowsArray[i].childNodes[1].childNodes[1].childNodes[1].childNodes[0].data === 'Phone') {
phoneRow = authRowsArray[i]
}
}
}
const emailInput = emailRow.childNodes[3].childNodes[1].childNodes[1].childNodes[0].childNodes[0].childNodes[0].childNodes[2];
const phoneInput = phoneRow.childNodes[3].childNodes[1].childNodes[1].childNodes[0].childNodes[0].childNodes[0].childNodes[2];
const event = new Event('input', {
'bubbles': true,
'cancelable': true
});
if (params[1] !== '000000000') {
phoneInput.value = `+48 ${params[1]}`;
phoneInput.dispatchEvent(event);
}
if (params[2] !== 'null') {
emailInput.value = params[2];
emailInput.dispatchEvent(event);
}
setTimeout(() => {
const buttonArr = document.getElementsByClassName('azc-toolbarButton-container fxs-portal-hover');
const saveButton = Array.from(buttonArr).find(e => e.title === 'Save');
saveButton.click();
} , 2000);
}
}, false);
})();
It requires you to open Azure portal with querystring like this (I do it with PowerShell):
https://portal.azure.com/#blade/Microsoft_AAD_IAM/UserDetailsMenuBlade/UserAuthMethods/userId/$($u.ObjectId)/adminUnitObjectId/?param1=$newPhone&param2=$newMail
How to use it:
open only one tab at a time, otherwise you'll receive Unable to sign-in error
from time to time you'll receive that error anyway, so just wait
to trigger the script press Alt+Shift+g after the site is loaded (you can change the shortcut in first if)
once the data is updated and saved, press Ctrl+w to close the current tab and press Alt+Tab to switch to previous window (should be PowerShell)
you're still free to use the code to update the phone. Make sure to change country code (currently +48 for Poland)

NuGet: How can I set "visible" of content to false with Install.ps1 file?

I know this sets CopyToOutputDirectory to Always
$project.ProjectItems.Item("test.exe").Properties.Item("CopyToOutputDirectory").Value = 1
But when I try to set Visible in the same way it won't work
$project.ProjectItems.Item("test.exe").Properties.Item("Visible").Value = 1 or "false" or $false
test.exe does not have a property item Visible so you cannot set the value
You will get an error if you do this
$project.ProjectItems.Item("Program.cs").Properties.Item("Visible")
This will work because CopyToOutputDirectory is an actual property
$project.ProjectItems.Item("test.exe").Properties.Item("CopyToOutputDirectory")
You could use Microsoft.Build.Evaluation.ProjectCollection as an alternative, but making changes in this way would require the project to be reloaded after the package is installed.
$buildProject = [Microsoft.Build.Evaluation.ProjectCollection]::GlobalProjectCollection.GetLoadedProjects($project.FullName)
$buildProject.Xml.AllChildren|?{$_.Include -eq "test.exe"} | % {
if ($_.HasMetadata -and ($visible=$_.Metadata|?{$_.Name -eq "Visible"}))
{
$visible.Value = $false
}
else
{
$_.AddMetadata("Visible",$false)
}
}
$buildProject.Save()
However, it appears to prevent the file from being uninstalled, and I'm not sure Uninstall.ps1 is called at the appropriate time for visibility to be restored so that NuGet can handle deletion.

JES f==None not working

I'm using JES version 5.010. I'm trying to do this assignment for school:
For the first part of the assignment, you are going to write a
function that will select, using pickAFile(), a picture file to be
opened. If cancel is pressed in the pickAFile() dialogue box, then you
must ask the user if it was a mistake. If it was a mistake, open the
pickAFile() dialogue again, and repeat until it is either not a
mistake, or a picture file was selected. If a picture file is
selected, return the 'made' picture, otherwise (i.e. cancel was pushed
and the user indicated that it was NOT a mistake) return an error
message. NOTE: the JES function requestString (see JES
Functions-->Input/Output) should be used when asking the user if the
pressing of 'cancel' was a mistake.
For some reason my if statement, if f==None, isn't working properly and I have no clue why. My code is below
def assign3PartA():
noFile = True
while noFile:
f = pickAFile()
if f==None: #This is what isn't working
noFile=mistake()
noFile = False
print "Invalid option, you must select a picture to continue!"
else: #Working fine
pic = makePicture(f)
show(pic)
break
def mistake():
ask = requestString("Did you press cancel by mistake? Enter yes or no. ")
if ask == "yes" or ask == "Yes":
return True
elif ask == "No" or ask == "no":
return False
else:
print "Try again. Please enter either yes or no."
mistake()
I have also tried if f is None as well and that didn't work.
Any help you can give is appreciated.
I found my error sigh. I get needed to put None in quotation marks.
if j == "None":

Is there a way to store message box settings to be used repetitively in Powershell?

I'd like to use the same message box repetitively in a Powershell script, without having to reiterate all the settings each time. I initially thought that I would store it as a variable:
$StandardMessage = [System.Windows.Forms.MessageBox]::Show("Repetitive Message.", "Chores.")
But as I found out this simply stores the user's response to the message box in the variable.
What I would like to do is something similar to the following pseudo-code:
$StandardMessage = [System.Windows.Forms.MessageBox]::Show("Repetitive Message.", "Chores.")
While(true){
If(condition){
$StandardMessage
}
If(condition2){
$StandardMessage
}
}
Where the conditions would be time-based. This is essentially displaying a message at specified times during the day.
Asked another way (and perhaps more clearly): Is it possible to 'define' a messagebox without actually 'showing' it?
You need to use a Function my good man!
Function Show-MyMessage{
[System.Windows.Forms.MessageBox]::Show("Repetitive Message.", "Chores.")
}
While(true){
If(condition){
Show-MyMessage
}
If(condition2){
Show-MyMessage
}
}
Edit: Personally I have this function on hand for several of my scripts to use as needed:
Function Show-MsgBox ($Text,$Title="",[Windows.Forms.MessageBoxButtons]$Button = "OK"){
[Windows.Forms.MessageBox]::Show("$Text", "$Title", [Windows.Forms.MessageBoxButtons]::$Button, [Windows.Forms.MessageBoxIcon]::Information) | ?{(!($_ -eq "OK"))}
}
Then I can just call it as needed, like:
Show-MsgBox -Title "You want the truth?" -Text "You can't handle the truth!"
And I've got a pop up with the text and title I want, and an OK button.
Buttons can be specified (there's a pop-up for it in the ISE to give options), and title can be excluded if I am feeling lazy. Only thing I really have to feed it is the message.