├── requirements.txt ├── logos ├── README.md ├── 32x32.png └── 512x512.png ├── LICENSE ├── README.md ├── index.html ├── db.json └── main.py /requirements.txt: -------------------------------------------------------------------------------- 1 | colorama 2 | requests==2.20 3 | -------------------------------------------------------------------------------- /logos/README.md: -------------------------------------------------------------------------------- 1 | # credits: 2 | - @0penrc 3 | 4 | # preview: 5 | -------------------------------------------------------------------------------- /logos/32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abrik1/xpykg/HEAD/logos/32x32.png -------------------------------------------------------------------------------- /logos/512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abrik1/xpykg/HEAD/logos/512x512.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Abhiraj Rik 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## xpykg - manage software packages for Windows XP 2 | xpykg is a script for Windows XP which is capable of installing software 3 | packages so that users don't have to look on random webpages for software. 4 | 5 | xpykg downloads the setup.exe of the software package and then runs it. 6 | It also keeps track of the location of the uninstaller executable so that 7 | the user may easily uninstall the package when they need to. 8 | 9 | ### requirements: 10 | - Python 3.4 11 | - requests 2.20 12 | - colorama (colors are cool) 13 | - wmi (for Un_A.exe detection) 14 | 15 | **NOTE**: Right now it works only on Service Pack 3 for x86 and Service Pack 2 for x64 (DB needs some changes). 16 | 17 | ### todo: 18 | - [x] implement search 19 | - [x] implement sync 20 | - [x] implement list 21 | - [x] implement installing via msi or exe 22 | - [x] implement uninstalling 23 | - WIP, needs some more testing 24 | 25 | ### software: 26 | see db.json 27 | 28 | ## docs: 29 | see [the wiki](https://github.com/abrik1/xpykg/wiki) 30 | 31 | # contact: 32 | Join the `#xpykg` channel on irc.libera.chat, or see the [${\color{purple}discord\ server\colon}$](https://discord.gg/5Jwd7Sch88) 33 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | xpykg 4 | 50 | 51 | 52 | 53 |

54 | xpykg - a package manager for Windows XP 55 |

56 | 57 |

58 | xpykg is a package manager for Windows XP/ReactOS. It downloads files, runs setup.exe, and handles upgrades/uninstallations. 59 |

60 | 61 |

62 | usage: 63 |

64 | 65 |
66 | 67 | help: view this page
68 | install: install {pkg}
69 | list: show all the available apps
70 | search: search {pkg}
71 | sync: sync software databases
72 | uninstall: uninstall {pkg}
73 | upgrade: upgrade packages installed using xpkg
74 | version: show xpkg version 75 |
76 |
77 | 78 |

packages:

79 |

80 | refer to this table here 81 |

82 | 83 |

download:

84 |

85 | this page will redirect you to the github downloads page 86 |

87 | 88 |

credits:

89 | 93 | 94 | True/False 423 | determines whether a package is installed 424 | """ 425 | if isfile("C:\\Program Files\\xpykg\\installed-packages") == True: 426 | with open("C:\\Program Files\\xpykg\\installed-packages", "r") as database: 427 | contents = database.read() 428 | for i in contents.splitlines(): 429 | try: 430 | if literal_eval(i)[0] == pkgname: 431 | database.close() 432 | return True 433 | except SyntaxError: 434 | continue 435 | 436 | database.close() 437 | return False 438 | else: 439 | return False 440 | 441 | 442 | def get_installed_package_version(pkgname: str): 443 | """ 444 | get_installed_package_version(pkgname) 445 | if pkgname is installed by xpykg, return its version 446 | """ 447 | 448 | if is_installed(pkgname) == True: 449 | with open("C:\\Program Files\\xpykg\\installed-packages", "r") as database: 450 | contents = database.read().splitlines() 451 | for i in contents: 452 | if literal_eval(i)[0] == pkgname: 453 | database.close() 454 | return literal_eval(i)[1] # good output 455 | else: 456 | return 1 # bad output 457 | 458 | 459 | def arr_to_str(arr, optchar: str): 460 | nstr = "" 461 | for i in arr: 462 | nstr = nstr + i + optchar 463 | 464 | return nstr 465 | 466 | 467 | def uninstall_package(pkgname: str): 468 | """ 469 | uninstall_package(pkgname): remove pkgname if installed by xpykg 470 | """ 471 | if is_installed(pkgname) == True: 472 | with open("C:\\Program Files\\xpykg\\installed-packages", "r+") as ipkg: 473 | contents = ipkg.read().splitlines() 474 | index = 0 475 | remover = "" 476 | uninstall_type = "" 477 | for i in contents: 478 | try: 479 | if literal_eval(i)[0] == pkgname: 480 | index = contents.index(i) 481 | remover = literal_eval(i)[2] 482 | uninstall_type = literal_eval(i)[3] 483 | break 484 | except SyntaxError: 485 | continue 486 | 487 | remove = remover.split("\\") 488 | remove.pop(len(remove) - 1) 489 | chdir(arr_to_str(remove, "\\")) 490 | 491 | remover = remover.split("\\")[len(remover.split("\\")) - 1] 492 | 493 | print( 494 | "{}{}[xpykg:note]:{} loading remover for package {}{}{}".format( 495 | Style.BRIGHT, 496 | Fore.BLUE, 497 | Fore.RESET, 498 | Fore.YELLOW, 499 | pkgname, 500 | Fore.RESET, 501 | ) 502 | ) 503 | remove_status = system(remover) 504 | pkg_removed = False 505 | 506 | if remove_status == 0 and uninstall_type == "Normal": 507 | pkg_removed = True 508 | elif remove_status == 0 and uninstall_type == "nullsoftUninstaller": 509 | # using wmi check that Un_A.exe is running or not 510 | sleep(5) 511 | bin = "" 512 | while True: 513 | prcs = [] # array to store processes running 514 | for process in wmi.Win32_Process(): 515 | prcs.append(process.Name) 516 | 517 | if "Un_A.exe" in prcs: 518 | bin = "Un_A.exe" 519 | elif "Au_.exe" in prcs: 520 | bin = "Au_.exe" 521 | elif ( 522 | "Uninst.exe" in prcs 523 | ): # 7zip has a very similar uninstller to NSIS Installers. 524 | bin = "Uninst.exe" 525 | 526 | if (bin in prcs) == False: 527 | break # assumption that it has been uninstalled.. 528 | 529 | if isfile(remover) == True: 530 | pkg_removed = False 531 | else: 532 | pkg_removed = True 533 | else: 534 | print( 535 | "{}{}[xpykg:error]:{} {}{}{} not removed".format( 536 | Style.BRIGHT, 537 | Fore.RED, 538 | Fore.RESET, 539 | Fore.YELLOW, 540 | pkgname, 541 | Fore.RESET, 542 | ) 543 | ) 544 | ipkg.close() 545 | return 1 546 | 547 | if pkg_removed == False: 548 | print( 549 | "{}{}[xpykg:error]: {}{}{} not removed".format( 550 | Style.BRIGHT, Fore.RED, Fore.YELLOW, pkgname, Fore.RESET 551 | ) 552 | ) 553 | return 1 554 | else: 555 | print( 556 | "{}{}[xpykg:success]: {}{}{} removed".format( 557 | Style.BRIGHT, Fore.GREEN, Fore.YELLOW, pkgname, Fore.RESET 558 | ) 559 | ) 560 | contents.pop(index) 561 | ncontent = "" 562 | for j in contents: 563 | ncontent = ncontent + j + "\n" 564 | 565 | ipkg.seek(0) 566 | ipkg.write(ncontent) 567 | ipkg.truncate() 568 | ipkg.close() 569 | return 0 570 | else: 571 | print( 572 | "{}{}[xpykg:error]:{} package {}{}{} not installed".format( 573 | Style.BRIGHT, Fore.RED, Fore.RESET, Fore.YELLOW, pkgname, Fore.RESET 574 | ) 575 | ) 576 | return 1 577 | 578 | 579 | def vtoi(version: str): 580 | """ 581 | vtoi(version): convert a version to an integer... 22.10 -> 2210 582 | """ 583 | 584 | ver = "" 585 | 586 | for i in version: 587 | try: 588 | ver = ver + str(int(i)) 589 | except ValueError: 590 | continue 591 | 592 | return int(ver) 593 | 594 | 595 | def upgrade_packages(): 596 | """ 597 | upgrade_packages(): this function is a dummy for the upgrade function in xpykg 598 | """ 599 | 600 | print( 601 | "{}{}[xpykg:warning]:{} xpykg no longer supports upgrading. remove and install the program to upgrade it.".format( 602 | Style.BRIGHT, Fore.YELLOW, Fore.RESET 603 | ) 604 | return 1 605 | 606 | 607 | if __name__ == "__main__": 608 | try: 609 | if argv[1] in ["-h", "help", "--help"]: 610 | print( 611 | """xpykg: a script for software management for Windows XP 612 | ===================================================== 613 | help: view this page 614 | install: install 615 | list: show all the available apps 616 | search: search 617 | sync: sync software databases 618 | uninstall: uninstall 619 | upgrade: upgrade packages installed using xpykg 620 | version: show xpykg version""" 621 | ) 622 | elif argv[1] in ["-v", "version", "--version"]: 623 | print("[xpykg:version]: {}".format(xpykg_version)) 624 | elif argv[1] in ["-S", "sync", "--sync"]: 625 | sync_database() 626 | elif argv[1] in ["-l", "list", "--list"]: 627 | list_packages() 628 | elif argv[1] in ["-s", "search", "--search"] and len(argv) == 3: 629 | search_packages(argv[2]) 630 | elif argv[1] in ["-i", "install", "--install"]: 631 | if len(argv) == 3: 632 | install_package(argv[2]) 633 | else: 634 | for i in range(2, len(argv)): 635 | install_package(argv[i]) 636 | elif argv[1] in ["-u", "uninstall", "--uninstall"]: 637 | if len(argv) == 3: 638 | uninstall_package(argv[2]) 639 | else: 640 | for i in range(2, len(argv)): 641 | uninstall_package(argv[i]) 642 | elif argv[1] in ["-U", "upgrade", "--upgrade"]: 643 | upgrade_packages() 644 | else: 645 | print( 646 | "{}{}[xpykg:error]:{} invalid argument or not sufficient arguements".format( 647 | Style.BRIGHT, Fore.RED, Fore.RESET 648 | ) 649 | ) 650 | exit(1) 651 | except IndexError: 652 | print( 653 | "{}{}[xpykg:error]:{} invalid argument or not sufficient arguments".format( 654 | Style.BRIGHT, Fore.RED, Fore.RESET 655 | ) 656 | ) 657 | exit(1) 658 | except KeyboardInterrupt: 659 | print( 660 | "{}{}[xpykg:error]:{} keyboard exit detected".format( 661 | Style.BRIGHT, Fore.RED, Fore.RESET 662 | ) 663 | ) 664 | exit(1) 665 | except PermissionError: 666 | print( 667 | "{}{}[xpykg:error]:{} please run xpykg as Administrator".format( 668 | Style.BRIGHT, Fore.RED, Fore.RESET 669 | ) 670 | ) 671 | exit(1) 672 | --------------------------------------------------------------------------------