Repository: pyinstaller/pyinstaller

Issue:
EXE fails with "Cannot open self" after running pyi-set_version.exe against it
I have a single-file script that I'm using pyinstaller to turn into a Windows exe file. It runs perfectly fine:
```
C:\svn\T220>dist\xlsx2csv\xlsx2csv.exe
Invalid Arguments. Usage: xlsx2csv <database> <folder for output [optional, should default to exe folder]>
```
until I run `pyi-set_version.exe` to embed version info:
```
C:\svn\T220>pyi-set_version.exe text.txt dist/xlsx2csv/xlsx2csv.exe
Version info set in: C:\svn\T220\dist\xlsx2csv\xlsx2csv.exe

C:\svn\T220>dist\xlsx2csv\xlsx2csv.exe
[3164] Cannot open self C:\svn\T220\dist\xlsx2csv\xlsx2csv.exe or archive C:\svn\T220\dist\xlsx2csv\xlsx2csv.pkg
```

I've installed the current development version of pyinstaller and run `pyi-archive_viewer.exe` against it, and it seems fine before I run `pyi-set_version.exe`, and fails afterwards:

```
C:\svn\T220>pyinstaller xlsx2csv.py
54 INFO: PyInstaller: 3.4.dev0+ab8fd9753
54 INFO: Python: 3.6.3
56 INFO: Platform: Windows-10-10.0.14393-SP0
59 INFO: wrote C:\svn\T220\xlsx2csv.spec
60 INFO: UPX is not available.
61 INFO: Extending PYTHONPATH with paths
['C:\\svn\\T220', 'C:\\svn\\T220']
62 INFO: checking Analysis
71 INFO: checking PYZ
79 INFO: checking PKG
80 INFO: Bootloader c:\python36-32\lib\site-packages\PyInstaller\bootloader\Windows-32bit\run.exe
81 INFO: checking EXE
82 INFO: checking COLLECT
WARNING: The output directory "C:\svn\T220\dist\xlsx2csv" and ALL ITS CONTENTS will be REMOVED! Continue? (y/n)y
2221 INFO: Removing dir C:\svn\T220\dist\xlsx2csv
2262 INFO: Building COLLECT out00-COLLECT.toc
2512 INFO: Building COLLECT out00-COLLECT.toc completed successfully.


C:\svn\T220>pyi-archive_viewer dist\xlsx2csv\xlsx2csv.exe
 pos, length, uncompressed, iscompressed, type, name
[(0, 248, 312, 1, 'm', 'struct'),
 (248, 1103, 1803, 1, 'm', 'pyimod01_os_path'),
 (1351, 4287, 9257, 1, 'm', 'pyimod02_archive'),
 (5638, 7218, 18478, 1, 'm', 'pyimod03_importers'),
 (12856, 1859, 4171, 1, 's', 'pyiboot01_bootstrap'),
 (14715, 2128, 3302, 1, 's', 'xlsx2csv'),
 (16843, 1284264, 1284264, 0, 'z', 'out00-PYZ.pyz')]
? Aborted by user request.

C:\svn\T220>pyi-set_version.exe text.txt dist/xlsx2csv/xlsx2csv.exe
Version info set in: C:\svn\T220\dist\xlsx2csv\xlsx2csv.exe

C:\svn\T220>pyi-archive_viewer dist\xlsx2csv\xlsx2csv.exe
Traceback (most recent call last):
  File "C:\Python36-32\Scripts\pyi-archive_viewer-script.py", line 11, in <module>
    load_entry_point('PyInstaller==3.4.dev0+ab8fd9753', 'console_scripts', 'pyi-archive_viewer')()
  File "c:\python36-32\lib\site-packages\PyInstaller\utils\cliutils\archive_viewer.py", line 261, in run
    raise SystemExit(main(**vars(args)))
  File "c:\python36-32\lib\site-packages\PyInstaller\utils\cliutils\archive_viewer.py", line 40, in main
    arch = get_archive(name)
  File "c:\python36-32\lib\site-packages\PyInstaller\utils\cliutils\archive_viewer.py", line 129, in get_archive
    return CArchiveReader(name)
  File "c:\python36-32\lib\site-packages\PyInstaller\archive\readers.py", line 130, in __init__
    super(CArchiveReader, self).__init__(archive_path, start)
  File "c:\python36-32\lib\site-packages\PyInstaller\loader\pyimod02_archive.py", line 163, in __init__
    self.checkmagic()
  File "c:\python36-32\lib\site-packages\PyInstaller\archive\readers.py", line 153, in checkmagic
    (self.path, self.__class__.__name__))
RuntimeError: dist\xlsx2csv\xlsx2csv.exe is not a valid CArchiveReader archive file
```

