[PYTHON] Machen Sie für VB6.

Vorwort

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) verhält sich nicht wie make. Mit anderen Worten, selbst wenn sich die Quellcode-Reihe nicht ändert, wird beim Ausführen der Kompilierung eine neue Binärdatei generiert. Das ist in Ordnung, aber jedes Mal, wenn Sie kompilieren, wird eine andere Binärdatei generiert. Das heißt, es ist nicht zu unterscheiden, ob die beiden Binärdateien funktional identisch sind oder geändert wurden. Dies ist das erste Problem.

Eine weitere gängige Konfiguration

\---Proj
  +---Common
  |     CommonModule.bas
  |
  +---PreExe
  |     PreExe.vbp ←CommonModule.Bas Referenzierung
  |
  +---MainExe
  |     MainExe.vbp ←CommonModule.Bas Referenzierung
  |
  \---PostExe
        PostExe.vbp ←CommonModule.bas nicht referenziert

Es ist üblich, Quellcode wie folgt auf der Ebene physischer Dateien freizugeben. Angenommen, Sie ändern eine Methode in CommonModule.bas im Ordner Common. Welches muss kompiliert werden, weil ich es geändert habe? Welches ist nicht notwendig? Es ist in Ordnung, alles von einem Ende zum nächsten zu kompilieren. Wenn Sie es jedoch ohne Notwendigkeit kompilieren, wird eine andere Binärdatei generiert, obwohl es keine funktionalen Änderungen wie beim ersten Problem gibt.

make-like Verhalten

make

Natürlich denke ich, dass dies mit dem ursprünglichen Befehl make realisiert werden kann, aber hier werde ich ein Programm schreiben, das vb-spezifisches make-like-Verhalten in Python 3 ausführt (make gibt es seit über 40 Jahren, warum also nicht in die VB6-Entwicklungsumgebung einfügen? War es ...)

Lesen Sie die VB-Projektdatei (.vbp) und führen Sie die Kompilierung aus, wenn eine der folgenden Bedingungen erfüllt ist.

--Executive Datei existiert nicht

Entwicklungsumgebung

Quellcode

Klasse, die Projektdateien verarbeitet (.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()

Klasse, die die in der Projektdatei beschriebenen Quelldateien (.bas, .cls, .frm) verarbeitet

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)

Körper

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)Ausführungsdatei existiert nicht
    # 2)Die VBP-Datei ist neuer als die ausführbare Datei
    # 3)Es gibt eine Quelldatei, die neuer als die ausführbare Datei ist
    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("Keine Kompilierung erforderlich")

Es gibt zwei vollständige Pfade für den Compiler, da das Installationsziel von VB6 je nach Betriebssystem und x86 / X64 unterschiedlich ist. Es scheint, dass Compiler1 W10 (x64) und Compiler2 W7 (x64) war.

Bonus

Verwenden Sie immer Batch-Dateien

make.bat


py vbmake.py %1

Ich mache so etwas, aber ich habe herausgefunden, was [pyinstaller] heißt (https://pypi.org/project/pyinstaller/), also werde ich es zu einer Exe machen. Great kann auch in einer Umgebung ohne Python ausgeführt werden.

>pip install pyinstaller

Tu es

>pyinstaller vbmake.py

das ist alles. Sicher genug, vbmake.exe über 10 MB wurde generiert (das ist richtig)

Recommended Posts

Machen Sie für VB6.
Machen Sie eine Tweet-Box für Pepper
Qt für Python App Desktop App
ROS-Kurs 107 Machen Sie einen Kunden für Rosblidge
Erstellen Sie ein Schachbrettmuster für die Kamerakalibrierung
Lassen Sie uns ein Backend-Plug-In für Errbot erstellen
So erstellen Sie ein Spigot-Plug-In (für Java-Anfänger)
Machen Sie vorerst ein Histogramm (matplotlib)
Lassen Sie uns mit SWIG ein Modul für Python erstellen
Wie man Python für Anfänger schneller macht [numpy]