/
MrDubstep72
/
ProjectMigration
Обзор
Документация
Войти
/
MrDubstep72
/
ProjectMigration
Код
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
migration.py
233 строки
9 KB
MrDubstep72
Initial file without/with gui
24 фев 2026, 05:53
24 фев 2026, 05:53
9e2299b
Код
Авторство
О чём код?
import tkinter as tk from tkinter import filedialog, messagebox, ttk import os import re import xml.etree.ElementTree as ET from uuid import uuid4 import argparse # Заголовки для различных версий Visual Studio solution_headers = { "2013": """\ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 VisualStudioVersion = 12.0.31101.0 MinimumVisualStudioVersion = 10.0.40219.1 """, "2015": """\ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 VisualStudioVersion = 14.0.23107.0 MinimumVisualStudioVersion = 10.0.40219.1 """, "2017": """\ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.26430.4 MinimumVisualStudioVersion = 10.0.40219.1 """, "2019": """\ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.28701.123 MinimumVisualStudioVersion = 10.0.40219.1 """, "2022": """\ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31919.166 MinimumVisualStudioVersion = 10.0.40219.1 """, } class MigrationGUI(tk.Tk): def __init__(self): super().__init__() self.title("Developer to Visual Studio Converter") self.geometry("500x80") # Увеличение размера окна self.resizable(False, False) # Фрейм для группировки элементов main_frame = ttk.Frame(self) main_frame.grid(row=0, column=0, padx=0, pady=0, sticky="ew") # Компоненты UI self.workspace_label = ttk.Label(main_frame, text="Select Workspace Directory:") self.workspace_entry = ttk.Entry(main_frame, width=40) self.select_workspace_button = ttk.Button(main_frame, text="Select Workspace", command=self.select_workspace) self.output_label = ttk.Label(main_frame, text="Select Output Directory:") self.output_entry = ttk.Entry(main_frame, width=40) self.select_output_button = ttk.Button(main_frame, text="Select Output", command=self.select_output) self.version_label = ttk.Label(main_frame, text="Select Visual Studio Version:") self.version_combobox = ttk.Combobox(main_frame, values=["2013", "2015", "2017", "2019", "2022"], state="readonly", width=37) self.version_combobox.current(0) # Устанавливаем значение по умолчанию self.convert_button = ttk.Button(main_frame, text="Convert Projects", command=self.start_conversion) # Расположение компонентов self.workspace_label.grid(row=0, column=0, sticky="w") self.workspace_entry.grid(row=0, column=1, sticky="w") self.select_workspace_button.grid(row=0, column=2, sticky="ew") self.output_label.grid(row=1, column=0, sticky="w") self.output_entry.grid(row=1, column=1, sticky="w") self.select_output_button.grid(row=1, column=2, sticky="ew") self.version_label.grid(row=2, column=0, sticky="w") self.version_combobox.grid(row=2, column=1, sticky="w") self.convert_button.grid(row=2, column=2, sticky="ew") def select_workspace(self): folder_selected = filedialog.askdirectory() if folder_selected: self.workspace_entry.delete(0, tk.END) self.workspace_entry.insert(0, folder_selected) def select_output(self): folder_selected = filedialog.askdirectory() if folder_selected: self.output_entry.delete(0, tk.END) self.output_entry.insert(0, folder_selected) def start_conversion(self): workspace_directory = self.workspace_entry.get() output_directory = self.output_entry.get() selected_version = self.version_combobox.get() if not workspace_directory or not output_directory: messagebox.showwarning("Warning", "Please specify both directories.") return try: # Вызов основного метода миграции migrate_project(workspace_directory, output_directory, selected_version) messagebox.showinfo("Success", "Conversion completed successfully!") except Exception as e: messagebox.showerror("Error", f"An error occurred during conversion: {e}") # Основная логика миграции остается прежней def find_dsp_files(directory): found_projects = [] for dirpath, _, filenames in os.walk(directory): for filename in filenames: if filename.endswith('.dsp'): full_path = os.path.join(dirpath, filename) found_projects.append(full_path) return found_projects def process_dsp_file(dsp_path): config_data = {} with open(dsp_path, 'r', encoding='utf-8-sig') as f: data = f.read() # Извлекаем include-директории include_pattern = r'/I\s+"([^"]+)"' includes = re.findall(include_pattern, data) config_data['includes'] = includes # Извлекаем флаги компилятора compiler_flags_pattern = r'/([^\s]+)' compiler_flags = re.findall(compiler_flags_pattern, data) config_data['compiler_flags'] = compiler_flags # Получаем библиотеки линковщика library_pattern = r'-l\s+([^\s]+)' libraries = re.findall(library_pattern, data) config_data['libraries'] = libraries return config_data def create_vcxproj_xml(config_data, vcxproj_path): root = ET.Element('Project', {'DefaultTargets': 'Build', 'ToolsVersion': '4.0', 'xmlns': 'http://schemas.microsoft.com/developer/msbuild/2003'}) # Глобальные свойства property_group = ET.SubElement(root, 'PropertyGroup', Label='Globals') ET.SubElement(property_group, 'ProjectGuid').text = '{%s}' % uuid4() ET.SubElement(property_group, 'RootNamespace').text = 'YourProjectName' ET.SubElement(property_group, 'Keyword').text = 'MakeFileProj' # Дополнительные директории включения item_group = ET.SubElement(root, 'ItemGroup') cl_include = ET.SubElement(item_group, 'ClCompile') for inc in config_data.get('includes', []): ET.SubElement(cl_include, 'AdditionalIncludeDirectories').text = inc # Линкерские библиотеки linker = ET.SubElement(root, 'Link') lib_element = ET.SubElement(linker, 'AdditionalDependencies') lib_element.text = ';'.join(config_data.get('libraries', [])) # Компиляторские флаги comp = ET.SubElement(root, 'ClCompile') ET.SubElement(comp, 'PreprocessorDefinitions').text = ';'.join(config_data.get('compiler_flags', [])) # Формируем дерево элементов tree = ET.ElementTree(root) tree.write(vcxproj_path, encoding='utf-8', xml_declaration=True) def generate_sln_file(sln_path, projects, version, output_directory): solution_template = solution_headers.get(version, "") content = solution_template for proj in projects: proj_name = os.path.basename(proj) rel_path = os.path.dirname(proj) new_proj_filename = os.path.join(rel_path, proj_name + ".vcxproj") guid = '{%s}' % uuid4() content += f'Project("{{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}}") = "{proj_name}", "{new_proj_filename}", "{guid}"\n' content += "EndProject\n" global_section = """ Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 EndGlobalSection GlobalSection(PROJECTConfigurationPlatforms) = postSolution """ config_lines = ["\t\t%s.Debug|Win32.ActiveCfg = Debug|Win32" % uuid4().hex[:8]] global_section += "\n".join(config_lines) global_section += """ EndGlobalSection EndGlobal """ content += global_section sln_filename = os.path.basename(sln_path).replace(".dsp", ".sln") sln_full_path = os.path.join(output_directory, sln_filename) with open(sln_full_path, 'w') as sln_f: sln_f.write(content) def migrate_project(workspace_directory, output_directory, version): # Шаг 1: Найти все файлы .dsp projects = find_dsp_files(workspace_directory) # Шаг 2: Обработать каждый проект и создать .vcxproj for proj in projects: config_data = process_dsp_file(proj) vcxproj_path = os.path.join(output_directory, os.path.basename(proj) + '.vcxproj') create_vcxproj_xml(config_data, vcxproj_path) # Шаг 3: Создать итоговый файл .sln sln_path = os.path.join(output_directory, os.path.basename(projects[0]).replace('.dsp', '.sln')) generate_sln_file(sln_path, projects, version, output_directory) print(f"Проекты были успешно перенесены в {output_directory}.") if __name__ == '__main__': parser = argparse.ArgumentParser(description="Developer to Visual Studio Converter") parser.add_argument("--gui", action="store_true", help="Launch with GUI") parser.add_argument("input", nargs="?", help="Input workspace directory") parser.add_argument("output", nargs="?", help="Output directory") parser.add_argument("-v", "--version", nargs="?", help="Visual Studio version (2013, 2015, 2017, 2019, 2022)") args = parser.parse_args() if args.gui: app = MigrationGUI() app.mainloop() elif args.input and args.output and args.version: migrate_project(args.input, args.output, args.version) else: parser.print_help()