The `text.txt` file I'm testing with there is https://raw.githubusercontent.com/pyinstaller/pyinstaller/develop/tests/old_suite/basic/test_pkg_structures-version.txt. Originally I was using a self-generated one created from using pyi-get_version from a py2exe-compiled version of this script (I'm trying to change over from py2exe to pyinstaller). In both cases, the file fails to run after the version info is added, but the version info *is* reported correctly by Windows afterwards.

I'd really like to switch over to using pyinstaller for this project rather than old py2exe, but including version info is important for it, so I hope this can be solved somehow!
EXE fails with "Cannot open self" after running pyi-set_version.exe against it
I have a single-file script that I'm using pyinstaller to turn into a Windows exe file. It runs perfectly fine:
```
C:\svn\T220>dist\xlsx2csv\xlsx2csv.exe
Invalid Arguments. Usage: xlsx2csv <database> <folder for output [optional, should default to exe folder]>
```
until I run `pyi-set_version.exe` to embed version info:
```
C:\svn\T220>pyi-set_version.exe text.txt dist/xlsx2csv/xlsx2csv.exe
Version info set in: C:\svn\T220\dist\xlsx2csv\xlsx2csv.exe

C:\svn\T220>dist\xlsx2csv\xlsx2csv.exe
[3164] Cannot open self C:\svn\T220\dist\xlsx2csv\xlsx2csv.exe or archive C:\svn\T220\dist\xlsx2csv\xlsx2csv.pkg
```

I've installed the current development version of pyinstaller and run `pyi-archive_viewer.exe` against it, and it seems fine before I run `pyi-set_version.exe`, and fails afterwards:

```
C:\svn\T220>pyinstaller xlsx2csv.py
54 INFO: PyInstaller: 3.4.dev0+ab8fd9753
54 INFO: Python: 3.6.3
56 INFO: Platform: Windows-10-10.0.14393-SP0
59 INFO: wrote C:\svn\T220\xlsx2csv.spec
60 INFO: UPX is not available.
61 INFO: Extending PYTHONPATH with paths
['C:\\svn\\T220', 'C:\\svn\\T220']
62 INFO: checking Analysis
71 INFO: checking PYZ
79 INFO: checking PKG
80 INFO: Bootloader c:\python36-32\lib\site-packages\PyInstaller\bootloader\Windows-32bit\run.exe
81 INFO: checking EXE
82 INFO: checking COLLECT
WARNING: The output directory "C:\svn\T220\dist\xlsx2csv" and ALL ITS CONTENTS will be REMOVED! Continue? (y/n)y
2221 INFO: Removing dir C:\svn\T220\dist\xlsx2csv
2262 INFO: Building COLLECT out00-COLLECT.toc
2512 INFO: Building COLLECT out00-COLLECT.toc completed successfully.


C:\svn\T220>pyi-archive_viewer dist\xlsx2csv\xlsx2csv.exe
 pos, length, uncompressed, iscompressed, type, name
[(0, 248, 312, 1, 'm', 'struct'),
 (248, 1103, 1803, 1, 'm', 'pyimod01_os_path'),
 (1351, 4287, 9257, 1, 'm', 'pyimod02_archive'),
 (5638, 7218, 18478, 1, 'm', 'pyimod03_importers'),
 (12856, 1859, 4171, 1, 's', 'pyiboot01_bootstrap'),
 (14715, 2128, 3302, 1, 's', 'xlsx2csv'),
 (16843, 1284264, 1284264, 0, 'z', 'out00-PYZ.pyz')]
? Aborted by user request.

C:\svn\T220>pyi-set_version.exe text.txt dist/xlsx2csv/xlsx2csv.exe
Version info set in: C:\svn\T220\dist\xlsx2csv\xlsx2csv.exe

C:\svn\T220>pyi-archive_viewer dist\xlsx2csv\xlsx2csv.exe
Traceback (most recent call last):
  File "C:\Python36-32\Scripts\pyi-archive_viewer-script.py", line 11, in <module>
    load_entry_point('PyInstaller==3.4.dev0+ab8fd9753', 'console_scripts', 'pyi-archive_viewer')()
  File "c:\python36-32\lib\site-packages\PyInstaller\utils\cliutils\archive_viewer.py", line 261, in run
    raise SystemExit(main(**vars(args)))
  File "c:\python36-32\lib\site-packages\PyInstaller\utils\cliutils\archive_viewer.py", line 40, in main
    arch = get_archive(name)
  File "c:\python36-32\lib\site-packages\PyInstaller\utils\cliutils\archive_viewer.py", line 129, in get_archive
    return CArchiveReader(name)
  File "c:\python36-32\lib\site-packages\PyInstaller\archive\readers.py", line 130, in __init__
    super(CArchiveReader, self).__init__(archive_path, start)
  File "c:\python36-32\lib\site-packages\PyInstaller\loader\pyimod02_archive.py", line 163, in __init__
    self.checkmagic()
  File "c:\python36-32\lib\site-packages\PyInstaller\archive\readers.py", line 153, in checkmagic
    (self.path, self.__class__.__name__))
RuntimeError: dist\xlsx2csv\xlsx2csv.exe is not a valid CArchiveReader archive file
```

