I want to write a programm which has a Kind of traffic light funtion. The color of the Frame should be changed depending on an check. I already solved the check of the criterias, so in this example the while-Loop is vicarious for a bigger check. But to focus on the problem i shortend it like this. My problem is that i canĀ“t update the Color of the UI.
So the program should be running all the time, but it seems to be stuck at:
[void] $Form.ShowDialog()
and only will continue after I close the form. So how can i bypass this section to get into the infinit Loop, so that my Form is shown all the time with changing Color?
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
$Form = New-Object System.Windows.Forms.Form
$Form.Text = "Test"
$Form.Size = New-Object System.Drawing.Size(300,300)
$Form.StartPosition = "CenterScreen"
$Form.BackColor = "Green"
$Form.Topmost = $True
$Form.Add_Shown({$Form.Activate()})
[void] $Form.ShowDialog()
while ($True)
$test = Get-Content -Path C:\Users\admin\Documents\pro.txt
if ($test -eq 2)
{
$Form.BackColor = "Green"
} else {
$Form.BackColor = "Red"
}
Start-Sleep -s 2
}
Thanks for you help!
$Form.ShowDialog()
This line requires interaction on the form. The code following that line will not run until the form is closed. Another way to launch the form would be like the following
$Form.Show()
If you launch the form like that, the code should continue to run. Although you still may need a better solution, as your following code uses start-sleep -s 2. I believe this might also make your form sleep, which would render it potentially unusable.
I would recommend learning about PowerShell Event Handlers here. There might be a better solution using an event handler for your solution. An example of an event handler follows
$Form_Load {
# Your commands and stuff here #
}
The $Form is the object that the event is looking at, then you have a separator _, then Load is the name of the actual event that when executed the code runs. So any of the code inside those brackets will run right away when form $Form is launched. This can be anything from loading a form, clicking a button, or even a selected index changing inside of a listbox.
Event handlers took my PowerShell GUI building abilities to then next level when it comes to what I had the ability to do with the form. So I would highly recommend learning about event handlers if PowerShell GUIs are the normal for you, the most helpful tool you could buy is SAPIEN PowerShell Studio which is an extremely helpful development environment. It is basically a Visual Studio built just for PowerShell. I think it's in the $400-$500 range.
Related
I've been looking online at ways to automatically change the default tray on a printer. I'm in need of this because my job uses printers via an old IBM server, and these specific printers don't seem to respond to any instruction from the IBM server to change the tray used for the job. My only option to automatically change the preferences of a printer seems to be through a PowerShell script. I found a script on Stack that seems to achieve most of the functionality I want, however, I have very limited scripting knowledge and as a result, I'm unsure how to add the additional functionality required. First off, here's the code:
$Printer = "Example Printer Name"
$InputBin = "AutoSelect","AutoSheetFeeder","Cassette","Manual","Tractor" #choose one
Add-Type -AssemblyName System.Printing
$Permissions = [System.Printing.PrintSystemDesiredAccess]::AdministrateServer
$QueuePerms = [System.Printing.PrintSystemDesiredAccess]::AdministratePrinter
$PrintServer = new-object System.Printing.LocalPrintServer -ArgumentList $Permissions
$NewQueue = New-Object System.Printing.PrintQueue -ArgumentList $PrintServer,$Printer,1,$QueuePerms
$InputBinCaps = $NewQueue.GetPrintCapabilities().InputBinCapability
if ($null -ne $InputBinCaps) {
if ($InputBinCaps.Contains([System.Printing.InputBin]::$InputBin)) {
$NewQueue.DefaultPrintTicket.InputBin = [System.Printing.InputBin]::$InputBin
$NewQueue.UserPrintTicket.InputBin = [System.Printing.InputBin]::$InputBin
} else {
Write-Error "$InputBin unavailable on $Printer"
}
}
$NewQueue.commit()
$NewQueue.dispose()
$PrintServer.commit()
$PrintServer.dispose()
What I need to add is a way to detect what tray is currently set to default and use that data to direct an if statement to change it to the opposite (I only have two trays on these printers, Cassette 1 and Bypass Tray). Additionally, I need the script to immediately close its window upon execution of the task. The reason being is that I plan to put this as a shortcut on their Windows taskbar and have them click the shortcut every time they need to switch printer trays. I understand this setup is jank, but it is the only way to get the correct type of paper printed, save opening up the default tray, and laying one yellow sheet on top.
Any help would be greatly appreciated.
Thanks
I am trying to create a powershell 'AccessObject' comobject for my MS Access app. Basically, I will trying to create a powershell script that gets queries in a database and the tables and/or queries a particular query depends on. To do that i will need to have an instance of the MS Access 'AccessObject' and 'DependencyInfo' classes in my powershell script. I have attached a snippet of the function i intend to use. This is not the complete function, please note. All i want is to know how to create an instance of the DependencyInfo and AccessObjects in powershell.
function getQueries([string] $database)
{
$dbEng = New-Object -ComObject DAO.DBEngine.120
$AccessApp= New-Object -ComObject Access.Application
$Dependency = $AccessApp.DependencyInfo
$AccessObject=$AccessApp.AccessObjects
...
}
All i want is to know how to create an instance of the DependencyInfo
and AccessObjects in powershell.
The following creates a new Access process, opens a local accdb file, and retrieves the dependencies for a given form:
$db = new-object -ComObject 'Access.Application'
$db.OpenCurrentDatabase('C:\temp\deezNutz.accdb')
$dependency_info = $db.Application.CurrentProject().AllForms('frm_person').GetDependencyInfo()
foreach ($dependency in $dependency_info.Dependencies) { $dependency.FullName }
$db.CloseCurrentDatabase()
$db.Application.DoCmd.Quit()
If you're trying to pro grammatically manipulate the objects in a Microsoft Access database e.g., forms, reports, queries, etc. Your best bet is to search for solutions using VBA then convert those to Powershell. For this example, I first wrote the solution in VBA then converted it to Powershell.
Thanks #Lord Adam. This was really helpful. In my case i had to modify the logic a little bit:
$AccessApp= New-Object -ComObject 'Access.Application'
$AccessApp.OpenCurrentDatabase($database)
$AccessApp.Application.SetOption("Track Name AutoCorrect Info", $true)
$QryDependency = $AccessApp.Application.CurrentData.AllQueries.Item($query.Name).GetDependencyInfo()
ForEach($di in $QryDependency.Dependencies)
{
$QryObjects= $QryObjects + $di.Name +","
}
I have an Installshield project that uses powershell custom actions.
In one of my dialogs, I'm asking from the user to enter username and password, then I validate the credentials (with powershell) and I want to enable the Next button only if the credentials were correct.
Can this be achieved with powershell action item? The reason I'm using powershell is that I don't know InstallScript at all.
Here is my powershell script so far:
Function Test-UserCredential {
Param($username, $password)
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$ct = [System.DirectoryServices.AccountManagement.ContextType]::Machine, $env:computername
$opt = [System.DirectoryServices.AccountManagement.ContextOptions]::SimpleBind
$pc = New-Object System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList $ct
$Result = $pc.ValidateCredentials($username, $password).ToString()
$Result
}
$comp_username = Get-Property -Name COMPUTER_USERNAME
$comp_password = Get-Property -Name COMPUTER_PASSWORD
$result = Test-UserCredential -username $comp_username -password $comp_password
if ($result)
{
#Enable "Next" button
}
else
{
#Disable "Next" button
}
Thanks.
There are three things you will have to do.
Choose a property that tracks whether the Next button should be enabled, and set that from your PowerShell. Typically you will set it to "1" or "" (empty string) for ease in the next step.
Create Control Conditions in the dialog editor that Enable and Disable the Next button referencing the property as your condition.
Separately trigger the UI to update after the powershell action completes. Unfortunately the UI does not evaluate control conditions after all property changes; it only does so after it changes a property it thinks is related. So the easiest way to do this is to add a Set Property control event that sets the property.
Note that for clarity of step 3's relevance, it can be useful to split this into two separate properties; set one in the powershell, reflect that into another in the Set Property control event, and have control conditions that read the latter.
I'm creating a GUI to enter in data then store into some variables to work with later. The problem I'm having is modifying the variables once the user clicks the OK button. I have the following code:
$button4 = New-Object system.windows.Forms.Button
$button4.Text = "button"
$button4.Width = 60
$button4.Height = 30
$button4.Add_Click({
$variable = "test"
})
$variable gets assigned with the Add_Click function but I'm not able to access it anywhere else. This makes sense as I read about Powershell scopes. But how am I supposed to access the information I set in there? I'm using this Microsoft guide as to build the GUI. In their example I should be able to return $x at the end of the script. But when I do it the variable isn't available.
I have a question about Outlook Rules in Powershell. I wrote some code that successfully stores any incoming e-mail from a certain sender to the deleted-items folder. I did this because when the mails enter the junk folder, the junk folder still has the counter token of mails, so in the end it will say I have 10-mails in the junk folder.
I want to avoid this by just throwing the incoming mails from that sender to the deleted-items folder and also marking the mail as "read" so that I don't see the clutter in the deleted items folder.
The question is really:
Can I add multiple actions to the same outlook rule in powershell? if so, how?
What is the syntax / code for the "run script" action?
My code so far:
$ol = New-Object -ComObject Outlook.Application
$ns = $ol.GetNamespace("MAPI")
$olFolders = "Microsoft.Office.Interop.Outlook.OlDefaultFolders"
$outlook = New-Object -ComObject outlook.application
$namespace = $Outlook.GetNameSpace("MAPI")
$inBox = $ns.GetDefaultFolder([Microsoft.Office.Interop.Outlook.OlDefaultFolders]::olFolderInbox)
$deleted = $ns.GetDefaultFolder([Microsoft.Office.Interop.Outlook.OlDefaultFolders]::olFolderDeletedItems)
$rules = $outlook.session.DefaultStore.GetRules()
$rule = $rules.create("Move mail: to DeletedItems", [Microsoft.Office.Interop.Outlook.OlRuleType]::olRuleReceive)
$rule_Address = $rule.Conditions.SenderAddress
$rule_Address.Enabled = $true
$rule_Address.Address = #("<Sender Address>")
$action = $rule.Actions.MoveToFolder
$action.Enabled = $true
[Microsoft.Office.Interop.Outlook._MoveOrCopyRuleAction].InvokeMember("Folder",[System.Reflection.BindingFlags]::SetProperty,$null, $action, $deleted)
$rules.Save()
This code works so far.
Please help.
Thanks!
Can I add multiple actions to the same outlook rule in powershell? if so, how?
Took a bit but I got a working test that uses multiple actions applied to a single rule. It is actually easy and you just need to repeat the steps you have already done and create a different action variable.
In my example, just showing the end of the code, I have added a action to display a message in the New Item Alert window.
...
$action = $rule.Actions.MoveToFolder
$action.Enabled = $true
$anotherAction = $rule.Actions.NewItemAlert
$anotherAction.Text = "I am awesome!"
$anotherAction.Enabled = $true
[Microsoft.Office.Interop.Outlook._MoveOrCopyRuleAction].InvokeMember("Folder",[System.Reflection.BindingFlags]::SetProperty,$null, $action, $deleted)
$rules.Save()
You quite possibly already tried something like this. If not there is an important reference for this that you need to be aware of.
What is the syntax / code for the "run script" action?
This is one of the actions you cannot programatically set as per this reference for Office 2007 or this one for Office 2010/2013. The tables are similar and rather large to include here but I will reference the one in your 2nd bullet.
Action : Start a script
Constant in olRuleActionType : olRuleActionRunScript
Supported when creating new rules programmatically? : No
Apply to olRuleReceive rules? : Yes
Apply to olRuleSend rules? : No
There are others as well where you are restricted. So you need to keep that in mind when you are making your rules.