0

I'm trying to modify the RCData of a compiled AutoHotkey script:

   void ReplaceStringTable() {

    HANDLE hRes = BeginUpdateResource( _T( "C:\\Users\\CAIO\\Documents\\Github\\main\\scripts\\ahkDebug\\Novo(a) AutoHotkey Script.exe" ), FALSE );
    if ( hRes != NULL ) {
        std::wstring data[] = { L"MsgBox Test" };

        std::vector< WORD > buffer;
        for ( size_t index = 0;
              index < sizeof( data ) / sizeof( data[ 0 ] );
              ++index ) {

            size_t pos = buffer.size();
            buffer.resize( pos + data[ index ].size() + 1 );
            buffer[ pos++ ] = static_cast< WORD >( data[ index ].size() );
            copy( data[ index ].begin(), data[ index ].end(),
                  buffer.begin() + pos );
        }
        UpdateResource( hRes,
                        RT_RCDATA,
                        L">AUTOHOTKEY SCRIPT<", //MAKEINTRESOURCE( 1 ),
                        1033, //MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
                        reinterpret_cast< void* >( &buffer[ 0 ] ),
                        buffer.size() * sizeof( WORD ) );

        EndUpdateResource( hRes, FALSE );
    }
}

However, this is the result after running the code:

RCData

The code does add an empty blank line (line 1), this line makes the exe not work correctly, how do I get rid of it?

  • 1
    Quote from the [documentation of `BeginUpdateResourceW` function](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-beginupdateresourcew): _If this parameter is `TRUE`, existing resources are deleted and the updated file includes only resources added with the UpdateResource function._ – heap underrun Oct 03 '21 at 20:53
  • "*... If this parameter is FALSE, the updated file includes existing resources unless they are explicitly deleted or replaced by using UpdateResource.*" – Remy Lebeau Oct 03 '21 at 20:55
  • If RcData is text, you can rename your *.exe file to *.dll, drop in Visual Studio and edit it. That doesn't sound legal! – Barmak Shemirani Oct 03 '21 at 21:27
  • @RemyLebeau Now the problem is only a blank line the code adds (line 1), when I clear it, the exe works properly, how do I get rid of it? –  Oct 03 '21 at 21:56
  • @Ruan the "blank line" you are referring to is not a line at all. It is caused by the display of the WORD length that you are placing in front of the wstring character data. Why are you doing that? Where did you find that ">AUTOHOTKEY SCRIPT<" resources use length-prefixed strings? The original script doesn't appear to be using them. – Remy Lebeau Oct 03 '21 at 23:11
  • @RemyLebeau i don't understand, I was trying to follow an example and it was using the data in a vector, i don't think i need it, just replacing the data that is inside of the `wstring` would help, but I'm I'm not getting it. –  Oct 03 '21 at 23:43
  • @Ruan what example are you referring to? Was it specifically for AHK scripts, or for something else? Have you tried simply removing the `WORD`s altogether? `std::wstring data = L"MsgBox Test"; ... UpdateResource(..., &data[0], data.size() * sizeof(wchar_t));` – Remy Lebeau Oct 03 '21 at 23:49
  • @RemyLebeau now it does not add the "blank line" anymore, but when I run the exe, looks like it does recognize just the `M` https://i.imgur.com/GvpEcBy.png, I was referring to this example: https://stackoverflow.com/questions/14088057/updating-a-string-table-with-updateresource –  Oct 04 '21 at 00:04
  • @Ruan that example is creating an `RT_STRING` (string table) resource, which is not what you are creating. As for the encoding issue, AHK is clearly processing the 16bit Unicode characters as 8bit characters, so try using `std::string` instead of `std::wstring`: `std::string data = "MsgBox Test"; ... UpdateResource(..., &data[0], data.size());` And FYI, there is no need to cast to `void*` using `reinterpret_cast` – Remy Lebeau Oct 04 '21 at 00:53
  • Thank you, I converted it to `std::string` now it does work. –  Oct 04 '21 at 01:29

1 Answers1

0

You need to use std::string instead of std::wstring, as AHK is expecting 8bit characters, not 16bit characters. Also, you need to get rid of your vector, as AHK does not expect each line to be prefixed by its length.

Try this instead:

void ReplaceStringTable() {

    HANDLE hRes = BeginUpdateResource( TEXT( "C:\\Users\\CAIO\\Documents\\Github\\main\\scripts\\ahkDebug\\Novo(a) AutoHotkey Script.exe" ), FALSE );
    if ( hRes != NULL ) {
        std::string data = "MsgBox Test";

        UpdateResource( hRes,
            RT_RCDATA,
            L">AUTOHOTKEY SCRIPT<", //MAKEINTRESOURCE( 1 ),
            1033, //MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
            const_cast<char*>(data.c_str()),
            data.size() );

        EndUpdateResource( hRes, FALSE ); 
    }
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770