RemedyBG»Forums
34 posts / 1 project
[extremely niche] Doesn't allow calling application without a space in command line

I'm currently working on a CRT implementation, and I was working on getting custom command line parsing (because reasons). There was an algorithm which I wanted to step through and see how it works on some edge cases and how it compares to CommaandLineToArgsW and other applications with different command line parsing.

One of those edge cases is when a slash-flag directly followed the application name, that is without a space, like this:

rd/s/q folder

Breakdown (for Windows' rd command, probably):

argv[0] = "rd"
argv[1] = "/s"
argv[2] = "/q"
argv[3] = "folder"

I found that remedy doesn't support any way of calling an application like that. If I try:

Command Name: "a.exe"
Command Arguments: "/s/q"

The command line ends up being:

"C:\programs\ciabatta\a.exe" /s/q

Which is not what I want.

I'd like to have a single field "command" where you input the whole command, and not application name/command separately.

Simon Anciaux
1260 posts
[extremely niche] Doesn't allow calling application without a space in command line

After reading your post I wondered what my command line parsing code was doing in such a case.

After some tests, it looks to me that cmd.exe is parsing the command line and separating the executable of its arguments, and then creating the process with a space in the command line. It's not the CRT or CommandLineToArgvW that is parsing a command line without space.

Also in my tests, if you don't add a space between the arguments then there will be only one arguments /s/q. So remedybg seems to be doing what is expected. You can see this if you call GetCommandLineW on the executable you ran in cmd.exe.

#include <windows.h>
#include <shellapi.h>

int main( int argc, char** argv ) {
    
    __debugbreak( );
    
    LPCWSTR cmd = GetCommandLineW( );
    int argcw = 0;
    LPCWSTR* argvw = CommandLineToArgvW( cmd, &argcw );
    
    return 0;
}

I think that using / to specify arguments is a Microsoft convention and there isn't a defined meaning for a / in arguments, it's just a character in a string. You probably already know about this, but just in case: Parsing C++ Command-Line Arguments

RemedyBG could probably add a way to specify an exact command line, but, assuming it uses CreateProcess to start the executable, it would need to do what cmd.exe does (separating the executable and arguments) as it would need to pass the exe in the first arguments of create process, then the full command line in the second argument (trying to pass the full command line without space in the first argument, or the second if the first is null, of CreateProcess will fail to create the process). And that behavior would not replicates what happens when you run from the command line (or batch file). So it would probably be just confusing.

You could do your tests by creating the process yourself, and adding a __debugbreak( ) in the test process at the start to trigger a breakpoint to let you attach a debugger:

CreateProcessW( L"test.exe", L"test.exe/s/q", 0, 0, 0, 0, 0, L".\\", &startup_information, &process_information );
34 posts / 1 project
[extremely niche] Doesn't allow calling application without a space in command line
Replying to mrmixer (#26544)

I was looking into a way to attach remedy to a running process and make it break immediately after mainCRTStartup, but the thought of using __debugbrk didn't occur to me. Thank you very much!

Mārtiņš Možeiko
2444 posts / 2 projects
[extremely niche] Doesn't allow calling application without a space in command line

Alternatively just do simple variable assignment LPCWSTR cmdline = L"whatever.exe/a/b"; and debug that instead of calling GetCommandLineW().