Skip to content

Commit b2dd364

Browse files
committed
Add support for running from pyinstaller frozen executable
1 parent cee2e0d commit b2dd364

File tree

3 files changed

+73
-9
lines changed

3 files changed

+73
-9
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,29 @@ By default the image credits are kept. Pass `--remove-credits` if you would like
1616
</p>
1717

1818
## Installation
19+
If you have Python installed
1920
```
2021
python -m pip install --user RemoveWindowsLockScreenAds
2122
pythonw -m RemoveWindowsLockScreenAds --install
2223
```
24+
If you don't want to install Python, download the [standalone installer](https://github.com/clarkb7/RemoveWindowsLockScreenAds/releases/latest/download/RemoveWindowsLockScreenAds.noconsole.exe), press `WindowsKey+r`, then paste and run
25+
```
26+
%USERPROFILE%\Downloads\RemoveWindowsLockScreenAds.noconsole.exe --install
27+
```
28+
29+
When run with pythonw or RemoveWindowsLockScreenAds.noconsole.exe there is no console output. However, --install and --uninstall will log to `%TEMP%\RemoveWindowsLockScreenAds.install.log`.
30+
31+
You can enable and disable RemoveWindowsLockScreenAds from the Startup tab in Windows Task Manager.
2332

2433
## Try it out without modifying anything
34+
Python
2535
```
2636
python -m RemoveWindowsLockScreenAds --once --dry-run --verbose
2737
```
38+
Standalone console program
39+
```
40+
RemoveWindowsLockScreenAds.console.exe --once --dry-run --verbose
41+
```
2842

2943
## Detailed Usage
3044
```

RemoveWindowsLockScreenAds/RemoveWindowsLockScreenAds.py

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66
import subprocess
77
import shutil
88
import time
9+
import struct
910

1011
import win32api
1112
import win32file
1213
import win32con
1314
import winreg
15+
from win32com.shell import shell, shellcon
1416

1517
import logging
1618
logger = logging.getLogger("RemoveWindowsLockScreenAds")
@@ -48,6 +50,15 @@ def handler(ctrltype):
4850
def wrap_wait_call(func, *args, **kwargs):
4951
return func(*args, **kwargs)
5052

53+
def is_console_app():
54+
"""
55+
Returns True if PE SUBSYSTEM of sys.executable is CONSOLE
56+
"""
57+
res,_ = shell.SHGetFileInfo(sys.executable, 0, shellcon.SHGFI_EXETYPE)
58+
# LOWORD = NE or PE and HIWORD = Windows version --> Windows application.
59+
# LOWORD = PE and HIWORD = 0 --> Console application or .bat file.
60+
return res == struct.unpack("<H", b'PE')[0]
61+
5162
def GetAdSettingsDirectory(user=None):
5263
EXT = r"Packages\Microsoft.Windows.ContentDeliveryManager_cw5n1h2txyewy\LocalState\TargetedContentCache\v3\338387"
5364
if user is None:
@@ -164,7 +175,7 @@ def watch_dir(self, path):
164175
filepath = os.path.join(path, fname)
165176
self.remove_ads_file(filepath)
166177

167-
def __autorun_key(self, do_add, path=None):
178+
def __autorun_key(self, do_add, run_args=None, path=None):
168179
key = "RemoveWindowsLockScreenAds"
169180
with winreg.OpenKey(
170181
winreg.HKEY_CURRENT_USER,
@@ -174,7 +185,8 @@ def __autorun_key(self, do_add, path=None):
174185
if do_add:
175186
# Run key has maximum length of 260 chars, so make a .bat file
176187
bat_path = os.path.join(self.INSTALL_LOCATION, 'RemoveWindowsLockScreenAds.bat')
177-
cmdline = ['start', sys.executable, os.path.join(self.INSTALL_LOCATION, os.path.basename(__file__)), '--watch']
188+
cmdline = ['start'] + run_args + ['--watch']
189+
# sys.executable, os.path.join(self.INSTALL_LOCATION, os.path.basename(__file__)),
178190
if self.remove_credits:
179191
cmdline.append('--remove-credits')
180192
if path is not None:
@@ -192,16 +204,24 @@ def __autorun_key(self, do_add, path=None):
192204

193205
def install(self, path):
194206
# Show a warning if using python.exe
195-
if os.path.basename(sys.executable) == 'python.exe':
196-
logger.warning("WARNING: Installing using python.exe, a command prompt window will be left open. We recommend installing with pythonw.exe.")
207+
if is_console_app():
208+
logger.warning("WARNING: Installing using console application, a command prompt window will be left open. We recommend installing with pythonw.exe or RemoveWindowsLockScreenAds.noconsole.exe.")
197209

198210
try:
199-
# Copy self (script) to install location
211+
# Copy self to install location
200212
os.makedirs(self.INSTALL_LOCATION, exist_ok=True)
201-
shutil.copyfile(__file__, os.path.join(self.INSTALL_LOCATION, os.path.basename(__file__)))
213+
if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
214+
# Running from pyinstaller .exe
215+
inst_path = os.path.join(self.INSTALL_LOCATION, os.path.basename(sys.executable))
216+
run_args = [inst_path]
217+
else:
218+
# Running as python module
219+
inst_path = os.path.join(self.INSTALL_LOCATION, os.path.basename(__file__))
220+
run_args = [sys.executable, inst_path]
221+
shutil.copyfile(sys.executable, inst_path)
202222

203223
# Create startup key
204-
self.__autorun_key(True, path=path)
224+
self.__autorun_key(True, run_args=run_args, path=path)
205225
except Exception as e:
206226
logger.error("Installation failed: {}".format(e))
207227
self.uninstall()
@@ -258,13 +278,21 @@ def main(argv):
258278

259279
args = parser.parse_args(argv[1:])
260280

281+
# Set a log file for noconsole installation
282+
filename = None
283+
if not is_console_app() and (args.install or args.uninstall):
284+
filename = os.path.join(os.path.expandvars("%TEMP%"), "RemoveWindowsLockScreenAds.install.log")
285+
286+
# Set log level and configure logger
261287
if args.verbose:
262-
logging.basicConfig(level=logging.DEBUG)
288+
logging.basicConfig(filename=filename, level=logging.DEBUG)
263289
else:
264-
logging.basicConfig(format='%(message)s', level=logging.INFO)
290+
logging.basicConfig(filename=filename, format='%(message)s', level=logging.INFO)
265291

292+
# Create instance
266293
adrem = AdRemover(dry_run=args.dry_run, remove_credits=args.remove_credits)
267294

295+
# Perform requested action
268296
if args.install:
269297
if adrem.install(args.path):
270298
adrem.remove_ads_path(args.path)

release.ps1

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Pyinstaller helper to avoid repeating args
2+
function New-pyinstaller
3+
{
4+
{
5+
param
6+
(
7+
[String]$exemode
8+
)
9+
pyinstaller --$exemode --distpath="dist.exe" --onefile --add-data="LICENSE;." .\RemoveWindowsLockScreenAds\RemoveWindowsLockScreenAds.py
10+
Move-Item -Force "dist.exe\RemoveWindowsLockScreenAds.exe" "dist.exe\RemoveWindowsLockScreenAds.$exemode.exe"
11+
}.GetNewClosure()
12+
}
13+
$function:global:do_pyinstaller = New-pyinstaller
14+
15+
Remove-Item -Force -Recurse dist, dist.exe, build
16+
# Create standalone executables
17+
do_pyinstaller noconsole
18+
do_pyinstaller console
19+
20+
# Create pypi dist
21+
python setup.py sdist bdist_wheel
22+

0 commit comments

Comments
 (0)