The `text.txt` file I'm testing with there is https://raw.githubusercontent.com/pyinstaller/pyinstaller/develop/tests/old_suite/basic/test_pkg_structures-version.txt. Originally I was using a self-generated one created from using pyi-get_version from a py2exe-compiled version of this script (I'm trying to change over from py2exe to pyinstaller). In both cases, the file fails to run after the version info is added, but the version info *is* reported correctly by Windows afterwards.

I'd really like to switch over to using pyinstaller for this project rather than old py2exe, but including version info is important for it, so I hope this can be solved somehow!


Discussion:
Does archive-viewer work on the file *after* running pyi-set_version? (I assume, it does not.)

The error message looks like something is killing the ["magic  bytes" near the end of the .exe](https://github.com/pyinstaller/pyinstaller/blob/v3.3.1/PyInstaller/archive/readers.py#L147). Maybe set-version is overwriting data or data may be appended to to file. Please check both. Some tool to view or analyze the structure of a PE file might help you.
I confirm I have this same issue. It happens on older Windows systems for me mainly. 2008 r2 servers for example.

On my dev Windows 7 system it works without problems.

I just ran the upgrade so am on the latest version of pyinstaller. I'm on python 3.5 and have compiled my exe on a 32bit system in order to be able to deal with older systems.
Sorry for the delayed response! Holidays, and all that :)

> Does archive-viewer work on the file after running pyi-set_version? (I assume, it does not.)

It does not, if you look at the last part of my output above you'll see that in fact it outright crashes:
```
C:\svn\T220>pyi-set_version.exe text.txt dist/xlsx2csv/xlsx2csv.exe
Version info set in: C:\svn\T220\dist\xlsx2csv\xlsx2csv.exe

C:\svn\T220>pyi-archive_viewer dist\xlsx2csv\xlsx2csv.exe
Traceback (most recent call last):
  File "C:\Python36-32\Scripts\pyi-archive_viewer-script.py", line 11, in <module>
    load_entry_point('PyInstaller==3.4.dev0+ab8fd9753', 'console_scripts', 'pyi-archive_viewer')()
  File "c:\python36-32\lib\site-packages\PyInstaller\utils\cliutils\archive_viewer.py", line 261, in run
    raise SystemExit(main(**vars(args)))
  File "c:\python36-32\lib\site-packages\PyInstaller\utils\cliutils\archive_viewer.py", line 40, in main
    arch = get_archive(name)
  File "c:\python36-32\lib\site-packages\PyInstaller\utils\cliutils\archive_viewer.py", line 129, in get_archive
    return CArchiveReader(name)
  File "c:\python36-32\lib\site-packages\PyInstaller\archive\readers.py", line 130, in __init__
    super(CArchiveReader, self).__init__(archive_path, start)
  File "c:\python36-32\lib\site-packages\PyInstaller\loader\pyimod02_archive.py", line 163, in __init__
    self.checkmagic()
  File "c:\python36-32\lib\site-packages\PyInstaller\archive\readers.py", line 153, in checkmagic
    (self.path, self.__class__.__name__))
RuntimeError: dist\xlsx2csv\xlsx2csv.exe is not a valid CArchiveReader archive file
```

> The error message looks like something is killing the "magic bytes" near the end of the .exe. Maybe set-version is overwriting data or data may be appended to to file. Please check both. Some tool to view or analyze the structure of a PE file might help you.

