Hide title bar in powershell - powershell

In a Powershell environment, is it possible to hide the title bar or at least remove the close button?
I have some scripts that I'd prefer the user not "poke" at while they're running. I've considered running the script as hidden, but then the system will look like it's stuck for a minute or completely done when things are actually still going on under the covers.

You can disable the close button of the Windows console with this script at poshcode.org. However, the user can still close the console from the taskbar, and it doesn't work on console replacements such as ConEmu.
$code = #'
using System;
using System.Runtime.InteropServices;
namespace CloseButtonToggle {
internal static class WinAPI {
[DllImport("kernel32.dll")]
internal static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DeleteMenu(IntPtr hMenu,
uint uPosition, uint uFlags);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DrawMenuBar(IntPtr hWnd);
[DllImport("user32.dll")]
internal static extern IntPtr GetSystemMenu(IntPtr hWnd,
[MarshalAs(UnmanagedType.Bool)]bool bRevert);
const uint SC_CLOSE = 0xf060;
const uint MF_BYCOMMAND = 0;
internal static void ChangeCurrentState(bool state) {
IntPtr hMenu = GetSystemMenu(GetConsoleWindow(), state);
DeleteMenu(hMenu, SC_CLOSE, MF_BYCOMMAND);
DrawMenuBar(GetConsoleWindow());
}
}
public static class Status {
public static void Disable() {
WinAPI.ChangeCurrentState(false); //its 'true' if need to enable
}
}
}
'#
Add-Type $code
[CloseButtonToggle.Status]::Disable()

The only option that comes to mind is to hide the window that's running the script, then add this to your script:
start-process powershell.exe -ArgumentList '-noprofile -command "&{get-content c:\temp\log.txt -Wait}"'
and re-direct your script output to that file. They'll be able to see the script ouput in that window, but nothing they do in that window will have any effect on the script. At the end of the script, delete the log file and the log window will close.

