I accidently did this command in powershell windows 10 and my mouse buttons are swapped.
rundll32.exe user32.dll,SwapMouseButton
How to fix it?
I was testing this command like in a youtube shorts. But I don't know how to fix it.
SwapMouseButton is a native Windows API function that can be called from PowerShell using P/Invoke.
Add the P/Invoke definition using Add-Type and then call the API function, passing $false to revert to normal mouse button behavior:
# Add the P/Invoke API definition
$api = Add-Type -PassThru -Namespace Win32 -Name Win32SwapMouseButton -MemberDefinition #'
[DllImport("user32.dll")]
public static extern bool SwapMouseButton(bool fSwap);
'#
# Call the API to restore normal mouse button behavior
$api::SwapMouseButton($false)
Likewise, you can pass $true to swap mouse buttons again, without having to resort to the rundll32 hack.
Related
I am creating a program in GoLang that has an optional console window. During normal operation, the window will be completely hidden (including the task bar) and I the user will interact with it through the system tray. I want to have an option that shows / hides the console window when the user presses a button in the tray. I've done this before in C# by doing this:
using System.Runtime.InteropServices;
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
const int SW_HIDE = 0;
const int SW_SHOW = 5;
var handle = GetConsoleWindow();
// Hide
ShowWindow(handle, SW_HIDE);
// Show
ShowWindow(handle, SW_SHOW);
In order to do this in Go, I used this package: https://github.com/lxn/win. This package is a WinAPI wrapper for Go that will let me use all the same commands. Here is the code I used to do the same thing as the C# code above:
win.ShowWindow(win.GetConsoleWindow(), win.SW_SHOW)
Now this actually worked perfectly as intended on Windows 10, which does NOT use Windows Terminal by default. I'm running Windows 11 which does use Windows terminal, so I assume that's the reason this is not hiding. Instead, it simply minimizes the window instead of hiding it. Is it possible for me to either force my Go program to NOT use Windows Terminal or preferably get the Windows Terminal to hide like it does with Command Prompt?
Thank you for any help
EDIT: In Windows Terminal, you can go to the settings and set the default terminal application to "Windows Console Host" and that will use command prompt, but this is computer wide. This does fix the problem though. I would like this to just be for my program alone, so the problem still stands, but just making note of it.
I am working on a Wix installer that creates a SymbolicLink inside a custom action. The custom action is written in C#. It is creating the SymbolicLink by calling the CreateSymbolicLink Win32 API. On Windows 10, the call works perfectly. On Windows 7 it fails. If I call Marshal.GetLastWin32Error(), it returns an error code of 997, which is ERROR_IO_PENDING
Here is the line of code the calls the API:
var result = CreateSymbolicLink(pathToCreateLink, installDir, SymbolicLinkFlags.Directory | SymbolicLinkFlags.UnprivilegedCreate);
if(!result)
{
_logger.Log($"Win32 Error Code: {Marshal.GetLastWin32Error()}");
}
Here is the Dll Import:
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool CreateSymbolicLink( string lpSymlinkFileName, string pTargetFileName, SymbolicLinkFlags dwFlags);
The custom action is invoked with Execute set to "deferred" and Impersonate set to "no".
If I put the line of C# code in a console application, it functions correctly (even on Windows 7). So there is something about how the code is being called in the installer that is causing the error.
Part of my problem is that I can find very little information on the error code, so I can't be sure what to try to fix it.
A kind of confirmation can be found in wixsharp code. They encountered this problem and could not surpass it.
https://github.com/oleg-shilo/wixsharp/blob/master/Source/src/WixSharp/ResilientPackage.cs
The w/a I implemented in my installer is repeating symbolic links creation via cmd tool mklink and if it fails as well, just copy files.
MSI packages run as System TrustedInstaller, and on Windows 7 that user does not have access to create SymLinks with the default Local Security Policy.
I fixed it by using junctions instead (mklink /j), but that only works for folders.
I know a little bit about programming. I wanted to know if there was a way to get a message box pop up every time someone plugs in a usb drive saying something like "is this an approved device?" . I was wondering if there was a way to insert this in a registry entry or something? Or maybe you have an idea on how to do this.
You can detect USB device inserts using the Win32_DeviceChangeEvent WMI event. There are other ways, like WM_DEVICECHANGE, but PowerShell already knowns how to handle WMI Events.
$query = "SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2"
Register-WMIEvent -Query $query -Action { Write-Host "A device has been inserted"}
Source: here and here
Showing GUI messages could be done using WPF or WinForms.
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.MessageBox]::Show('Message', 'Title')
Source: here and here
Does anyone have an example of building a complete WIN32 Windows app as a dll?
I'd like to export a function, call it via rundll32, and have a complete Windows app with decorations, a menu, accelerators, and everything pop up.
I know about the calling convention for rundll32:
void CALLBACK TestEntryW(HWND hWnd, HINSTANCE hInst, LPWSTR pszCmdLine, int nCmdShow);
I can pull up a MessageBox from that function via the command: rundll32.exe test3.dll,TestEntry other params and args
I can load resources from my DLL by getting the DLL's handle via GetModuleHandle("test3.dll") and using that as hInst in my LoadString calls. That seems to be working for LoadIcon and LoadAccelerators as well, but I don't have working yet (baby steps..).
I can register a Windows class via RegisterClassEx using those strings and icons, but I must use the parent hInst or I get ERROR_CANNOT_FIND_WND_CLASS when calling CreateWindow. I think that's expected.
However, When I try to use that class in CreateWindow, it returns NULL, and so does GetLastError.
I can retrieve the window class of the hInst passed from rundll32 using GetWindowsLong(hWnd, GWL_ATOM). Using that for lpClassName, I can pull up a decorated window minus menus and accelerators, but it's a bit funky, as rundll's window class is normally only used for its message queue. I tried subclassing the window using SetWindowsLong to replace the WndProc and calling CallWindowProc instead of DefWindowProc in my dll's WndProc.
I'm hampered by being unable to debug it in MSVC++ 2010 Express. I replaced the project's command and command arguments with the appropriate entries so it launches it correctly, but it complains about no debugging info for rundll32.exe, and breakpoints etc. don't work.
Any ideas? Am I on the right track?
Is there a command I can put into a Windows XP .bat file to bring the command shell to the front?
nircmd will do this, though it involves a little scripting.
nircmd win activate "titleofwindow"
You basically need to know the title of the cmd window you are executing (you can set this via the TITLE command in windows)
thus:
TITLE %SOME_UNIQUE_VALE%
nircmd win activate %SOME_UNIQUE_VALE%
should do the trick.
Note some malware tools make use of the NirCmd executable (it requires no deployment and is very powerful); this may cause you problems.
Another way to get the cmd prompt window to show in front is by ending file1.bat with a command to call a second file2.bat file, followed by an exit command.
EXAMPLE using
file1.bat
....
[your code here]
start C:\file2.bat
exit
This closes file1.bat and opens a second .bat file where you can continue with your code. This second .bat command prompt will open in front of other windows
I had a similar problem and I had to develop a simple C# console application that brings to front a Window. The windows is selected using the window title pass as argument.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
class Program
{
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(String lpClassName, String lpWindowName);
[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("User32.dll")]
private static extern bool IsIconic(IntPtr handle);
[DllImport("User32.dll")]
private static extern bool ShowWindow(IntPtr handle, int nCmdShow);
const int SW_RESTORE = 9;
public static void bringToFront(string title)
{
// Get a handle to the Calculator application.
IntPtr handle = FindWindow(null, title);
// Verify that Calculator is a running process.
if (handle == IntPtr.Zero)
{
return;
}
if (IsIconic(handle))
{
ShowWindow(handle, SW_RESTORE);
}
Console.WriteLine("Founded ");
SetForegroundWindow(handle);
}
static void Main(string[] args)
{
if (args.Length > 0)
bringToFront(args[0]);
else
Console.WriteLine("specify program window title");
}
}
}
the code of my batch script is then something similar to
tasklist /FI "IMAGENAME eq program.exe" | find "program.exe"
if errorlevel 1 (program.exe) else (BringToFront.exe "Program Window Title")
From a batch file, no. If you want to activate a window you have to use SetActiveWindow(). If you don't want to get dirty with windows programming but still want to activate windows and simple stuff like that, I highly recommend checking out Autoit. You could always call this program from your batchfile to have it do the task.
CMDOW is also useful for this and for other DOS programming tasks where a little added functionality is needed. Simple to use and well documented. Mind your anti-virus program, though - CMDOW has the ability to hide windows which your anti-virus program will pick up as a possible virus. Just add it to your exception list. CMDOW is completely portable, is definitely NOT a virus and if you have any concerns about it being used by a third party to hide something, simply tuck it away in some non obvious folder somewhere.
Try with focusOn.bat
call focusOn.bat "My Title"
Another quick way to switch to a window by name is via Ctrl+Shift+Esc, which opens Task Manager. Then just type the first few letters of the windows title to select the process, then hit Enter.