[PYTHON] Faites pour VB6.

Préface

VB6 [IDE](https://ja.wikipedia.org/wiki/%E7%B5%B1%E5%90%88%E9%96%8B%E7%99%BA%E7%92%B0%E5 % A2% 83) ne se comporte pas comme make. En d'autres termes, même s'il n'y a pas de changement dans la série de code source, un nouveau fichier binaire sera généré lorsque vous exécutez la compilation. C'est bien, mais chaque fois que vous compilez, un fichier binaire différent est généré. Autrement dit, il est impossible de distinguer si les deux fichiers binaires sont fonctionnellement identiques ou ont été modifiés. C'est le premier problème.

Une autre configuration courante

\---Proj
  +---Common
  |     CommonModule.bas
  |
  +---PreExe
  |     PreExe.vbp ←CommonModule.référencement bas
  |
  +---MainExe
  |     MainExe.vbp ←CommonModule.référencement bas
  |
  \---PostExe
        PostExe.vbp ←CommonModule.bas non référencé

Il est courant de partager le code source au niveau du fichier physique comme celui-ci. Supposons maintenant que vous modifiez une méthode dans CommonModule.bas dans le dossier Common. Lequel doit être compilé parce que je l'ai changé? Lequel n'est pas nécessaire? Il est normal de tout compiler, mais si vous le compilez sans que vous en ayez besoin, un binaire différent sera généré même s'il n'y a pas de changements fonctionnels comme le premier problème.

comportement de fabrication

make

Bien sûr, je pense que cela peut être réalisé en utilisant la commande make originale, mais j'écrirai ici un programme qui effectue un comportement de type make-like spécifique à vb dans Python 3 (make existe depuis plus de 40 ans, alors pourquoi ne pas le mettre dans l'environnement de développement VB6? Était-ce ...)

Reportez-vous au fichier de projet VB (.vbp) et exécutez la compilation si l'une des conditions suivantes est remplie.

Environnement de développement

Code source

Classe qui gère les fichiers de projet (.vbp)

projectfile.py


import child
import os

class ProjectFile:
    __lines = []
    __exe_name32 = ""
    __children = []

    def get_exe_name32(self):
        line = [i for i in self.__lines if i.startswith("ExeName32=")]

        if len(line) != 0:
            (_, value) = line[0].split('=')
            self.exe_name32 = value.replace('\"', '').replace('\n', '')

    def get_children(self):
        keys = ["Clas", "Form", "Modu"]

        servived_lines = [i for i in self.__lines if i[0:4] in keys]

        for line in servived_lines:
            c = child.Child(line, os.path.dirname(self.fullpath))
            self.__children.append(c)

    @property
    def exe_name32(self):
        return self.__exe_name32

    @exe_name32.setter
    def exe_name32(self, value):
        self.__exe_name32 = value

    @property
    def children(self):
        return self.__children

    def __init__(self, fullpath):
        self.fullpath = fullpath
        with open(fullpath, mode='r') as f:
            self.__lines = f.readlines()
        self.get_exe_name32()
        self.get_children()

Classe qui gère les fichiers source (.bas, .cls, .frm) décrits dans le fichier projet

child.py


import os
import datetime

class Child:
    __full_path = ""
    __last_write_time = ""

    @property
    def full_path(self):
        return self.__full_path

    @property
    def last_write_time(self):
        return self.__last_write_time

    def __init__(self, line, basepath):
        (_, value) = line.split('=')

        if (';' in value):
            (_, item) = value.split(';')
            filename = item.strip()
        else:
            filename = value.strip()

        self.__full_path = os.path.join(basepath, filename)
        self.__last_write_time = os.path.getmtime(self.__full_path)

Corps

vbmake.py


import projectfile
import sys
import os
import datetime
import subprocess

if __name__ == "__main__":
    if (len(sys.argv) != 2):
        print("vbmake.py vbpfullpath")
        x = input()
        exit

    vbp_full_path = sys.argv[1]
    vbp = projectfile.ProjectFile(vbp_full_path)
    exe_full_path = os.path.join(os.path.dirname(vbp_full_path), vbp.exe_name32)

    if os.path.exists(exe_full_path):
        standard_time_stamp = os.path.getmtime(exe_full_path)
        print(f"TimeStamp={datetime.datetime.fromtimestamp(standard_time_stamp)}")

        exe_not_found = False
        is_new_vbp = os.path.getmtime(vbp_full_path) > standard_time_stamp
        are_new_sources = any([i.last_write_time > standard_time_stamp for i in vbp.children])
    else:
        exe_not_found = True

    # 1)Le fichier d'exécution n'existe pas
    # 2)Le fichier VBP est plus récent que le fichier exécutable
    # 3)Il existe un fichier source plus récent que le fichier exécutable
    if exe_not_found or is_new_vbp or are_new_sources:
        compiler1 = "C:\\Program Files\\Microsoft Visual Studio\\VB98\\VB6.EXE"
        compiler2 = "C:\\Program Files (x86)\\Microsoft Visual Studio\\VB98\\VB6.EXE"
        option = "/make"

        if os.path.exists(compiler1):
            compiler = compiler1
        else:
            compiler = compiler2

        print(f"{compiler} {option} {vbp_full_path}")
        subprocess.run([compiler, option, vbp_full_path])
    else:
        print("Aucune compilation requise")

Il existe deux chemins complets pour le compilateur car la destination d'installation de VB6 est différente selon le système d'exploitation et x86 / X64. Il semble que le compilateur1 était W10 (x64) et le compilateur2 était W7 (x64).

prime

Toujours utiliser des fichiers batch

make.bat


py vbmake.py %1

Je fais quelque chose comme ça, mais j'ai découvert ce qu'on appelle pyinstaller, donc je vais en faire un exe. Great est capable de fonctionner même dans un environnement sans Python.

>pip install pyinstaller

fais le

>pyinstaller vbmake.py

c'est tout. Effectivement, vbmake.exe sur 10 Mo a été généré (c'est vrai)

Recommended Posts

Faites pour VB6.
Créer une boîte à Tweet pour Pepper
Qt pour l'application de bureau de l'application Python
Cours ROS 107 Créer un client pour rosblidge
Créez un modèle d'échiquier pour l'étalonnage de la caméra
Faisons un plug-in backend pour Errbot
Comment créer un plug-in Spigot (pour les débutants Java)
Faire un histogramme pour le moment (matplotlib)
Faisons un module pour Python en utilisant SWIG
Comment rendre le Python des débutants plus rapide [numpy]