Skip to content

[pull] master from winpython:master #50

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
May 8, 2025
Merged
39 changes: 2 additions & 37 deletions make.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,6 @@ def _get_python_zip_file(self) -> Path:
@property
def package_index_markdown(self) -> str:
"""Generates a Markdown formatted package index page."""
installed_tools_markdown = self._get_installed_tools_markdown()
installed_packages_markdown = self._get_installed_packages_markdown()

return f"""## WinPython {self.winpyver2 + self.flavor}

The following packages are included in WinPython-{self.architecture_bits}bit v{self.winpyver2 + self.flavor} {self.release_level}.
Expand All @@ -115,49 +112,17 @@ def package_index_markdown(self) -> str:

Name | Version | Description
-----|---------|------------
{installed_tools_markdown}
{utils.get_installed_tools_markdown(utils.get_python_executable(self.python_executable_directory))}

### Python packages

Name | Version | Description
-----|---------|------------
[Python](http://www.python.org/) | {self.python_full_version} | Python programming language with standard library
{installed_packages_markdown}
{self.distribution.get_installed_packages_markdown()}

</details>
"""

def _get_installed_tools_markdown(self) -> str:
"""Generates Markdown for installed tools section in package index."""
tool_lines = []

if (nodejs_path := self.winpython_directory / NODEJS_RELATIVE_PATH).exists():
version = utils.exec_shell_cmd("node -v", nodejs_path).splitlines()[0]
tool_lines.append(f"[Nodejs](https://nodejs.org) | {version} | xa JavaScript runtime built on Chrome's V8 JavaScript engine")
version = utils.exec_shell_cmd("npm -v", nodejs_path).splitlines()[0]
tool_lines.append(f"[npmjs](https://www.npmjs.com) | {version} | a package manager for JavaScript")

if (pandoc_exe := self.winpython_directory / "t" / "pandoc.exe").exists():
version = utils.exec_shell_cmd("pandoc -v", pandoc_exe.parent).splitlines()[0].split(" ")[-1]
tool_lines.append(f"[Pandoc](https://pandoc.org) | {version} | an universal document converter")

if vscode_exe := (self.winpython_directory / "t" / "VSCode" / "Code.exe").exists():
version = utils.getFileProperties(str(vscode_exe))["FileVersion"]
tool_lines.append(f"[VSCode](https://code.visualstudio.com) | {version} | a source-code editor developed by Microsoft")

return "\n".join(tool_lines)

def _get_installed_packages_markdown(self) -> str:
"""Generates Markdown for installed packages section in package index."""
if not self.distribution:
return "" # Distribution not initialized yet.
self.installed_packages = self.distribution.get_installed_packages(update=True)
package_lines = [
f"[{pkg.name}]({pkg.url}) | {pkg.version} | {pkg.description}"
for pkg in sorted(self.installed_packages, key=lambda p: p.name.lower())
]
return "\n".join(package_lines)

@property
def winpython_version_name(self) -> str:
"""Returns the full WinPython version string."""
Expand Down
9 changes: 7 additions & 2 deletions portable/build_my_launchers.bat
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@ set VCVARS_PATH="C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\

rem pick the right ones and rename them in launchers_final
set do_launcher=%~dp0launchers_src\build_one_launcher.bat
set do_launcher_original=%~dp0launchers_src_original\build_one_launcher.bat

::WINDOWS launchers
call %do_launcher% "powershell.ico" "cmd_ps.bat" "WinPython Powershell Prompt" WINDOWS
call %do_launcher% "python.ico" "winidle.bat" "IDLE (Python GUI)" WINDOWS

echo displace this pause if you want to re-build more
pause
call %do_launcher% "python.ico" "winidle.bat" "IDLE (Python GUI)" WINDOWS
exit


call %do_launcher% "powershell.ico" "cmd_ps.bat" "WinPython Powershell Prompt" WINDOWS
call %do_launcher% "spyder.ico" "winspyder.bat" "Spyder" WINDOWS
call %do_launcher% "spyder_reset.ico" "spyder_reset.bat" "Spyder reset" WINDOWS
call %do_launcher% "code.ico" "winvscode.bat" "VS Code" WINDOWS
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added portable/launchers_final_original/Spyder.exe
Binary file not shown.
Binary file added portable/launchers_final_original/VS Code.exe
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
29 changes: 27 additions & 2 deletions portable/launchers_src/launcher_template_WINDOWS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,26 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR /
std::wstring exeDir = exePath;
exeDir = exeDir.substr(0, exeDir.find_last_of(L"\\/"));

