My project is based in CMD. I am using a PS1 script for the desired effect of disabling the CMD windows X (close) button as I am doing DISM work with the cmd script and it will cause issues if the script is closed before it completes.
I am using the below PS code:
$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()
My current method is to ECHO the above code to a PS1 file from within my CMD script, then run and delete it, e.g.:
CALL :DISABLEX
PAUSE
EXIT
:DISABLEX
(
ECHO $code = @'
ECHO using System;
ECHO using System.Runtime.InteropServices;
ECHO namespace CloseButtonToggle {
ECHO internal static class WinAPI {
ECHO [DllImport^("kernel32.dll"^)]
ECHO internal static extern IntPtr GetConsoleWindow^(^);
ECHO [DllImport^("user32.dll"^)]
ECHO [return: MarshalAs^(UnmanagedType.Bool^)]
ECHO internal static extern bool DeleteMenu^(IntPtr hMenu,
ECHO uint uPosition, uint uFlags^);
ECHO [DllImport^("user32.dll"^)]
ECHO [return: MarshalAs^(UnmanagedType.Bool^)]
ECHO internal static extern bool DrawMenuBar^(IntPtr hWnd^);
ECHO [DllImport^("user32.dll"^)]
ECHO internal static extern IntPtr GetSystemMenu^(IntPtr hWnd,
ECHO [MarshalAs^(UnmanagedType.Bool^)]bool bRevert^);
ECHO const uint SC_CLOSE = 0xf060;
ECHO const uint MF_BYCOMMAND = 0;
ECHO internal static void ChangeCurrentState^(bool state^) {
ECHO IntPtr hMenu = GetSystemMenu^(GetConsoleWindow^(^), state^);
ECHO DeleteMenu^(hMenu, SC_CLOSE, MF_BYCOMMAND^);
ECHO DrawMenuBar^(GetConsoleWindow^(^)^);
ECHO }
ECHO }
ECHO public static class Status {
ECHO public static void Disable^(^) {
ECHO WinAPI.ChangeCurrentState^(false^);
ECHO }
ECHO }
ECHO }
ECHO '@
ECHO Add-Type $code
ECHO [CloseButtonToggle.Status]::Disable^(^)
)>"%~dp0disablex.ps1"
powershell -executionpolicy unrestricted -file "%~dp0disablex.ps1">>"%~dp0WimFix.log"
DEL "%~dp0disablex.ps1">>"%~dp0WimFix.log"
exit /b
It works, however I would prefer to just run it as a Powershell command from a single line instead of generating a ps1 file, e.g.:
powershell -nop -c 'command here; \"parsed with semicolons\"; but everything on one long line'
I'm not sure if this is possible, but after a few failed attempts to convert it to a command, I thought I'd ask for help before I give up and just continue the way I am already using it.