You could use a Windows Form in PowerShell, and hide the control box:
[Void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$form = New-Object Windows.Forms.Form
$form.ControlBox = $false
$form.Text = "Test Form"
$Button = New-Object Windows.Forms.Button
Would look like:

Related

Disable SHIFT Stickykey shortcut

I'm trying to disable the popout that appears when pressing shift 5 times. Despite setting the HKCU\Control Panel\Accessibility\StickyKeys\Flags key to the 506 value in the registry, the change is not automatically applied.
I tried the code below in powershell, but to no avail:
$SKHA = Add-Type -MemberDefinition '[DllImport("user32.dll", EntryPoint = "SystemParametersInfo")] public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, uint vParam, uint init);' -Name 'Test' -PassThru;
$SKHA::SystemParametersInfo(0x003B, 0, 4, 0)
The documents I used were:
SystemParametersInfoA function (winuser.h)
STICKYKEYS structure (winuser.h)
Is there any way to disable this popout without the user having to manually disable or log off/restart the system after changing the registry?
Thank you in advance.
As explained by mklement0 you need to use the STICKYKEYS structure. Here is a working snippet based on following answer which first, read the current data then apply the parameter
$MethodDefinition = #'
[StructLayout(LayoutKind.Sequential)]
public struct STICKYKEYS
{
public uint cbSize;
public int dwFlags;
}
[DllImport("user32.dll")]
public static extern int SystemParametersInfo(int uiAction, int uiParam, out STICKYKEYS pvParam, int fWinIni);
'#
$get = 0x003A
$set = 0x003B
$WinApiVariable = Add-Type -MemberDefinition $MethodDefinition -Name 'Win32' -NameSpace '' -PassThru
$startupStickyKeys = New-Object -TypeName 'Win32+STICKYKEYS'
$startupStickyKeys.cbSize = [System.Runtime.InteropServices.Marshal]::SizeOf($startupStickyKeys)
[Win32]::SystemParametersInfo($get, [System.Runtime.InteropServices.Marshal]::SizeOf($startupStickyKeys), [ref]$startupStickyKeys, 0)
Write-Host "Current:"
$startupStickyKeys.dwFlags
Write-host "Set current flag to disabled (506)"
$startupStickyKeys.dwFlags = 506
[Win32]::SystemParametersInfo($set, [System.Runtime.InteropServices.Marshal]::SizeOf($startupStickyKeys), [ref]$startupStickyKeys, 0)
To complement Brice's helpful and effective solution (his answer deserves the accepted status):
Below is a more fully featured, PowerShell-friendly way to access and manage the sticky-keys feature: The code at the bottom defines type [demo.StickyKeys] with static members that allow you do to do the following:
# Get the active flags as a combination of friendly enum values; e.g.:
# AVAILABLE, HOTKEYACTIVE, CONFIRMHOTKEY, HOTKEYSOUND, INDICATOR, AUDIBLEFEEDBACK, TRISTATE, TWOKEYSOFF
[demo.StickyKeys]::ActiveFlags
# Query if the hotkey is currently enabled.
[demo.StickyKeys]::IsHotKeyEnabled
# Disable the hotkey *for the current session*
# Afterwards, [demo.StickyKeys]::ActiveFlags output no longer contains HOTKEYACTIVE
[demo.StickyKeys]::IsHotKeyEnabled = $false
# Disable the hotkey *persistently*.
[demo.StickyKeys]::EnableHotKey($false, $true)
# Show the flags in effect by default, on a pristine system.
[demo.StickyKeys]::DefaultFlags
Add-Member-based definition of [demo.StickyKeys]:
Add-Type -Namespace demo -Name StickyKeys -MemberDefinition '
// The WinAPI P/Invoke declaration for SystemParametersInfo()
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SystemParametersInfo(uint uiAction, uint uiParam, ref STICKYKEYS pvParam, uint fWinIni);
// The data structure used by SystemParametersInfo() to get and set StickyKey-related flags.
[StructLayout(LayoutKind.Sequential)]
struct STICKYKEYS {
public uint cbSize;
public UInt32 dwFlags;
}
// A helper enum that represents a given combination of flags as a list of friendly symbolic identifiers.
[Flags]
public enum StickyKeyFlags : uint { // Prefix SKF_ omitted from the value names.
AUDIBLEFEEDBACK = 0x00000040,
AVAILABLE = 0x00000002,
CONFIRMHOTKEY = 0x00000008,
HOTKEYACTIVE = 0x00000004,
HOTKEYSOUND = 0x00000010,
INDICATOR = 0x00000020,
STICKYKEYSON = 0x00000001,
TRISTATE = 0x00000080,
TWOKEYSOFF = 0x00000100,
LALTLATCHED = 0x10000000,
LCTLLATCHED = 0x04000000,
LSHIFTLATCHED = 0x01000000,
RALTLATCHED = 0x20000000,
RCTLLATCHED = 0x08000000,
RSHIFTLATCHED = 0x02000000,
LALTLOCKED = 0x00100000,
LCTLLOCKED = 0x00040000,
LSHIFTLOCKED = 0x00010000,
RALTLOCKED = 0x00200000,
RCTLLOCKED = 0x00080000,
RSHIFTLOCKED = 0x00020000,
LWINLATCHED = 0x40000000,
RWINLATCHED = 0x80000000,
LWINLOCKED = 0x00400000,
RWINLOCKED = 0x00800000
}
// Gets or set the enabled status of the sticky-keys hotkey.
// Note: Setting is invariably *non-persistent*.
// Use the .EnableHotKey() method for optional persistence.
public static bool IsHotKeyEnabled {
get { return (GetFlags() & StickyKeyFlags.HOTKEYACTIVE) != 0u; }
set { EnableHotKey(value, false); }
}
// Gets or set the active sticky-keys flags.
// Note: Setting is invariably *non-persistent*.
// Use the .SetFlags() method for optional persistence.
public static StickyKeyFlags ActiveFlags {
get { return GetFlags(); }
set { SetFlags(value, false); }
}
// The flags in effect on a pristine system.
public static StickyKeyFlags DefaultFlags {
get { return StickyKeyFlags.AVAILABLE | StickyKeyFlags.HOTKEYACTIVE | StickyKeyFlags.CONFIRMHOTKEY | StickyKeyFlags.HOTKEYSOUND | StickyKeyFlags.INDICATOR | StickyKeyFlags.AUDIBLEFEEDBACK | StickyKeyFlags.TRISTATE | StickyKeyFlags.TWOKEYSOFF; } // 510u
}
// Enable or disable the stick-keys hotkey, optionally persistently.
public static void EnableHotKey(bool enable = true, bool persist = false) {
var skInfo = new STICKYKEYS();
skInfo.cbSize = (uint)Marshal.SizeOf(skInfo);
var flags = GetFlags();
SetFlags((enable ? flags | StickyKeyFlags.HOTKEYACTIVE : flags & ~StickyKeyFlags.HOTKEYACTIVE), persist);
}
// Get the currently active flags; exposed via the static .ActiveFlags property only.
private static StickyKeyFlags GetFlags() {
var skInfo = new STICKYKEYS();
skInfo.cbSize = (uint)Marshal.SizeOf(skInfo);
if (!SystemParametersInfo(0x003a /* SPI_GETSTICKYKEYS */, 0, ref skInfo, 0))
throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
return (StickyKeyFlags)skInfo.dwFlags;
}
// Set the active flags *in full*, i.e. the value must combine all flags that should be set.
// Best to start from the current combination of flags reported by .ActiveFlags.
public static void SetFlags(StickyKeyFlags flags, bool persist = false) {
var skInfo = new STICKYKEYS();
skInfo.cbSize = (uint)Marshal.SizeOf(skInfo);
skInfo.dwFlags = (UInt32)flags;
if (!SystemParametersInfo(0x003b /* SPI_SETSTICKYKEYS */, 0, ref skInfo, persist ? 1u : 0u))
throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
}
'

Installing 'printer forms' using powershell without prnadmin.dll?

Due to the fact that the latest security updates coming from Microsoft have turned the Jet OLEDB Provider unusable I have to rewrite several elder VBScripts.
Is there a better way to install printer forms on Windows Server 2008 R2 and 2012 R2 then calling the outdated prnadmin.dll via regsvr32/COM/VBscript?
prnadmin.dll was first introduced with Windows Server 2000 Resource Kit and I would like to migrate the whole script to PowerShell.
Unfortunately I can't find any usefull PowerShell cmdlet within the module PrintManagement. So how can I add custom forms to the Printer Server using PSH?
The programmatic way to add a system form definition is to call AddForm. There is not a good wrapper for this call that I am aware of, but P/Invoking to AddForm works. I wrote a quick wrapper and posted it on GitHub.
Example using the wrapper:
Windows PowerShell
Copyright (C) 2016 Microsoft Corporation. All rights reserved.
PS C:\Drop> Import-Module .\PowershellPrinterFormsModule.dll
PS C:\Drop> Add-SystemForm -Name 'Demo User Form try 1' -Units Inches -Size '4,5'
PS C:\Drop> Add-SystemForm -Name 'Demo User Form try 2' -Units Inches -Size '4,5' -Margin '0.25,0.5'
PS C:\Drop> Add-SystemForm -Name 'Demo User Form try 3' -Units Millimeters -Size '80,50' -Margin '10,10,0,0'
Actual P/Invoke call to AddForm:
SafePrinterHandle hServer;
if (!OpenPrinter(null, out hServer, IntPtr.Zero))
{
throw new Win32Exception();
}
using (hServer)
{
var form = new FORM_INFO_1()
{
Flags = 0,
Name = this.Name,
Size = (SIZEL)pageSize,
ImageableArea = (RECTL)imageableArea
};
if (!AddForm(hServer, 1, ref form))
{
throw new Win32Exception();
}
}
internal static class NativeMethods
{
#region Constants
internal const int ERROR_INSUFFICIENT_BUFFER = 0x7A;
#endregion
#region winspool.drv
private const string Winspool = "winspool.drv";
[DllImport(Winspool, SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool OpenPrinter(string szPrinter, out SafePrinterHandle hPrinter, IntPtr pd);
public static SafePrinterHandle OpenPrinter(string szPrinter)
{
SafePrinterHandle hServer;
if (!OpenPrinter(null, out hServer, IntPtr.Zero))
{
throw new Win32Exception();
}
return hServer;
}
[DllImport(Winspool, SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool ClosePrinter(IntPtr hPrinter);
[DllImport(Winspool, SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool EnumForms(SafePrinterHandle hPrinter, int level, IntPtr pBuf, int cbBuf, out int pcbNeeded, out int pcReturned);
[DllImport(Winspool, SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool AddForm(SafePrinterHandle hPrinter, int level, [In] ref FORM_INFO_1 form);
[DllImport(Winspool, SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool DeleteForm(SafePrinterHandle hPrinter, string formName);
#endregion
#region Structs
[StructLayout(LayoutKind.Sequential)]
internal struct FORM_INFO_1
{
public int Flags;
[MarshalAs(UnmanagedType.LPWStr)]
public string Name;
public SIZEL Size;
public RECTL ImageableArea;
}
[StructLayout(LayoutKind.Sequential)]
internal struct SIZEL
{
public int cx;
public int cy;
public static explicit operator SIZEL(Size r)
=> new SIZEL { cx = (int)r.Width, cy = (int)r.Height };
public static explicit operator Size(SIZEL r)
=> new Size(r.cx, r.cy);
}
[StructLayout(LayoutKind.Sequential)]
internal struct RECTL
{
public int left;
public int top;
public int right;
public int bottom;
public static explicit operator RECTL(Rect r)
=> new RECTL { left = (int)r.Left, top = (int)r.Top, right = (int)r.Right, bottom = (int)r.Bottom };
public static explicit operator Rect(RECTL r)
=> new Rect(new Point(r.left, r.top), new Point(r.right, r.bottom));
}
#endregion
}
internal sealed class SafePrinterHandle : SafeHandleZeroOrMinusOneIsInvalid
{
public SafePrinterHandle()
: base(true)
{
}
protected override bool ReleaseHandle()
{
return NativeMethods.ClosePrinter(handle);
}
}

Open NotePad in mys form on top

Can you hel me please to open an application (notepad) on top my form ?
private void button1_Click(object sender, EventArgs e)
{
Process N = new Process.Start(#"notepad.exe");
N.ShowDialog(this);
}
I try this but is not correctly.
So, how can i open notepad.exe or word.exe on top my form as ShowDialog please ?
Cordialy
Use SetForegroundWindow function.
Declare using System.Runtime.InteropServices; and use
[DllImport("user32.dll")]
static extern bool SetForegroundWindow(IntPtr hWnd);
private void SetNotepadAsForegroundApp()
{
Process N = new Process.Start(#"notepad.exe");
SetForegroundWindow(N.MainWindowHandle);
}

Capture keypress in Unity when Unity doesn't have the input focus

I need Unity to capture ALL key presses, even if Unity doesn't have the focus.
I've tried to use:
Input.KeyPress()
But this seems to only work if Unity has the focus of the user's input. I need it to work when it doesn't have the focus, such as when I'm looking at / working with another Windows program.
PS: I already turned on the "Run in Background" option in player preferences.
This is totally possible! Although, there is no way to do it by using only the tools in-built into Unity3D. You will have to use native libraries to do that.
The example below hooks the hook chain with a hook type of WH_KEYBOARD, which corresponds to a message-level keyboard hook. You can read more on SetWindowsHookEx and different types [ here][1].
You can check the parameters that are being received on hooking such a message type (WH_KEYBOARD) [here][2]
using UnityEngine;
using System;
using System.Collections;
using System.Runtime.InteropServices;
public class KBHooks : MonoBehaviour
{
[DllImport("user32")]
protected static extern IntPtr SetWindowsHookEx(
HookType code, HookProc func, IntPtr hInstance, int threadID);
[DllImport("user32")]
protected static extern int UnhookWindowsHookEx(
IntPtr hhook);
[DllImport("user32")]
protected static extern int CallNextHookEx(
IntPtr hhook, int code, IntPtr wParam, IntPtr lParam);
// Hook types. To hook the keyboard we only need WH_KEYBOARD
protected enum HookType : int
{
WH_JOURNALRECORD = 0,
WH_JOURNALPLAYBACK = 1,
WH_KEYBOARD = 2,
WH_GETMESSAGE = 3,
WH_CALLWNDPROC = 4,
WH_CBT = 5,
WH_SYSMSGFILTER = 6,
WH_MOUSE = 7,
WH_HARDWARE = 8,
WH_DEBUG = 9,
WH_SHELL = 10,
WH_FOREGROUNDIDLE = 11,
WH_CALLWNDPROCRET = 12,
WH_KEYBOARD_LL = 13,
WH_MOUSE_LL = 14
}
protected IntPtr m_hhook = IntPtr.Zero;
protected HookType m_hookType = HookType.WH_KEYBOARD;
protected delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);
//We install the hook and hold on to the hook handle.
//The handle will be need to unhook.
protected bool Install(HookProc cbFunc)
{
if (m_hhook == IntPtr.Zero)
m_hhook = SetWindowsHookEx(
m_hookType,
cbFunc,
IntPtr.Zero,
(int)AppDomain.GetCurrentThreadId());
if (m_hhook == IntPtr.Zero)
return false;
return true;
}
protected void Uninstall()
{
if (m_hhook != IntPtr.Zero)
{
UnhookWindowsHookEx(m_hhook);
m_hhook = IntPtr.Zero;
}
}
protected int CoreHookProc(int code, IntPtr wParam, IntPtr lParam)
{
if (code < 0)
return CallNextHookEx(m_hhook, code, wParam, lParam);
Debug.Log(
"hook code =" + code.ToString() +
" lparam=" + lParam.ToString() +
" wparam=" + wParam.ToString());
// Yield to the next hook in the chain
return CallNextHookEx(m_hhook, code, wParam, lParam);
}
// Use this for initialization
void Start()
{
Debug.Log("install hook");
Install(CoreHookProc);
}
void OnDisable()
{
Debug.Log("Uninstall hook");
Uninstall();
}
}
This example comes from [this blog][3].
Such a way of hooking will only work on Windows systems. If you need to make a separate hook on OS X or Linux you would need to do it in a native way in that operating system.
I cannot post more than 1 link because I lack reputation on SO. I hope one of the mods will edit my post accordingly.
[1]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx
[2]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms644984(v=vs.85).aspx
[3]: http://phardera.blogspot.com.es/2010/12/windows-hooks-in-unity3d.html
I've assembled a Unity package based on the #boris-makogonyuk answer with some usability improvements.
The package is available on GitHub (MIT license): https://github.com/Elringus/UnityRawInput
You can use it as follows:
Include package namespace.
using UnityRawInput;
Initialize the input service to start processing native input messages.
RawKeyInput.Start();
Optinally, you can specify whether input messages should be handled when the application is not in focus (disabled by default).
var workInBackground = true;
RawKeyInput.Start(workInBackground);
Add listeners for the input events.
RawKeyInput.OnKeyUp += HandleKeyUp;
RawKeyInput.OnKeyDown += HandleKeyDown;
private void HandleKeyUp (RawKey key) { ... }
private void HandleKeyDown (RawKey key) { ... }
You can also check whether specific key is currently pressed.
if (RawKeyInput.IsKeyDown(key)) { ... }
You can stop the service at any time.
RawKeyInput.Stop();
Don't forget to remove listeners when you no longer need them.
private void OnDisable ()
{
RawKeyInput.OnKeyUp -= HandleKeyUp;
RawKeyInput.OnKeyDown -= HandleKeyDown;
}

Pathing in Powershell

My corrent Code is this
Add-Type #"
using System;
using System.Runtime.InteropServices;
using Microsoft.Win32;
namespace Wallpaper
{
public enum Style : int
{
Tile, Center, Stretch, NoChange
}
public class Setter {
public const int SetDesktopWallpaper = 20;
public const int UpdateIniFile = 0x01;
public const int SendWinIniChange = 0x02;
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern int SystemParametersInfo (int uAction, int uParam, string lpvParam, int fuWinIni);
public static void SetWallpaper ( string path, Wallpaper.Style style ) {
SystemParametersInfo( SetDesktopWallpaper, 0, path, UpdateIniFile | SendWinIniChange );
RegistryKey key = Registry.CurrentUser.OpenSubKey("Control Panel\\Desktop", true);
switch( style )
{
case Style.Stretch :
key.SetValue(#"WallpaperStyle", "2") ;
key.SetValue(#"TileWallpaper", "0") ;
break;
case Style.Center :
key.SetValue(#"WallpaperStyle", "1") ;
key.SetValue(#"TileWallpaper", "0") ;
break;
case Style.Tile :
key.SetValue(#"WallpaperStyle", "1") ;
key.SetValue(#"TileWallpaper", "1") ;
break;
case Style.NoChange :
break;
}
key.Close();
}
}
}
"#
[Wallpaper.Setter]::SetWallpaper( 'C:\Users\God\Desktop\Test\God.bmp' , 0 )
Ok, the Script comes with the God.bmp, which are ALWAYS in the same
directory (Folder Test on Desktop right now), I tried to replace the Path "C:\Users\God\Desktop\Test\God.bmp" With ".\God.bmp" which should work but it doesent seem to work I tried "./God.bmp" aswell but the Background turns black and not into the God picture. So how can I make it work because normally .\ makes it use the current Path as far as i know
Probably Windows doesn't handle relative paths to wallpaper in registry. If you'd like to use relative paths in your code, you have to expand them to full paths before writing to the registry:
$FullPath = Join-Path -Path (Get-Location -PSProvider FileSystem).Path -ChildPath 'God.bmp'
[Wallpaper.Setter]::SetWallpaper($FullPath , 0)
PowerShell will try to find .\God.bmp relative to where the caller is, not where the executing script exists in the filesystem.
Try this simple example:
# C:\scripts\relativepath.ps1
[System.IO.Path]::GetFullPath(".\god.bmp")
If you open a prompt and cd to C:\scripts, it works as expected:
PS C:\scripts> .\relativepath.ps1
C:\scripts\god.bmp
But if you change to another directory:
PS C:\somewhere\else> C:\scripts\relativepath.ps1
C:\somewhere\else\god.bmp
If you want the full path relative to where the executing script is located, use the $PSScriptRoot automatic variable:
$WallPaperPath = Join-Path -Path $PSScriptRoot -ChildPath "god.bmp"