// Get command line string and extract arguments
LPWSTR commandLine = GetCommandLineW();
std::wstring args;
// If executable path is double quoted, skip the entire quoted section
if (commandLine[0] == L'"') {
LPWSTR closingQuote = wcschr(commandLine + 1, L'"');
if (closingQuote) {
args = closingQuote + 1;
}
// For non-quoted path, skip to character after first space if it exists
} else {
LPWSTR spacePos = wcschr(commandLine, L' ');
if (spacePos) {
args = spacePos + 1;
}
}
// Strip leading whitespace
size_t args_start = args.find_first_not_of(L" ");
args = (args_start != std::wstring::npos) ? args.substr(args_start) : L"";

// Define the path to the "scripts" directory
std::wstring scriptsDir = exeDir + L"\\scripts";

Expand All @@ -37,8 +57,13 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR /
return 1;
}

// Define the command to run
std::wstring target = L"cmd.exe /c \"" LAUNCH_TARGET L"\"";
// Define the command to run and append arguments if present
std::wstring target;
if (!args.empty()) {
target = L"cmd.exe /c \"\"" LAUNCH_TARGET L"\" " + args + L"\"";
} else {
target = L"cmd.exe /c \"" LAUNCH_TARGET L"\"";
}

// Configure the process startup info
STARTUPINFO si = { sizeof(si) };
Expand Down
63 changes: 63 additions & 0 deletions portable/launchers_src_original/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
DataLab-WinPython license terms
===============================

DataLab-WinPython is a Python distribution for Windows:
- Based on WinPython, a portable distribution of Python for Windows (see section I. below).
- Including DataLab, an open-source platform for signal and image processing (see section II. below).

I. - WinPython License Agreement (MIT License)
----------------------------------------------

Copyright (c) 2012 Pierre Raybaut, 2016+ WinPython team

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

II. - DataLab License Agreement (BSD 3-Clause License)
------------------------------------------------------

Copyright (c) 2023, DataLab Platform Developers.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
107 changes: 107 additions & 0 deletions portable/launchers_src_original/build_one_launcher.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
@echo on
set icon_name=%1
set LAUNCH_TARGET=%2
set launcher_name=%3
set subsystem=%4

set icon_name=%icon_name:"=%
set LAUNCH_TARGET=%LAUNCH_TARGET:"=%
set launcher_name=%launcher_name:"=%
set subsystem=%subsystem:"=%

set ROOT_PATH=%~dp0..\
set SCRIPT_PATH=%~dp0
set TEMPO_PATH=%ROOT_PATH%launchers_temp
set OUTPUT_DIR=%ROOT_PATH%launchers_final

set "ICON_FILE=%ROOT_PATH%icons\%icon_name%"
set LAUNCHER_EXE=%OUTPUT_DIR%\%launcher_name%.exe


:: Paths to template WINDOWS or CONSOLE
set SOURCE_FILE=%SCRIPT_PATH%launcher_template_%subsystem%.cpp
echo SOURCE_FILE=%SOURCE_FILE%

set "RESOURCE_FILE=%TEMPO_PATH%\%icon_name%.rc"
set "RESOURCE_OBJ=%TEMPO_PATH%\%icon_name%.res"


:: create pDirectory if needed
if not exist "%OUTPUT_DIR%" mkdir "%OUTPUT_DIR%"
if not exist "%TEMPO_PATH%" mkdir "%TEMPO_PATH%"

cd/d %TEMPO_PATH%

:: Check if MSVC environment is already initialized
if not defined VSINSTALLDIR (
echo Initializing MSVC environment...
call %VCVARS_PATH%
if errorlevel 1 (
echo [ERROR] Failed to initialize MSVC environment.
exit /b 1
)
)

@echo on

:: Walk through .bat files in the current directory
echo Processing %icon_name%..
:: Stonebig: Remove previous .exe file
echo launcher_exe_action del /q "%LAUNCHER_EXE%"
if exist "%LAUNCHER_EXE%" (
move "%LAUNCHER_EXE%" "%LAUNCHER_EXE%.old.exe"
del /q "%LAUNCHER_EXE%.old.exe"
)
:: Stonebig: Remove intermediate .res and.rc file
if exist "%RESOURCE_OBJ%" (
move "%RESOURCE_OBJ%" "%RESOURCE_OBJ%.old.exe"
del /q "%RESOURCE_OBJ%.old.exe"
)
if exist "%RESOURCE_FILE%" (
move "%RESOURCE_FILE%" "%RESOURCE_FILE%.old.exe"
del /q "%RESOURCE_FILE%.old.exe"
)
:: Remove intermediate .obj file
del /q "launcher_template_%subsystem%.obj"

