Skip to content

Commit

Permalink
allow for switching between focusing and non focusing behaviour and u…
Browse files Browse the repository at this point in the history
…pdate readme accordingly - resolves #1
  • Loading branch information
schnotzler committed Mar 11, 2023
1 parent 71e60b6 commit 7017a36
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 22 deletions.
80 changes: 73 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,86 @@
# winrun

Simple Windows Executable to run commands from a file.

## About
The current [Base Camp™](https://mountain.gg/base-camp/) release does not support running commands or launching programs with custom launch options,
while at the same time only allowing you to select .exe files to be launched.

This program is a quick and dirty workaround for this usecase.
I can't think of any other usecase, because usually you could just write a .bat file or something similar.
The current [Base Camp™](https://mountain.gg/base-camp/) release does not support running commands or launching programs with custom launch options, while at the same time only allowing you to select .exe files to be launched.

This program is a quick and dirty workaround for this usecase.

Sometimes it may be desired to launch applications in the background, without giving focus to them. ***winrun*** allows for this.

## Installation and Usage

- Download the [latest version](https://github.com/schnotzler/winrun/releases) (winrun.exe)
- Move the downloaded executable to any directory you like. I prefer to use same location as the program i want to run is in.
- Create a simple file named `winrun.cfg` in the ***same directory as winrun.exe***
- Add you command(s) to `winrun.cfg`. See [this example](https://github.com/schnotzler/winrun/blob/main/winrun.cfg) which would run the windows calculator app
- Create a simple file named `winrun.cfg` in the ***same directory as winrun.exe***
- Add the process(es) you wish to run `winrun.cfg`. See [this example](https://github.com/schnotzler/winrun/blob/main/winrun.cfg) which would run the windows editor (notepad.exe). Have a look at section [Advanced Usage](#detailed-usage-of-cfg) for more information
- Now select `winrun.exe` from your directory in `Base Camp™`»`Device`»`Key Binding`»`Key`»`Function`»`Run Program`»`Link`

Note: Of course you can have multiple configuration of `winrun` in use, just make sure to use a different directory with a different `winrun.cfg`
Note: Of course you can have multiple configurations of `winrun` in use, just make sure to use a different directory with a different `winrun.cfg`

## Detailed usage of `.cfg`

### General

The winrun.cfg file is parsed line by line.
Each line is executed one after another.
Empty lines are skipped.
It is therefore possible to open multiple programs in one go.

### Leading whitespaces
Leading spaces or tabs are ignored.
So each one of the lines below is valid in a `winrun.cfg` and is going to give the same result.

```cfg
notepad.exe winrun.cfg
notepad.exe winrun.cfg
notepad.exe winrun.cfg
notepad.exe winrun.cfg
```

### Running in background

The default behaviour if not specified is, that the newly launched Program will receive focus.

But it is possible to start programs in the background, without giving focus to them, as well.
However some applications give focus to themselves on launch, so your mileage may vary here.

To mark program, to be run without focus, just add `#NOFOCUS` before the command.

Whitespace handling is quite lenient here as well.

So each one of the lines below is valid in a `winrun.cfg` and is going to give the same result, that is opening notepad without giving focus to the new window.


```cfg
#NOFOCUSnotepad.exe winrun.cfg
#NOFOCUS notepad.exe winrun.cfg
#NOFOCUS notepad.exe winrun.cfg
#NOFOCUSnotepad.exe winrun.cfg
#NOFOCUS notepad.exe winrun.cfg
#NOFOCUS notepad.exe winrun.cfg
#NOFOCUSnotepad.exe winrun.cfg
```

Analog to `#NOFOCUS` there is also support for `#FOCUS`, which as you may have guessed gives focus to the new window.
`#FOCUS` may be omitted, since it is the default behaviour anyway.

You can mix and match `#NOFOCUS`, `#FOCUS`, and no explicit specification in the same `winrun.cfg` to your liking on a per-line-basis.

Example for a mixed `winrun.cfg`, that would start 2 instances of notepad in the background and 2 in the foreground (only the last one will retain focus obviously). 2 of the editors will be empty, while 2 opened winrun.cfg. With the empty notepad launched by line 3 having focus.

```cfg
#NOFOCUSnotepad.exe winrun.cfg
#FOCUS notepad.exe winrun.cfg
notepad.exe
#NOFOCUS notepad.exe
```

## Troubleshooting

- If you have problems running your program, try using the absolute file path of your program `C:\WINDOWS\system32\notepad.exe` for example
- Open an Issue only **after** you have read this `Readme.md` entirely

<sub>This is provided as-is. Use this program at you own risk, i am not responsible for any problems or damages you might have due to using this program</sub>
60 changes: 50 additions & 10 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
#include <unistd.h>
#include <windows.h>

void ShowErrorBox( char* msg, char* windowtitle ) {
HWND hwnd = NULL; // Use NULL to display the message box as a standalone window
LPCSTR text = msg; // The text to display in the message box
LPCSTR title = windowtitle; // The title of the message box
MessageBox( hwnd, text, title, MB_OK | MB_ICONERROR );
}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdParam, int nCmdShow ) {
FILE* fp;
char linebuf[256 + 1] = { 0 };
Expand All @@ -25,8 +32,10 @@ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdPara
return -2;
}

int retVal = 0;

// read and execute from file line by line
while ( 0 < fscanf( fp, "%256[A-Za-z0-9 -\\:]\n", linebuf ) ) {
while ( EOF != fscanf( fp, "%256[A-Za-z0-9 -\\:]\n", linebuf ) ) {
STARTUPINFOA startupInfo = { 0 };
PROCESS_INFORMATION processInfo = { 0 };

Expand All @@ -37,25 +46,56 @@ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdPara
startupInfo.cb = sizeof( STARTUPINFO );
startupInfo.dwFlags = STARTF_USESHOWWINDOW;

// Focus new Window
// startupInfo.wShowWindow = SW_SHOWNORMAL;
// Trim leading whitespace(s)
while ( *commandLineArgs == ' ' || *commandLineArgs == '\t' ) {
commandLineArgs++;
}

// Don't Focus new Window
startupInfo.wShowWindow = SW_SHOWNOACTIVATE;
// Check for specified focus state and handle accordingly
if ( strncmp( "#NOFOCUS", commandLineArgs, 8 ) == 0 ) {
// Don't Focus new Window
startupInfo.wShowWindow = SW_SHOWNOACTIVATE;
commandLineArgs += 8;
} else { // Focus new Window
if ( strncmp( "#FOCUS", commandLineArgs, 6 ) == 0 ) {
commandLineArgs += 6;
}
startupInfo.wShowWindow = SW_SHOWNORMAL;
}

// Trim leading whitespace(s)
while ( *commandLineArgs == ' ' || *commandLineArgs == '\t' ) {
commandLineArgs++;
}

// Skip empty lines
if ( strlen( commandLineArgs ) == 0 ) {
// move fp by 1
fgetc( fp );
continue;
}

// Launch the process
if ( CreateProcessA( NULL, commandLineArgs, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfo ) ) {
printf( "Process started with process ID %lu\n", processInfo.dwProcessId );
// printf( "Process started with process ID %lu\n", processInfo.dwProcessId );
CloseHandle( processInfo.hProcess );
CloseHandle( processInfo.hThread );
} else {
printf( "Error launching process: %lu\n", GetLastError() );
fclose( fp );
return ( -3 );
char* errortext = calloc( sizeof( char ), 512 + 1 /* \0 */ );
// char errortext[512];
snprintf( errortext,
512,
"Error launching process: %lu\nFailed command: >%s<\nLine in file: %s",
GetLastError(),
commandLineArgs,
linebuf );
ShowErrorBox( errortext, "CreateProcess Error" );
free( errortext );
retVal = -3;
}
}

// cleanup and close
fclose( fp );
return ( 0 );
return ( retVal );
}
11 changes: 7 additions & 4 deletions winrun.cbp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<FileVersion major="1" minor="6" />
<Project>
<Option title="winrun" />
<Option platforms="Windows;" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
Expand All @@ -17,11 +18,16 @@
</Target>
<Target title="Release">
<Option output="bin/Release/winrun" prefix_auto="1" extension_auto="1" />
<Option working_dir="bin/Release" />
<Option object_output="obj/Release/" />
<Option type="1" />
<Option type="0" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
<Add option="-Weffc++" />
<Add option="-pedantic" />
<Add option="-Wextra" />
<Add option="-Wall" />
</Compiler>
<Linker>
<Add option="-s" />
Expand All @@ -37,9 +43,6 @@
</Unit>
<Unit filename="winrun.cfg" />
<Extensions>
<code_completion />
<envvars />
<debugger />
<lib_finder disable_auto="1" />
</Extensions>
</Project>
Expand Down
2 changes: 1 addition & 1 deletion winrun.cfg
Original file line number Diff line number Diff line change
@@ -1 +1 @@
start calc
notepad.exe winrun.cfg

0 comments on commit 7017a36

Please # to comment.