@@ -1371,6 +1371,89 @@ get_version_info(wchar_t * version_text, size_t size)
13711371 }
13721372}
13731373
1374+ static void
1375+ show_help_text (wchar_t * * argv )
1376+ {
1377+ wchar_t version_text [MAX_PATH ];
1378+ #if defined(_M_X64 )
1379+ BOOL canDo64bit = TRUE;
1380+ #else
1381+ /* If we are a 32bit process on a 64bit Windows, first hit the 64bit keys. */
1382+ BOOL canDo64bit = FALSE;
1383+ IsWow64Process (GetCurrentProcess (), & canDo64bit );
1384+ #endif
1385+
1386+ get_version_info (version_text , MAX_PATH );
1387+ fwprintf (stdout , L"\
1388+ Python Launcher for Windows Version %ls\n\n" , version_text );
1389+ fwprintf (stdout , L"\
1390+ usage:\n\
1391+ %ls [launcher-args] [python-args] script [script-args]\n\n" , argv [0 ]);
1392+ fputws (L"\
1393+ Launcher arguments:\n\n\
1394+ -2 : Launch the latest Python 2.x version\n\
1395+ -3 : Launch the latest Python 3.x version\n\
1396+ -X.Y : Launch the specified Python version\n" , stdout );
1397+ if (canDo64bit ) {
1398+ fputws (L"\
1399+ The above all default to 64 bit if a matching 64 bit python is present.\n\
1400+ -X.Y-32: Launch the specified 32bit Python version\n\
1401+ -X-32 : Launch the latest 32bit Python X version\n\
1402+ -X.Y-64: Launch the specified 64bit Python version\n\
1403+ -X-64 : Launch the latest 64bit Python X version" , stdout );
1404+ }
1405+ fputws (L"\n-0 --list : List the available pythons" , stdout );
1406+ fputws (L"\n-0p --list-paths : List with paths" , stdout );
1407+ fputws (L"\n\nThe following help text is from Python:\n\n" , stdout );
1408+ fflush (stdout );
1409+ }
1410+
1411+ static BOOL
1412+ show_python_list (wchar_t * * argv )
1413+ {
1414+ /*
1415+ * Display options -0
1416+ */
1417+ INSTALLED_PYTHON * result = NULL ;
1418+ INSTALLED_PYTHON * ip = installed_pythons ; /* List of installed pythons */
1419+ INSTALLED_PYTHON * defpy = locate_python (L"" , FALSE);
1420+ size_t i = 0 ;
1421+ wchar_t * p = argv [1 ];
1422+ wchar_t * fmt = L"\n -%ls-%d" ; /* print VER-BITS */
1423+ wchar_t * defind = L" *" ; /* Default indicator */
1424+
1425+ /*
1426+ * Output informational messages to stderr to keep output
1427+ * clean for use in pipes, etc.
1428+ */
1429+ fwprintf (stderr ,
1430+ L"Installed Pythons found by %s Launcher for Windows" , argv [0 ]);
1431+ if (!_wcsicmp (p , L"-0p" ) || !_wcsicmp (p , L"--list-paths" )) /* Show path? */
1432+ fmt = L"\n -%ls-%d\t%ls" ; /* print VER-BITS path */
1433+
1434+ if (num_installed_pythons == 0 ) /* We have somehow got here without searching for pythons */
1435+ locate_all_pythons (); /* Find them, Populates installed_pythons */
1436+
1437+ if (num_installed_pythons == 0 ) /* No pythons found */
1438+ fwprintf (stderr , L"\nNo Installed Pythons Found!" );
1439+ else
1440+ {
1441+ for (i = 0 ; i < num_installed_pythons ; i ++ , ip ++ ) {
1442+ fwprintf (stdout , fmt , ip -> version , ip -> bits , ip -> executable );
1443+ /* If there is a default indicate it */
1444+ if ((defpy != NULL ) && !_wcsicmp (ip -> executable , defpy -> executable ))
1445+ fwprintf (stderr , defind );
1446+ }
1447+ }
1448+
1449+ if ((defpy == NULL ) && (num_installed_pythons > 0 ))
1450+ /* We have pythons but none is the default */
1451+ fwprintf (stderr , L"\n\nCan't find a Default Python.\n\n" );
1452+ else
1453+ fwprintf (stderr , L"\n\n" ); /* End with a blank line */
1454+ return (FALSE); /* If this has been called we cannot continue */
1455+ }
1456+
13741457static int
13751458process (int argc , wchar_t * * argv )
13761459{
@@ -1380,12 +1463,12 @@ process(int argc, wchar_t ** argv)
13801463 wchar_t * p ;
13811464 int rc = 0 ;
13821465 size_t plen ;
1466+ size_t slen ;
13831467 INSTALLED_PYTHON * ip ;
13841468 BOOL valid ;
13851469 DWORD size , attrs ;
13861470 HRESULT hr ;
13871471 wchar_t message [MSGSIZE ];
1388- wchar_t version_text [MAX_PATH ];
13891472 void * version_data ;
13901473 VS_FIXEDFILEINFO * file_info ;
13911474 UINT block_size ;
@@ -1516,12 +1599,22 @@ process(int argc, wchar_t ** argv)
15161599 else {
15171600 p = argv [1 ];
15181601 plen = wcslen (p );
1519- valid = (* p == L'-' ) && validate_version (& p [1 ]);
1602+ if (argc == 2 ) {
1603+ slen = wcslen (L"-0" );
1604+ if (!wcsncmp (p , L"-0" , slen )) /* Starts with -0 */
1605+ valid = show_python_list (argv ); /* Check for -0 FIRST */
1606+ }
1607+ valid = valid && (* p == L'-' ) && validate_version (& p [1 ]);
15201608 if (valid ) {
15211609 ip = locate_python (& p [1 ], FALSE);
15221610 if (ip == NULL )
1611+ {
1612+ fwprintf (stdout , \
1613+ L"Python %ls not found!\n" , & p [1 ]);
1614+ valid = show_python_list (argv );
15231615 error (RC_NO_PYTHON , L"Requested Python version (%ls) not \
1524- installed" , & p [1 ]);
1616+ installed, use -0 for available pythons" , & p [1 ]);
1617+ }
15251618 executable = ip -> executable ;
15261619 command += wcslen (p );
15271620 command = skip_whitespace (command );
@@ -1540,49 +1633,28 @@ installed", &p[1]);
15401633#endif
15411634
15421635 if (!valid ) {
1543- /* Look for an active virtualenv */
1544- executable = find_python_by_venv ();
1545-
1546- /* If we didn't find one, look for the default Python */
1547- if (executable == NULL ) {
1548- ip = locate_python (L"" , FALSE);
1549- if (ip == NULL )
1550- error (RC_NO_PYTHON , L"Can't find a default Python." );
1551- executable = ip -> executable ;
1552- }
1553- if ((argc == 2 ) && (!_wcsicmp (p , L"-h" ) || !_wcsicmp (p , L"--help" ))) {
1554- #if defined(_M_X64 )
1555- BOOL canDo64bit = TRUE;
1556- #else
1557- /* If we are a 32bit process on a 64bit Windows, first hit the 64bit keys. */
1558- BOOL canDo64bit = FALSE;
1559- IsWow64Process (GetCurrentProcess (), & canDo64bit );
1560- #endif
1561-
1562- get_version_info (version_text , MAX_PATH );
1563- fwprintf (stdout , L"\
1564- Python Launcher for Windows Version %ls\n\n" , version_text );
1565- fwprintf (stdout , L"\
1566- usage:\n\
1567- %ls [launcher-args] [python-args] script [script-args]\n\n" , argv [0 ]);
1568- fputws (L"\
1569- Launcher arguments:\n\n\
1570- -2 : Launch the latest Python 2.x version\n\
1571- -3 : Launch the latest Python 3.x version\n\
1572- -X.Y : Launch the specified Python version\n" , stdout );
1573- if (canDo64bit ) {
1574- fputws (L"\
1575- The above all default to 64 bit if a matching 64 bit python is present.\n\
1576- -X.Y-32: Launch the specified 32bit Python version\n\
1577- -X-32 : Launch the latest 32bit Python X version\n\
1578- -X.Y-64: Launch the specified 64bit Python version\n\
1579- -X-64 : Launch the latest 64bit Python X version" , stdout );
1636+ if ((argc == 2 ) && (!_wcsicmp (p , L"-h" ) || !_wcsicmp (p , L"--help" )))
1637+ show_help_text (argv );
1638+ if ((argc == 2 ) && (!_wcsicmp (p , L"-0" ) || !_wcsicmp (p , L"-0p" )))
1639+ executable = NULL ; /* Info call only */
1640+ else
1641+ {
1642+ /* Look for an active virtualenv */
1643+ executable = find_python_by_venv ();
1644+
1645+ /* If we didn't find one, look for the default Python */
1646+ if (executable == NULL ) {
1647+ ip = locate_python (L"" , FALSE);
1648+ if (ip == NULL )
1649+ error (RC_NO_PYTHON , L"Can't find a default Python." );
1650+ executable = ip -> executable ;
15801651 }
1581- fputws (L"\n\nThe following help text is from Python:\n\n" , stdout );
1582- fflush (stdout );
15831652 }
15841653 }
1585- invoke_child (executable , NULL , command );
1654+ if (executable != NULL )
1655+ invoke_child (executable , NULL , command );
1656+ else
1657+ rc = RC_NO_PYTHON ;
15861658 return rc ;
15871659}
15881660
0 commit comments