:: Check if the icon exists
if exist "%ICON_FILE%" (
echo Icon found: "%ICON_FILE%"
) else (
echo No icon found for "%ICON_FILE%" stoping
pause
exit
)


:: Create resource file
echo Creating resource file...
> "%RESOURCE_FILE%" echo IDI_ICON1 ICON "%ICON_FILE%"
:: Compile resource
echo Compiling resource...
rc /fo "%RESOURCE_OBJ%" "%RESOURCE_FILE%"

:: Compile the launcher executable
echo Compiling launcher executable...
cl /EHsc /O2 /DUNICODE /W4 "%SOURCE_FILE%" "%RESOURCE_OBJ%" ^
/Fe"%LAUNCHER_EXE%%" ^
/DLAUNCH_TARGET=\"%LAUNCH_TARGET%\" ^
User32.lib ^
/link /SUBSYSTEM:%subsystem%


if errorlevel 1 (
echo [ERROR] Failed to build launcher for %LAUNCH_TARGET%
exit /b 1
)

if exist "%LAUNCHER_EXE%" (
echo [SUCCESS] Launcher created: "%LAUNCHER_EXE%""
) else (
echo [ERROR] Failed to build launcher "%LAUNCHER_EXE%" from "%icon_name%" to call "%LAUNCH_TARGET%"
exit /b 1
)

echo All launchers processed.
rem exit /b 0

75 changes: 75 additions & 0 deletions portable/launchers_src_original/launcher_template_CONSOLE.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
DataLab-WinPython launcher script
---------------------------------

Licensed under the terms of the BSD 3-Clause
(see ./LICENSE for details)

*/

#include <windows.h>
#include <string>

int main() {
// Get the path to the current executable
wchar_t exePath[MAX_PATH];
GetModuleFileNameW(NULL, exePath, MAX_PATH);

// Determine the directory of the executable
std::wstring exeDir = exePath;
exeDir = exeDir.substr(0, exeDir.find_last_of(L"\\/"));

// Define the path to the "scripts" directory
std::wstring scriptsDir = exeDir + L"\\scripts";

// Check if the "scripts" directory exists
DWORD attributes = GetFileAttributesW(scriptsDir.c_str());
if (attributes == INVALID_FILE_ATTRIBUTES || !(attributes & FILE_ATTRIBUTE_DIRECTORY)) {
MessageBoxW(NULL, L"The 'scripts' directory does not exist. Please ensure it is in the same folder as the launcher.",
L"Launcher Error", MB_ICONERROR);
return 1;
}

// Set the working directory to the "scripts" folder
if (!SetCurrentDirectoryW(scriptsDir.c_str())) {
MessageBoxW(NULL, L"Failed to set the working directory to 'scripts'.",
L"Launcher Error", MB_ICONERROR);
return 1;
}

// Define the command to run
std::wstring target = L"cmd.exe /c \"" LAUNCH_TARGET L"\"";

// Configure the process startup info
STARTUPINFO si = { sizeof(si) };
si.dwFlags = STARTF_USESHOWWINDOW; // Prevent the window from appearing
si.wShowWindow = SW_HIDE; // Hide the command window

PROCESS_INFORMATION pi = {};

// Start the process without CREATE_NO_WINDOW flag to show the command window
if (!CreateProcessW(
NULL, // Application name (NULL because we pass the command in the command line)
&target[0], // Command line
NULL, // Process security attributes
NULL, // Thread security attributes
FALSE, // Inherit handles
0, // No special flags
NULL, // Environment block (NULL to inherit parent)
NULL, // Current directory (NULL to use the parent process's current directory)
&si, // Startup info
&pi // Process information
)) {
MessageBoxW(NULL, L"Failed to launch the script.", L"Launcher Error", MB_ICONERROR);
return 1;
}

// Wait for the script to finish
WaitForSingleObject(pi.hProcess, INFINITE);

// Cleanup
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);

return 0;
}
Loading