winapiexec

winapiexec is a small tool that allows you to run WinAPI functions through command line parameters.

The syntax is:
winapiexec.exe library.dll@FunctionName 123 unicode_text "a space"

If you don’t specify a library or use “k”, kernel32.dll is used.
If you specify “u” as a library, user32.dll is used.

Numbers are detected automatically, you also can use hex numbers (like 0xFE) and use the minus sign (e.g. -5).
Strings are unicode by default.

You can use special prefixes to specify parameter types:
$s:ascii – an ascii string
$u:unicode – a unicode string (it’s unicode by default, but you can use it to force numbers as strings)
$b:1024 – a zero-bytes buffer with the size you specify, in bytes
$$:1 – a reference to another parameter, you can also use $$:0 for the program’s name (argv[0])
$a:1,$u:2,str – an array of parameters, divided by commas. you can use all the perfixes here
$$:3@2 – a reference to an item in an array of parameters

While referencing to another parameter, note that they are processed by the order of execution, which means there’s no point to reference to a parameter right to the referencing one.
Also note that after a function is run, it’s first parameter (like library.dll@FunctionName) is replaced with the return value.

You can execute multiple WinAPI functions, one after the other, using a comma:
winapiexec.exe library.dll@FunctionName1 123 , library.dll@FunctionName2 456
You can also execute functions nested, using brackets:
winapiexec.exe library.dll@FunctionName1 ( library.dll@FunctionName2 456 )
While the return value of the internal function is passed as a parameter to the external function.

Download:
rar winapiexec.rar (2.98 KB)

Here are some examples of what you can do:

Display temp path:
winapiexec.exe GetTempPathW 260 $b:520 , u@MessageBoxW 0 $$:3 $$:0 0x40

Greetings:
winapiexec.exe advapi32.dll@GetUserNameW $b:65534 $a:32767 , u@wsprintfW $b:2050 "Hello %s from %s" $$:2 $$:0 , u@MessageBoxW 0 $$:6 ... 0

Hide the taskbar for half a second, then show it:
winapiexec.exe u@ShowWindow ( u@FindWindowW Shell_TrayWnd 0 ) 0 , Sleep 500 , u@ShowWindow $$:3 5

Run calculator for a second, then terminate it:
winapiexec.exe CreateProcessW 0 calc 0 0 0 0x20 0 0 $a:0x44,,,,,,,,,,,,,,,, $b:16 , Sleep 1000 , TerminateProcess $$:11@0 0

Show a messagebox and then create a new instance of the process:
winapiexec.exe u@MessageBoxW 0 Hello! :) 0 , CreateProcessW $$:0 ( GetCommandLineW ) 0 0 0 0x20 0 0 $a:0x44,,,,,,,,,,,,,,,, $b:16

Eject your cdrom :)
winapiexec.exe winmm.dll@mciSendStringW "open cdaudio" 0 0 0 , winmm.dll@mciSendStringW "set cdaudio door open" 0 0 0 , winmm.dll@mciSendStringW "close cdaudio" 0 0 0

…and some more useful stuff

Turn off and on monitor:
winapiexec.exe u@SendMessageW 0xFFFF 0x112 0xF170 2
winapiexec.exe u@SendMessageW 0xFFFF 0x112 0xF170 -1

Display the Start menu:
winapiexec.exe u@SendMessageW ( u@FindWindowW Shell_TrayWnd 0 ) 0x111 305 0
Run task manager:
winapiexec.exe u@SendMessageW ( u@FindWindowW Shell_TrayWnd 0 ) 0x111 420 0
More tricks like that:
http://www.codeproject.com/KB/miscctrl/Taskbar_Manipulation.aspx

Posted in Releases, Software by RaMMicHaeL at January 8th, 2011.
Tags:

48 Responses to “winapiexec”

  1. xpclient says:

    What would be the command to show the Quick launch? :)

  2. mike says:

    I have the clock hidden in the system tray (windows 7) so I just want to know if there is a way to open the clock window (ex: http://windows7themes.net/pics/windows-7-taskbar-clock.jpg) via command line?

    Thanks in advance and keep up the good work

  3. Anonymous says:

    Does winapiexec allow sending an e-mail with custom message text and attachments via the default e-mail client?
    A while ago I tried to find a way to modify the default text Windows forces upon the user (“Your message is ready to be sent with the following file or link attachments:”) but I think I gave up.
    I think I was trying to take advantage of Windows’ simple image resizing interface. There may be other ways to achieve this (AutoHotkey), though.

  4. Mark Hopkins says:

    I took the UNIX/POSIX language BC, a while back, and upgraded it practically into a C interpreter, called C-BC. I can take some of that code and language design, remake it into a command shell and adapt it into your program’s source code, if you wish.

    C-BC has the “include” directive, so it has the ability to load modules containing pre-defined routines as well.

    The proposed extension would be invoked by just calling “winapiexec.exe” with no command-line arguments. Alternatively, it might be invoked with an argument like $@ to start the shell in mid-command. Or, the modified program might be given a different name, such as wsh.exe, mssh.exe or winsh.exe.

    The main question on my mind is how much of C-BC’s facilities to keep intact. I’d probably take out or replace its data types (extended precision numbers, strings, arrays and pointers) with a simpler system of types (bytes, words, strings, arrays). On the other hand, the temptation is strong to go into the opposite direction and throw in the whole type system of a modern language: polymorphism, abstract types, classes and all.

    The other question, of course, is what unforeseen consequences there will be in combining a command-line windows API processor with a programming language interpreter.

    If you’re interested, send an e-mail note.

    • RaMMicHaeL says:

      Hi Mark,

      1995, huh? I was 4 back then :P

      I can take some of that code and language design, remake it into a command shell and adapt it into your program’s source code, if you wish.

      If I wish? I won’t mind.

      the temptation is strong to go into the opposite direction and throw in the whole type system of a modern language: polymorphism, abstract types, classes and all.

      Polymorphism and classes in a command shell? o_O

      Do I get it right, that by command shell you mean something like cmd.exe? I’m not very familiar with UNIX/POSIX OSes, but from what I understand, you want to extend the syntax to include C-BC functions, to allow e.g. to create a while loop from command line?

      A couple of examples of what would it look like or what would it be able to do will help me get the idea better.

      Regards.

      • Mark says:

        You were 4? That’s a pretty good memory. Though I have to admit, my earliest memory was some time around the age of 3-6 months.

        But C-BC was put out in October 1993, not 1995. The source is 4000 lines and I was always intending on putting threaded multitasking directly in C-BC. This would yield a vastly simplified wrapper for WinAPI, if it is properly integrated with it. It goes the other way too. It’s easier to put multithreading in the language if it can deferred to native OS API’s. The 2010 extensions to C/C++ may also help, though they’re 20 years overdue.

        I’ll back away a little from all this to think more about everything — especially with Windows and even PC’s quickly falling out of date.

        But yes, in answer to your question: shells do loops, branches and other control flow as a matter of course. Take a look at the page on C-shell at http://en.wikipedia.org/wiki/C_shell and there are similar features are in Window shell, too … http://en.wikipedia.org/wiki/Cmd.exe and even in DOS… http://en.wikipedia.org/wiki/COMMAND.COM which is what Windows shell was up until Windows XP.

        But nobody pulls out the Windows API up front. I also found this comparison for command line shells:
        http://en.wikipedia.org/wiki/Comparison_of_command_shells

        Scripting languages, do control flow too, like these:
        Perl: http://en.wikipedia.org/wiki/Perl
        Python: http://en.wikipedia.org/wiki/Python_(programming_language)

        both of which has more contemporary systems of data types built into them.

        But after thinking about all this, it might actually be better to focus on mobile systems (or even Linux), rather than Windows.

        • RaMMicHaeL says:

          You were 4? That’s a pretty good memory. Though I have to admit, my earliest memory was some time around the age of 3-6 months.

          I found the article in Google, and just wanted to say it was written a long time ago. I surely wasn’t interested in programming when I was 4.

          Anyway, winapiexec is a tiny <4 KB tool that I wrote for no specific purpose. The nice thing about it is that you can create a shortcut that would do some unique stuff, e.g. showing the system clock.

          I’ve never used it in a shell script, and I assume that if a single command line for winapiexec is not enough, it might be worth to just write the code in e.g. C, or even in a scripting language such as Lua (which appears to support calling WinAPI functions).

  5. Jegimeco says:

    Please a command to enable/disable windows shadows in Windows 7 x64 on the fly. Thanks.

  6. Bizarre™ says:

    Does anyone know how to decommit private bytes for a specific process using this program?

  7. Aquilai says:

    Avast Anti-Virus blocked my download before it started stating winapiexec is a suspicious Win32:MDE-B [Susp] item. Could you contact Avast to have it allowed?

  8. Iron Slippers says:

    А можно этой чудо-программкой запустить команду “Minimize all”, ну и соответственно обратно?

    • RaMMicHaeL says:

      “Minimize all”:
      winapiexec.exe u@SendMessageW ( u@FindWindowW Shell_TrayWnd 0 ) 0x111 419 0

      Обратно оно не работает. Для этого можно использовать “Show desktop”:
      winapiexec.exe u@SendMessageW ( u@FindWindowW Shell_TrayWnd 0 ) 0x111 407 0

      • IronSlippers says:

        Спасибо. До этого у меня вот такая веселая конструкция была:
        chp.exe —> cmdow.exe —> ярлык с командой
        =)

  9. Sleeping_Dragon says:

    Is there a command for this tool to do manual garbage collection? If so, can it also be done on a specific process?

  10. YouCrazyKids says:

    Hi there, I’m attempting to use winapiexec through a batch file to read the system idle time (using the User32.dll function GetLastInputInfo), but don’t understand how it would be expressed in the batch file. Is it even possible using winapiexec? My attempt was:

    winapiexec User32.dll@GetLastInputInfo(LastInputInfo)

    The GetLastInputInfo function description from Microsoft is really cryptic. Any help you can give would be appreciated. Thanks!

    • RaMMicHaeL says:

      Hi,

      GetLastInputInfo is a bit complicated, as it expects a reference of a structure.

      Here’s an example of how it can be done:

      winapiexec.exe u@GetLastInputInfo $a:8,0 , InterlockedExchange $b:4 $$:2@1 , InterlockedExchange $$:5 0
      

      According to the documentation, this will return “The tick count when the last input event was received.”.

      The current tick count can be retrieved with the GetTickCount function:

      winapiexec.exe GetTickCount
      
  11. highend says:

    Hi,

    would it be possible to use SHGetKnownFolderPath from shell32.dll to return the real folder if we supply the GUID?

    E.g.: “{4BD8D571-6D19-48D3-BE97-422220080E43}”
    which is the GUID for “My Music”. Many of the new GUIDs (SkyDrive / OneDrive on Win 8.1) aren’t present in the User Shell Folder (registry path) so SHGetKnownFolderPath is the the only viable option ;)

    • RaMMicHaeL says:

      Hi,

      Yeah, that’s possible:

      winapiexec.exe shell32.dll@SHGetKnownFolderPath $a:0x4BD8D571,0x48D36D19,0x224297BE,0x430E0820 0 0 $b:4 , u@MessageBoxW 0 $$:5@0 $$:0 0x40

      The GUID format is not straightforward, so I wrote a small conversion script:
      http://ideone.com/nkZhtb

      Click on fork, replace the GUID, and run it right in the browser :)

      <?php
      
      $guid = '{4BD8D571-6D19-48D3-BE97-422220080E43}';
      
      $p = '#{?([0-9A-F]{8})-'.
      	'([0-9A-F]{4})-'.
      	'([0-9A-F]{4})-'.
      	'([0-9A-F]{2})([0-9A-F]{2})-'.
      	'([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})}?#';
      preg_match($p, strtoupper($guid), $m);
      echo sprintf('0x%s,0x%s%s,0x%s%s%s%s,0x%s%s%s%s', 
      	$m[1], 
      	$m[3], $m[2], 
      	$m[7], $m[6], $m[5], $m[4], 
      	$m[11], $m[10], $m[9], $m[8]);
      
  12. highend says:

    Hi RaMMicHaeL,

    thanks for your reply and posting the necessary command line, much appreciated!

    Works perfectly fine (the .php code for putting the 0x… things together as well.

    Is there a way to return the output to stdout (e.g. when called from inside a dos box) instead of a real window?

    Regards,
    Highend

    • RaMMicHaeL says:

      Here you go:

      winapiexec.exe shell32.dll@SHGetKnownFolderPath $a:0x4BD8D571,0x48D36D19,0x224297BE,0x430E0820 0 0 $b:4 , AttachConsole -1 , WriteConsoleW ( GetStdHandle -11 ) $$:5@0 ( lstrlenW $$:5@0 ) $b:4 0

      Note that by default the process starts in the background, so the output order could get mixed up. You can use START /WAIT to fix this:

      START /WAIT winapiexec.exe shell32.dll@SHGetKnownFolderPath $a:0x4BD8D571,0x48D36D19,0x224297BE,0x430E0820 0 0 $b:4 , AttachConsole -1 , WriteConsoleW ( GetStdHandle -11 ) $$:5@0 ( lstrlenW $$:5@0 ) $b:4 0

  13. highend says:

    Just incredible…

    Thanks again!

    Regards,
    Highend

  14. David.M says:

    Hi

    I having trouble understanding how WinApiExec replicates C structures. I know it can create arrays but how do you control how many bytes each array member takes up? Some API structures have a mix of different width members. Also can you explain the array referencing syntax a little more. What does $$:5@0 reference? Is the 0 array one which is passed to the executable?

    Regards

    David.M

    • RaMMicHaeL says:

      Hi David,

      See the example with CreateProcess (“Run calculator for a second, then terminate it”).
      $a is an array of doublewords, and because most structures are padded, this should fit nicely. If it’s not padded, you’ll have to hack around, similarly to what I did above with GUIDs:
      http://rammichael.com/winapiexec/comment-page-1#comment-4417

      What does $$:5@0 reference?

      $$:5 is the fifth argument. $$:5@0 is equivalent to this in C:
      ((DWORD *)argv[5])[0];

      In the example above (with the GUIDs), the fifth argument holds a pointer to a string, so argv[5] is a pointer to a pointer.

  15. David.M says:

    Hi

    Thanks for the info, I understand the syntax now. Is there a why to return the output to the global atom table? I use a scripting language that could get the data from athe atom table rather than the console.

    Regards

    David.M

  16. David Paul says:

    Hi,
    I need to refresh after changing registry keys
    “HKCU \ Software \ Microsoft \ Windows \ CurrentVersion \ Internet Settings \ ProxyEnable” to 0/1 DWORD.

    It is about turning off the proxy in the registry. But after that change the system knows that proxy was changed and only works when the ticks manually in the GUI.

    Thanks for your time

    David Paul

  17. sheldon says:

    Hi
    I try to change taskbar icons size on the fly without terminating explorer process
    So long I came up with this script (Windows 7):

    @echo off
    (reg add “hkcu\software\microsoft\windows\currentversion\explorer\advanced” /v TaskbarSmallIcons /t REG_DWORD /d 0 /f)>NUL
    winapiexec.exe u@SendMessageW ( u@FindWindowW Shell_TrayWnd 0 ) 0x111 413 0
    ping 192.0.2.2 -n 1 -w 1 > nul
    nircmd.exe dlg “” “” click OK

    Could you please take a look at this? How to make this shorter or at least replace nircmd with winapiexec

    Regards
    sheldon

Leave a Reply