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.
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
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.
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