So I took a look and it's actually way more dramatic than that:

```
keithzg@siddhartha:/media/quartet/case-data/pyinstaller3142$ ls -l
total 1752
-rwxrw-rw- 1 nobody nogroup 1544712 Jan  3 17:11 xlsx2csv_unversioned.exe
-rwxrw-rw- 1 nobody nogroup  244224 Jan  3 17:13 xlsx2csv_versioned.exe
```

Writing the version info to the exe instantly reduces the size from 1.5MB to less than a quarter of a megabyte. It isn't just killing the magic bytes at the end of the exe, it's killing most of the exe! There seem to be only minor differences until about 2/3rds of the way into the truncated exe at which point it suddenly completely diverges from the untruncated one.

Here are hexdumps of the two exes:

[unversioned.hex.txt](https://github.com/pyinstaller/pyinstaller/files/1602112/unversioned.hex.txt)
[versioned.hex.txt](https://github.com/pyinstaller/pyinstaller/files/1602111/versioned.hex.txt)

Perhaps worth noting, these exes were created with Pyinstaller 3.3.1, on Python 3.6 32-bit, on Windows 10 64-bit, since I returned the build machine in question to the stable release and I've been using [a third-party tool](https://www.codeproject.com/Articles/37133/Simple-Version-Resource-Tool-for-Windows) to embed version info in the meantime. But I can fire up a test environment and reinstall the development version of Pyinstaller if need be!
  
Any hope of a fix for this? Using a third-party tool works alright, but it'd be nice to not have to!
Thanks for the analysis. Looks like out current approach of appending the PYZ-archive to the .exe (by simply appending the bytes to the file) doesn't really work fro PE files. (For ELF files we use `objcoby` since long.) I wonder why nobody brought this up earlier.

Somebody with a better knowledge of the PE file format needs to look at this. The place to fix it is around [here](https://github.com/pyinstaller/pyinstaller/blob/v3.3.1/PyInstaller/building/api.py#L569). I suggest suing the the `pefile` package to manipulate the exe.
FWIW, I tried to add a version resource to the pyinstaller generated exe with Visual Studio 2017 and the exact same thing happened. Before adding the version resource, my executable was 5 MB. After adding the resource, my executable was 280 KB and seemed to be corrupt in exactly the same way as when using pyi-set_version.exe.

There's a problem somewhere, but I don't think it's necessarily in pyi-set_version.exe
I confirm @criddell 's observation. My original executable has a size of 5.35 MB. After running `pyi-set_version` it's only 253 KB. The error message is the same es above.

Shouldn't it be possible to provide the version.rc file already when running pyinstaller via 
```sh
pyinstaller --version-file=version.rc example.spec
```
It did not set any information from the rc file. Are these bugs related?
I have tried [rcedit](https://github.com/electron/rcedit) now, but I get the same issue, so i guess the problem is not specific to pyinstaller. Does someone have an idea where it might originate from?
I just tried [verpatch](https://github.com/pavel-a/ddverpatch) and was able to add a version resource to the file!

I built it with VS2017 and ran it with this command line:

v.exe C:\Temp\Foo.exe /va 1.2.3.4 /s desc "my program" 

Interestingly, it output the debug message 

    Found extra 5832811 bytes appended to the file

I wonder if the other resource editing tools think there's a bunch of wasted space and they clean it up when really it's the data payload needed by the exe to run?

> I wonder if the other resource editing tools think there's a bunch of wasted space and they clean it up when really it's the data payload needed by the exe to run?

This might indeed be the case, see https://github.com/pyinstaller/pyinstaller/issues/3142#issuecomment-364268857
I was able to work around the problem in `pyi-set_version.exe` by modifying `SetVersion` in `utils/win32/versioninfo.py`. This just grabs the overlay from executable prior to updating the version resource and then copies it back afterward.

```
def SetVersion(exenm, versionfile):
    if isinstance(versionfile, VSVersionInfo):
        vs = versionfile
    else:
        fp = codecs.open(versionfile, 'rU', 'utf-8')
        txt = fp.read()
        fp.close()
        vs = eval(txt)

    import pefile
    pe = pefile.PE(exenm, fast_load=True)
    try:
       overlay = pe.get_overlay()
    finally:
        pe.close()

    hdst = win32api.BeginUpdateResource(exenm, 0)
    win32api.UpdateResource(hdst, pefile.RESOURCE_TYPE['RT_VERSION'], 1, vs.toRaw())
    win32api.EndUpdateResource (hdst, 0)

    with open(exenm, 'ab') as exef:
        exef.write(overlay)

```

@dekrueger Would you please be so kind and provide a pull-request? This would be great!
Does archive-viewer work on the file *after* running pyi-set_version? (I assume, it does not.)

The error message looks like something is killing the ["magic  bytes" near the end of the .exe](https://github.com/pyinstaller/pyinstaller/blob/v3.3.1/PyInstaller/archive/readers.py#L147). Maybe set-version is overwriting data or data may be appended to to file. Please check both. Some tool to view or analyze the structure of a PE file might help you.
I confirm I have this same issue. It happens on older Windows systems for me mainly. 2008 r2 servers for example.

On my dev Windows 7 system it works without problems.

I just ran the upgrade so am on the latest version of pyinstaller. I'm on python 3.5 and have compiled my exe on a 32bit system in order to be able to deal with older systems.
Sorry for the delayed response! Holidays, and all that :)

> Does archive-viewer work on the file after running pyi-set_version? (I assume, it does not.)

It does not, if you look at the last part of my output above you'll see that in fact it outright crashes:
```
C:\svn\T220>pyi-set_version.exe text.txt dist/xlsx2csv/xlsx2csv.exe
Version info set in: C:\svn\T220\dist\xlsx2csv\xlsx2csv.exe

C:\svn\T220>pyi-archive_viewer dist\xlsx2csv\xlsx2csv.exe
Traceback (most recent call last):
  File "C:\Python36-32\Scripts\pyi-archive_viewer-script.py", line 11, in <module>
    load_entry_point('PyInstaller==3.4.dev0+ab8fd9753', 'console_scripts', 'pyi-archive_viewer')()
  File "c:\python36-32\lib\site-packages\PyInstaller\utils\cliutils\archive_viewer.py", line 261, in run
    raise SystemExit(main(**vars(args)))
  File "c:\python36-32\lib\site-packages\PyInstaller\utils\cliutils\archive_viewer.py", line 40, in main
    arch = get_archive(name)
  File "c:\python36-32\lib\site-packages\PyInstaller\utils\cliutils\archive_viewer.py", line 129, in get_archive
    return CArchiveReader(name)
  File "c:\python36-32\lib\site-packages\PyInstaller\archive\readers.py", line 130, in __init__
    super(CArchiveReader, self).__init__(archive_path, start)
  File "c:\python36-32\lib\site-packages\PyInstaller\loader\pyimod02_archive.py", line 163, in __init__
    self.checkmagic()
  File "c:\python36-32\lib\site-packages\PyInstaller\archive\readers.py", line 153, in checkmagic
    (self.path, self.__class__.__name__))
RuntimeError: dist\xlsx2csv\xlsx2csv.exe is not a valid CArchiveReader archive file
```

> The error message looks like something is killing the "magic bytes" near the end of the .exe. Maybe set-version is overwriting data or data may be appended to to file. Please check both. Some tool to view or analyze the structure of a PE file might help you.

So I took a look and it's actually way more dramatic than that:

```
keithzg@siddhartha:/media/quartet/case-data/pyinstaller3142$ ls -l
total 1752
-rwxrw-rw- 1 nobody nogroup 1544712 Jan  3 17:11 xlsx2csv_unversioned.exe
-rwxrw-rw- 1 nobody nogroup  244224 Jan  3 17:13 xlsx2csv_versioned.exe
```

Writing the version info to the exe instantly reduces the size from 1.5MB to less than a quarter of a megabyte. It isn't just killing the magic bytes at the end of the exe, it's killing most of the exe! There seem to be only minor differences until about 2/3rds of the way into the truncated exe at which point it suddenly completely diverges from the untruncated one.

Here are hexdumps of the two exes:

[unversioned.hex.txt](https://github.com/pyinstaller/pyinstaller/files/1602112/unversioned.hex.txt)
[versioned.hex.txt](https://github.com/pyinstaller/pyinstaller/files/1602111/versioned.hex.txt)

Perhaps worth noting, these exes were created with Pyinstaller 3.3.1, on Python 3.6 32-bit, on Windows 10 64-bit, since I returned the build machine in question to the stable release and I've been using [a third-party tool](https://www.codeproject.com/Articles/37133/Simple-Version-Resource-Tool-for-Windows) to embed version info in the meantime. But I can fire up a test environment and reinstall the development version of Pyinstaller if need be!
  
Any hope of a fix for this? Using a third-party tool works alright, but it'd be nice to not have to!
Thanks for the analysis. Looks like out current approach of appending the PYZ-archive to the .exe (by simply appending the bytes to the file) doesn't really work fro PE files. (For ELF files we use `objcoby` since long.) I wonder why nobody brought this up earlier.

Somebody with a better knowledge of the PE file format needs to look at this. The place to fix it is around [here](https://github.com/pyinstaller/pyinstaller/blob/v3.3.1/PyInstaller/building/api.py#L569). I suggest suing the the `pefile` package to manipulate the exe.
FWIW, I tried to add a version resource to the pyinstaller generated exe with Visual Studio 2017 and the exact same thing happened. Before adding the version resource, my executable was 5 MB. After adding the resource, my executable was 280 KB and seemed to be corrupt in exactly the same way as when using pyi-set_version.exe.

There's a problem somewhere, but I don't think it's necessarily in pyi-set_version.exe
I confirm @criddell 's observation. My original executable has a size of 5.35 MB. After running `pyi-set_version` it's only 253 KB. The error message is the same es above.

Shouldn't it be possible to provide the version.rc file already when running pyinstaller via 
```sh
pyinstaller --version-file=version.rc example.spec
```
It did not set any information from the rc file. Are these bugs related?
I have tried [rcedit](https://github.com/electron/rcedit) now, but I get the same issue, so i guess the problem is not specific to pyinstaller. Does someone have an idea where it might originate from?
I just tried [verpatch](https://github.com/pavel-a/ddverpatch) and was able to add a version resource to the file!

I built it with VS2017 and ran it with this command line:

v.exe C:\Temp\Foo.exe /va 1.2.3.4 /s desc "my program" 

Interestingly, it output the debug message 

    Found extra 5832811 bytes appended to the file

I wonder if the other resource editing tools think there's a bunch of wasted space and they clean it up when really it's the data payload needed by the exe to run?

> I wonder if the other resource editing tools think there's a bunch of wasted space and they clean it up when really it's the data payload needed by the exe to run?

This might indeed be the case, see https://github.com/pyinstaller/pyinstaller/issues/3142#issuecomment-364268857
I was able to work around the problem in `pyi-set_version.exe` by modifying `SetVersion` in `utils/win32/versioninfo.py`. This just grabs the overlay from executable prior to updating the version resource and then copies it back afterward.

```
def SetVersion(exenm, versionfile):
    if isinstance(versionfile, VSVersionInfo):
        vs = versionfile
    else:
        fp = codecs.open(versionfile, 'rU', 'utf-8')
        txt = fp.read()
        fp.close()
        vs = eval(txt)

    import pefile
    pe = pefile.PE(exenm, fast_load=True)
    try:
       overlay = pe.get_overlay()
    finally:
        pe.close()

    hdst = win32api.BeginUpdateResource(exenm, 0)
    win32api.UpdateResource(hdst, pefile.RESOURCE_TYPE['RT_VERSION'], 1, vs.toRaw())
    win32api.EndUpdateResource (hdst, 0)

    with open(exenm, 'ab') as exef:
        exef.write(overlay)

```

@dekrueger Would you please be so kind and provide a pull-request? This would be great!

Resolving patch:
diff --git a/PyInstaller/utils/win32/versioninfo.py b/PyInstaller/utils/win32/versioninfo.py
--- a/PyInstaller/utils/win32/versioninfo.py
+++ b/PyInstaller/utils/win32/versioninfo.py
@@ -581,6 +581,23 @@ def SetVersion(exenm, versionfile):
         txt = fp.read()
         fp.close()
         vs = eval(txt)
+
+    # Remember overlay
+    pe = pefile.PE(exenm, fast_load=True)
+    overlay_before = pe.get_overlay()
+    pe.close()
+
     hdst = win32api.BeginUpdateResource(exenm, 0)
     win32api.UpdateResource(hdst, pefile.RESOURCE_TYPE['RT_VERSION'], 1, vs.toRaw())
     win32api.EndUpdateResource (hdst, 0)
+
+    if overlay_before:
+        # Check if the overlay is still present
+        pe = pefile.PE(exenm, fast_load=True)
+        overlay_after = pe.get_overlay()
+        pe.close()
+
+        # If the update removed the overlay data, re-append it
+        if not overlay_after:
+            with open(exenm, 'ab') as exef:
+                exef.write(overlay_before)


Test patch: