using System;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;
namespace 安装包打包工具
{
public partial class Form1 : Form
{
private string innoSetupPath = “”;
private string tempAppFolder = “”;
public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { // 设置默认版本号 txtVersion.Text = "v1.0"; // 设置默认产品名称 if (string.IsNullOrEmpty(txtProductName.Text)) { txtProductName.Text = "忠利模架CAD插件"; } // 设置默认安装路径为Autodesk的子目录 string appName = txtProductName.Text; txtInstallPath.Text = $@"C:\Program Files (x86)\Autodesk\{appName}"; // 初始化文件夹树形视图 InitializeFolderTree(); // 检查Inno Setup是否安装 CheckInnoSetupInstallation(); // 创建临时目录 tempAppFolder = Path.Combine(Path.GetTempPath(), $"app_temp_{Guid.NewGuid():N}"); } private void InitializeFolderTree() { treeViewFolder.Nodes.Clear(); treeViewFolder.CheckBoxes = true; treeViewFolder.AfterCheck += TreeViewFolder_AfterCheck; } private void CheckInnoSetupInstallation() { string innoPath = FindInnoSetupCompiler(); if (string.IsNullOrEmpty(innoPath)) { lblInnoStatus.Text = "Inno Setup: 未安装"; lblInnoStatus.ForeColor = System.Drawing.Color.Red; btnGenerate.Enabled = false; // 提供安装指引 MessageBox.Show( "未检测到 Inno Setup 安装。\n\n" + "请先安装 Inno Setup 5 或 6 版本:\n" + "1. 访问 http://www.jrsoftware.org/isdl.php\n" + "2. 下载并安装 Inno Setup\n" + "3. 重新启动本程序", "Inno Setup 未安装", MessageBoxButtons.OK, MessageBoxIcon.Warning); } else { innoSetupPath = Path.GetDirectoryName(innoPath); lblInnoStatus.Text = $"Inno Setup: 已安装 ({Path.GetFileName(innoSetupPath)})"; lblInnoStatus.ForeColor = System.Drawing.Color.Green; btnGenerate.Enabled = true; } } // ============ 安装包打包功能 ============ private void TreeViewFolder_AfterCheck(object sender, TreeViewEventArgs e) { if (e.Node.Nodes.Count > 0) { SetChildNodesCheckedState(e.Node, e.Node.Checked); } } private void SetChildNodesCheckedState(TreeNode parentNode, bool isChecked) { foreach (TreeNode childNode in parentNode.Nodes) { childNode.Checked = isChecked; SetChildNodesCheckedState(childNode, isChecked); } } // 选择主程序(单个文件) private void btnBrowseMain_Click(object sender, EventArgs e) { using (OpenFileDialog openFileDialog = new OpenFileDialog()) { openFileDialog.Filter = "可执行文件 (*.exe)|*.exe|所有文件 (*.*)|*.*"; openFileDialog.Title = "选择主程序文件"; if (openFileDialog.ShowDialog() == DialogResult.OK) { txtMainProgram.Text = openFileDialog.FileName; AddFileToTreeView(openFileDialog.FileName); // 自动获取程序信息 try { FileVersionInfo fileInfo = FileVersionInfo.GetVersionInfo(openFileDialog.FileName); if (!string.IsNullOrEmpty(fileInfo.FileVersion)) txtVersion.Text = fileInfo.FileVersion; if (!string.IsNullOrEmpty(fileInfo.ProductName)) txtProductName.Text = fileInfo.ProductName; } catch (Exception ex) { MessageBox.Show($"无法读取文件信息: {ex.Message}", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } } } // 选择包含exe的文件夹 private void btnBrowseFolder_Click(object sender, EventArgs e) { using (FolderBrowserDialog folderDialog = new FolderBrowserDialog()) { folderDialog.Description = "选择包含应用程序文件的文件夹"; folderDialog.ShowNewFolderButton = false; if (folderDialog.ShowDialog() == DialogResult.OK) { string selectedFolder = folderDialog.SelectedPath; txtSelectedFolder.Text = selectedFolder; // 扫描文件夹中的exe文件 ScanFolderForExecutables(selectedFolder); } } } // 扫描文件夹中的可执行文件 private void ScanFolderForExecutables(string folderPath) { try { treeViewFolder.Nodes.Clear(); // 添加根节点 TreeNode rootNode = new TreeNode(Path.GetFileName(folderPath)); rootNode.Tag = folderPath; rootNode.Checked = true; treeViewFolder.Nodes.Add(rootNode); // 递归扫描文件夹 ScanDirectory(folderPath, rootNode); // 展开第一层 rootNode.Expand(); // 自动选择第一个exe文件作为主程序 AutoSelectMainExecutable(folderPath); } catch (Exception ex) { MessageBox.Show($"扫描文件夹时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } // 递归扫描目录 private void ScanDirectory(string directoryPath, TreeNode parentNode) { try { // 添加文件 foreach (string file in Directory.GetFiles(directoryPath)) { string extension = Path.GetExtension(file).ToLower(); if (extension == ".exe" || extension == ".dll" || extension == ".config" || extension == ".lsp" || extension == ".xml" || extension == ".json" || extension == ".txt" || extension == ".bmp" || extension == ".png" || extension == ".ico" || extension == ".dwg" || extension == ".dxf") { TreeNode fileNode = new TreeNode(Path.GetFileName(file)); fileNode.Tag = file; fileNode.Checked = true; parentNode.Nodes.Add(fileNode); } } // 递归添加子目录 foreach (string subDirectory in Directory.GetDirectories(directoryPath)) { if (ShouldSkipDirectory(subDirectory)) continue; TreeNode dirNode = new TreeNode(Path.GetFileName(subDirectory)); dirNode.Tag = subDirectory; dirNode.Checked = true; parentNode.Nodes.Add(dirNode); ScanDirectory(subDirectory, dirNode); } } catch (UnauthorizedAccessException) { // 忽略无访问权限的目录 } catch (Exception ex) { Debug.WriteLine($"扫描目录 {directoryPath} 时出错: {ex.Message}"); } } // 判断是否应该跳过目录 private bool ShouldSkipDirectory(string directoryPath) { string dirName = Path.GetFileName(directoryPath).ToLower(); string[] skipDirs = { "bin", "obj", "debug", "release", ".git", ".vs", "packages" }; return Array.Exists(skipDirs, dir => dir == dirName); } // 自动选择主可执行文件 private void AutoSelectMainExecutable(string folderPath) { try { string[] exeFiles = Directory.GetFiles(folderPath, "*.exe"); if (exeFiles.Length > 0) { string mainExe = FindMainExecutable(exeFiles); if (mainExe != null) { txtMainProgram.Text = mainExe; try { FileVersionInfo fileInfo = FileVersionInfo.GetVersionInfo(mainExe); if (!string.IsNullOrEmpty(fileInfo.FileVersion)) txtVersion.Text = fileInfo.FileVersion; if (!string.IsNullOrEmpty(fileInfo.ProductName)) txtProductName.Text = fileInfo.ProductName; } catch (Exception ex) { Debug.WriteLine($"无法读取文件信息: {ex.Message}"); } } } } catch (Exception ex) { Debug.WriteLine($"自动选择主程序时出错: {ex.Message}"); } } // 查找最可能的主程序 private string FindMainExecutable(string[] exeFiles) { foreach (string exe in exeFiles) { string fileName = Path.GetFileName(exe).ToLower(); if (!fileName.Contains("vshost") && !fileName.Contains("test") && !fileName.Contains("setup")) { return exe; } } return exeFiles.Length > 0 ? exeFiles[0] : null; } // 添加单个文件到树形视图 private void AddFileToTreeView(string filePath) { if (treeViewFolder.Nodes.Count == 0) { TreeNode rootNode = new TreeNode("选择的文件"); rootNode.Checked = true; treeViewFolder.Nodes.Add(rootNode); } TreeNode fileNode = new TreeNode(Path.GetFileName(filePath)); fileNode.Tag = filePath; fileNode.Checked = true; treeViewFolder.Nodes[0].Nodes.Add(fileNode); treeViewFolder.Nodes[0].Expand(); } // 获取所有选中的文件 private List<string> GetSelectedFiles() { List<string> selectedFiles = new List<string>(); if (treeViewFolder.Nodes.Count > 0) { CollectSelectedFiles(treeViewFolder.Nodes[0], selectedFiles); } // 添加附加文件 foreach (var item in listBoxAdditionalFiles.Items) { string filePath = item.ToString(); if (File.Exists(filePath)) { selectedFiles.Add(filePath); } } return selectedFiles; } // 递归收集选中的文件 private void CollectSelectedFiles(TreeNode node, List<string> selectedFiles) { if (node.Checked && node.Tag is string filePath && File.Exists(filePath)) { selectedFiles.Add(filePath); } foreach (TreeNode childNode in node.Nodes) { CollectSelectedFiles(childNode, selectedFiles); } } // 检查是否包含CAD插件文件夹 - 增强版本 private bool ContainsCADPluginFolder(List<string> files) { foreach (string file in files) { if (file.Contains("Zhongli Mojia Software.bundle")) { Debug.WriteLine($"找到CAD插件文件夹: {file}"); return true; } // 同时检查可能的不同命名方式 if (file.ToLower().Contains("zhongli") || file.ToLower().Contains("mojia") || file.Contains(".bundle")) { Debug.WriteLine($"找到可能的CAD插件文件: {file}"); } } // 额外检查:在临时目录中查找 if (Directory.Exists(tempAppFolder)) { string[] bundleDirs = Directory.GetDirectories(tempAppFolder, "*bundle*", SearchOption.AllDirectories); foreach (string bundleDir in bundleDirs) { Debug.WriteLine($"在临时目录中找到bundle文件夹: {bundleDir}"); if (bundleDir.Contains("Zhongli") || bundleDir.Contains("Mojia")) { Debug.WriteLine($"确认找到CAD插件文件夹: {bundleDir}"); return true; } } } return false; } // 选择图标 private void btnBrowseIcon_Click(object sender, EventArgs e) { using (OpenFileDialog openFileDialog = new OpenFileDialog()) { openFileDialog.Filter = "图标文件 (*.ico)|*.ico|所有文件 (*.*)|*.*"; openFileDialog.Title = "选择应用程序图标"; if (openFileDialog.ShowDialog() == DialogResult.OK) { txtIconPath.Text = openFileDialog.FileName; try { pictureBoxIcon.Image = System.Drawing.Icon.ExtractAssociatedIcon(openFileDialog.FileName).ToBitmap(); } catch { pictureBoxIcon.Image = null; } } } } // 选择安装路径 private void btnBrowseInstallPath_Click(object sender, EventArgs e) { using (FolderBrowserDialog folderDialog = new FolderBrowserDialog()) { folderDialog.Description = "选择默认安装目录"; folderDialog.SelectedPath = txtInstallPath.Text; if (folderDialog.ShowDialog() == DialogResult.OK) { txtInstallPath.Text = folderDialog.SelectedPath; } } } // 刷新文件夹视图 private void btnRefreshFolder_Click(object sender, EventArgs e) { if (!string.IsNullOrEmpty(txtSelectedFolder.Text) && Directory.Exists(txtSelectedFolder.Text)) { ScanFolderForExecutables(txtSelectedFolder.Text); } } // 生成安装包 - 修复版本 private void btnGenerate_Click(object sender, EventArgs e) { // 移除主程序文件检查,允许没有主程序文件 if (string.IsNullOrEmpty(txtProductName.Text)) { MessageBox.Show("请输入产品名称", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } List<string> selectedFiles = GetSelectedFiles(); if (selectedFiles.Count == 0) { MessageBox.Show("请选择要打包的文件", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } using (SaveFileDialog saveDialog = new SaveFileDialog()) { // 优化文件名生成:确保版本号格式正确 string productName = txtProductName.Text.Trim(); string version = txtVersion.Text.Trim(); // 构建文件名:产品名称 + 空格 + 版本号 string fileName = productName; if (!string.IsNullOrEmpty(version)) { // 确保版本号格式正确,移除可能的多余字符 version = version.Replace("_", "."); // 将下划线替换为点 fileName += $" {version}"; } saveDialog.Filter = "安装包文件 (*.exe)|*.exe"; saveDialog.FileName = fileName; saveDialog.Title = "保存安装包"; if (saveDialog.ShowDialog() == DialogResult.OK) { try { progressBar.Value = 0; btnGenerate.Enabled = false; // 使用Inno Setup生成安装包 bool success = GenerateInnoSetupScript(saveDialog.FileName, selectedFiles); if (success) { progressBar.Value = 100; MessageBox.Show($"安装包生成成功!\n保存位置: {saveDialog.FileName}", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information); // 打开输出目录 string outputDir = Path.GetDirectoryName(saveDialog.FileName); if (Directory.Exists(outputDir)) { Process.Start("explorer.exe", outputDir); } } else { MessageBox.Show("安装包生成失败,请检查Inno Setup安装和配置。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } catch (Exception ex) { MessageBox.Show($"生成安装包时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { progressBar.Value = 0; btnGenerate.Enabled = true; // 清理临时目录 CleanupTempFolder(); } } } } // 修复的Inno Setup脚本生成方法 private bool GenerateInnoSetupScript(string outputPath, List<string> files) { try { // 准备临时文件目录 PrepareTempAppFolder(files); string scriptContent = CreateInnoScriptContent(outputPath, files); string scriptPath = Path.Combine(Path.GetTempPath(), $"setup_script_{Guid.NewGuid():N}.iss"); File.WriteAllText(scriptPath, scriptContent, Encoding.UTF8); // 调试:显示生成的脚本内容 Debug.WriteLine("=== 生成的Inno Setup脚本 ==="); Debug.WriteLine(scriptContent); Debug.WriteLine("=== 脚本结束 ==="); // 编译Inno Setup脚本 bool result = CompileInnoSetupScript(scriptPath, outputPath); // 清理临时文件 try { if (File.Exists(scriptPath)) File.Delete(scriptPath); } catch { } return result; } catch (Exception ex) { MessageBox.Show($"生成脚本时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } } // 准备临时应用程序文件夹 private void PrepareTempAppFolder(List<string> files) { // 清理临时目录 CleanupTempFolder(); // 创建临时目录 Directory.CreateDirectory(tempAppFolder); Debug.WriteLine($"=== 开始准备临时应用程序文件夹 ==="); Debug.WriteLine($"临时目录: {tempAppFolder}"); Debug.WriteLine($"文件总数: {files.Count}"); // 复制所有文件到临时目录,保持目录结构 foreach (string file in files) { try { string relativePath = GetRelativePath(file, files); string destPath = Path.Combine(tempAppFolder, relativePath); // 确保目标目录存在 string destDir = Path.GetDirectoryName(destPath); if (!Directory.Exists(destDir)) { Directory.CreateDirectory(destDir); Debug.WriteLine($"创建目录: {destDir}"); } File.Copy(file, destPath, true); Debug.WriteLine($"复制文件: {file} -> {destPath}"); // 特别记录CAD插件文件 if (file.Contains("Zhongli Mojia Software.bundle")) { Debug.WriteLine($"!!! CAD插件文件已复制: {file} -> {destPath}"); } } catch (Exception ex) { Debug.WriteLine($"!!! 复制文件 {file} 失败: {ex.Message}"); } } // 详细检查临时目录结构 Debug.WriteLine("=== 临时目录完整结构 ==="); DisplayDirectoryStructure(tempAppFolder, 0); Debug.WriteLine("=== 结构显示结束 ==="); } // 辅助方法:显示目录结构 private void DisplayDirectoryStructure(string directory, int indentLevel) { string indent = new string(' ', indentLevel * 2); try { // 显示文件 foreach (string file in Directory.GetFiles(directory)) { Debug.WriteLine($"{indent}📄 {Path.GetFileName(file)}"); } // 递归显示子目录 foreach (string subDir in Directory.GetDirectories(directory)) { string dirName = Path.GetFileName(subDir); Debug.WriteLine($"{indent}📁 {dirName}/"); DisplayDirectoryStructure(subDir, indentLevel + 1); } } catch (Exception ex) { Debug.WriteLine($"{indent}❌ 访问目录失败: {ex.Message}"); } } // 获取文件的相对路径 - 改进版本 private string GetRelativePath(string filePath, List<string> allFiles) { // 如果文件在CAD插件文件夹中,保持完整路径结构 if (filePath.Contains("Zhongli Mojia Software.bundle")) { // 找到bundle文件夹的起始位置 int bundleIndex = filePath.IndexOf("Zhongli Mojia Software.bundle"); if (bundleIndex >= 0) { string relativePath = filePath.Substring(bundleIndex); Debug.WriteLine($"CAD插件文件相对路径: {relativePath}"); return relativePath; } } // 找出共同的基础目录 string commonBase = FindCommonBaseDirectory(allFiles); if (!string.IsNullOrEmpty(commonBase) && filePath.StartsWith(commonBase)) { string relativePath = filePath.Substring(commonBase.Length).TrimStart(Path.DirectorySeparatorChar); Debug.WriteLine($"普通文件相对路径: {relativePath} (基础目录: {commonBase})"); return relativePath; } string fileNameOnly = Path.GetFileName(filePath); Debug.WriteLine($"仅文件名: {fileNameOnly}"); return fileNameOnly; } // 找出所有文件的共同基础目录 private string FindCommonBaseDirectory(List<string> files) { if (files == null || files.Count == 0) return null; string firstFile = files[0]; string baseDir = Path.GetDirectoryName(firstFile); foreach (string file in files.Skip(1)) { string fileDir = Path.GetDirectoryName(file); while (!string.IsNullOrEmpty(baseDir) && !fileDir.StartsWith(baseDir) && baseDir.Length > 0) { baseDir = Path.GetDirectoryName(baseDir); if (baseDir == null) break; } } return baseDir; } // 清理临时文件夹 private void CleanupTempFolder() { try { if (Directory.Exists(tempAppFolder)) { Directory.Delete(tempAppFolder, true); Debug.WriteLine("临时目录已清理"); } } catch (Exception ex) { Debug.WriteLine($"清理临时文件夹失败: {ex.Message}"); } } private string CreateInnoScriptContent(string outputPath, List<string> files) { string appName = txtProductName.Text; string appVersion = txtVersion.Text; string company = string.IsNullOrEmpty(txtCompanyName.Text) ? "我的公司" : txtCompanyName.Text; // 使用应用程序名称作为子目录 string installDir = $@"{{autopf}}\{appName}"; string outputDir = Path.GetDirectoryName(outputPath); string outputBaseName = Path.GetFileNameWithoutExtension(outputPath); StringBuilder sb = new StringBuilder(); // ==================== [Setup] 部分 ==================== sb.AppendLine(@"[Setup]"); sb.AppendLine($"AppName={appName}"); sb.AppendLine($"AppVersion={appVersion}"); sb.AppendLine($"AppVerName={appName} {appVersion}"); sb.AppendLine($"AppPublisher={company}"); sb.AppendLine($"DefaultDirName={installDir}"); sb.AppendLine("AppendDefaultDirName=no"); sb.AppendLine("UsePreviousAppDir=no"); sb.AppendLine("DisableDirPage=no"); sb.AppendLine("DirExistsWarning=no"); sb.AppendLine("DisableProgramGroupPage=yes"); sb.AppendLine($"OutputDir={outputDir}"); sb.AppendLine($"OutputBaseFilename={outputBaseName}"); sb.AppendLine("Compression=lzma"); sb.AppendLine("SolidCompression=yes"); sb.AppendLine("SetupLogging=yes"); sb.AppendLine("PrivilegesRequired=admin"); // 添加管理员权限 sb.AppendLine("AppId=ZhongliMojiaCADPlugin"); sb.AppendLine("DisableFinishedPage=no"); sb.AppendLine("DisableWelcomePage=no"); sb.AppendLine("ShowComponentSizes=no"); sb.AppendLine("UsePreviousTasks=no"); sb.AppendLine("CreateUninstallRegKey=yes"); sb.AppendLine("Uninstallable=yes"); // 添加卸载文件锁定处理 sb.AppendLine("UninstallFilesDir={app}"); // 确保卸载文件在应用目录 if (!string.IsNullOrEmpty(txtIconPath.Text) && File.Exists(txtIconPath.Text)) { sb.AppendLine($"SetupIconFile={txtIconPath.Text}"); } // ==================== [Languages] 部分 ==================== sb.AppendLine(@"[Languages]"); string chineseLangPath = Path.Combine(innoSetupPath, "Languages", "ChineseSimplified.isl"); if (File.Exists(chineseLangPath)) { sb.AppendLine(@"Name: ""chinesesimplified""; MessagesFile: ""compiler:Languages\ChineseSimplified.isl"""); } else { sb.AppendLine(@"Name: ""english""; MessagesFile: ""compiler:Default.isl"""); } // ==================== [Files] 部分 ==================== sb.AppendLine(@"[Files]"); bool hasCADPlugin = ContainsCADPluginFolder(files); foreach (string file in files) { string relativePath = GetRelativePath(file, files); string sourcePath = Path.Combine(tempAppFolder, relativePath); if (hasCADPlugin && relativePath.Contains("Zhongli Mojia Software.bundle")) { string cadRelativePath = relativePath.Substring(relativePath.IndexOf("Zhongli Mojia Software.bundle")); string destDir = @"{commonappdata}\Autodesk\ApplicationPlugins\" + Path.GetDirectoryName(cadRelativePath); sb.AppendLine($@"Source: ""{sourcePath}""; DestDir: ""{destDir}""; Flags: ignoreversion nocompression"); } else { string destDir = "{app}"; if (!string.IsNullOrEmpty(Path.GetDirectoryName(relativePath))) { destDir += "\\" + Path.GetDirectoryName(relativePath); } sb.AppendLine($@"Source: ""{sourcePath}""; DestDir: ""{destDir}""; Flags: ignoreversion"); } } // ==================== [Icons] 部分 ==================== if (!string.IsNullOrEmpty(txtMainProgram.Text) && File.Exists(txtMainProgram.Text)) { sb.AppendLine(@"[Icons]"); string mainExe = Path.GetFileName(txtMainProgram.Text); sb.AppendLine($@"Name: ""{{autodesktop}}\{appName}""; Filename: ""{{app}}\{mainExe}"""); sb.AppendLine($@"Name: ""{{autoprograms}}\{appName}""; Filename: ""{{app}}\{mainExe}"""); } // ==================== [Run] 部分 ==================== if (!string.IsNullOrEmpty(txtMainProgram.Text) && File.Exists(txtMainProgram.Text)) { string mainExe = Path.GetFileName(txtMainProgram.Text); bool mainExeIncluded = files.Any(f => string.Equals(Path.GetFileName(f), mainExe, StringComparison.OrdinalIgnoreCase)); if (mainExeIncluded) { sb.AppendLine(@"[Run]"); sb.AppendLine($@"Filename: ""{{app}}\{mainExe}""; Description: ""运行 {appName}""; Flags: nowait postinstall skipifsilent"); } } // ==================== [UninstallRun] 部分 ==================== sb.AppendLine(@"[UninstallRun]"); sb.AppendLine(@"Filename: ""{app}\unins000.exe""; Flags: runhidden"); // ==================== [UninstallDelete] 部分 ==================== sb.AppendLine(@"[UninstallDelete]"); sb.AppendLine(@"Type: filesandordirs; Name: ""{app}"""); sb.AppendLine(@"Type: filesandordirs; Name: ""{commonappdata}\Autodesk\ApplicationPlugins\Zhongli Mojia Software.bundle"""); // ==================== [Code] 部分 ==================== sb.AppendLine(@"[Code]"); // 声明Windows API函数 sb.AppendLine(@"function FindWindow(lpClassName, lpWindowName: PAnsiChar): HWND;"); sb.AppendLine(@"external 'FindWindowA@user32.dll stdcall';"); sb.AppendLine(@""); sb.AppendLine(@"function PostMessage(hWnd: HWND; Msg: UINT; wParam, lParam: Longint): BOOL;"); sb.AppendLine(@"external 'PostMessageA@user32.dll stdcall';"); sb.AppendLine(@""); sb.AppendLine(@"const"); sb.AppendLine(@" WM_CLOSE = 16;"); sb.AppendLine(@" PROCESS_TERMINATE = $0001;"); sb.AppendLine(@""); sb.AppendLine(@"function TerminateProcessByID(ProcessID: DWORD): Boolean;"); sb.AppendLine(@"external 'TerminateProcess@kernel32.dll stdcall';"); sb.AppendLine(@""); sb.AppendLine(@"function OpenProcess(dwDesiredAccess: DWORD; bInheritHandle: BOOL; dwProcessId: DWORD): THandle;"); sb.AppendLine(@"external 'OpenProcess@kernel32.dll stdcall';"); sb.AppendLine(@""); sb.AppendLine(@"function CloseHandle(hObject: THandle): BOOL;"); sb.AppendLine(@"external 'CloseHandle@kernel32.dll stdcall';"); sb.AppendLine(@""); // 查找并关闭主程序 sb.AppendLine(@"procedure CloseMainApplication();"); sb.AppendLine(@"var"); sb.AppendLine(@" hWnd: HWND;"); sb.AppendLine(@" processID: DWORD;"); sb.AppendLine(@" hProcess: THandle;"); sb.AppendLine(@"begin"); sb.AppendLine(@" hWnd := FindWindow(nil, '忠利模架CAD插件');"); sb.AppendLine(@" if hWnd <> 0 then"); sb.AppendLine(@" begin"); sb.AppendLine(@" PostMessage(hWnd, WM_CLOSE, 0, 0);"); sb.AppendLine(@" Sleep(1000); // 等待进程退出"); sb.AppendLine(@" end;"); sb.AppendLine(@" "); sb.AppendLine(@" // 强制终止同名进程"); sb.AppendLine(@" if Exec('taskkill', '/F /IM ""忠利模架CAD插件.exe""', '', SW_HIDE, ewWaitUntilTerminated, processID) then"); sb.AppendLine(@" begin"); sb.AppendLine(@" Log('成功终止主进程');"); sb.AppendLine(@" end;"); sb.AppendLine(@"end;"); sb.AppendLine(@""); // 安全删除文件(带重试机制) sb.AppendLine(@"function SafeDeleteFile(const FileName: string): Boolean;"); sb.AppendLine(@"var"); sb.AppendLine(@" Tries: Integer;"); sb.AppendLine(@"begin"); sb.AppendLine(@" Tries := 0;"); sb.AppendLine(@" Result := False;"); sb.AppendLine(@" "); sb.AppendLine(@" while Tries < 5 do"); sb.AppendLine(@" begin"); sb.AppendLine(@" if DeleteFile(FileName) then"); sb.AppendLine(@" begin"); sb.AppendLine(@" Result := True;"); sb.AppendLine(@" Break;"); sb.AppendLine(@" end;"); sb.AppendLine(@" "); sb.AppendLine(@" Sleep(1000); // 等待1秒后重试"); sb.AppendLine(@" Tries := Tries + 1;"); sb.AppendLine(@" end;"); sb.AppendLine(@" "); sb.AppendLine(@" if not Result then"); sb.AppendLine(@" Log('无法删除文件: ' + FileName + ' | 错误代码: ' + IntToStr(DLLGetLastError));"); sb.AppendLine(@"end;"); sb.AppendLine(@""); // 安全删除目录 sb.AppendLine(@"function SafeDeleteDirectory(const DirName: string): Boolean;"); sb.AppendLine(@"var"); sb.AppendLine(@" Tries: Integer;"); sb.AppendLine(@"begin"); sb.AppendLine(@" Tries := 0;"); sb.AppendLine(@" Result := False;"); sb.AppendLine(@" "); sb.AppendLine(@" while Tries < 5 do"); sb.AppendLine(@" begin"); sb.AppendLine(@" if DelTree(DirName, True, True, True) then"); sb.AppendLine(@" begin"); sb.AppendLine(@" Result := True;"); sb.AppendLine(@" Break;"); sb.AppendLine(@" end;"); sb.AppendLine(@" "); sb.AppendLine(@" Sleep(2000); // 等待2秒后重试"); sb.AppendLine(@" Tries := Tries + 1;"); sb.AppendLine(@" end;"); sb.AppendLine(@"end;"); sb.AppendLine(@""); // 注册重启后删除 sb.AppendLine(@"procedure RegisterRestartDelete(const FileName: string);"); sb.AppendLine(@"begin"); sb.AppendLine(@" RegWriteStringValue(HKEY_LOCAL_MACHINE, "); sb.AppendLine(@" 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', "); sb.AppendLine(@" 'PendingFileRenameOperations', "); sb.AppendLine(@" '\??\' + FileName + #0);"); sb.AppendLine(@"end;"); sb.AppendLine(@""); // 在常见路径中查找AutoCAD - 必须先定义 sb.AppendLine(@"procedure FindAutoCADInCommonPath(basePath: string; var paths: TArrayOfString);"); sb.AppendLine(@"var"); sb.AppendLine(@" subDirs: TArrayOfString;"); sb.AppendLine(@" i: Integer;"); sb.AppendLine(@" acadExePath: string;"); sb.AppendLine(@"begin"); sb.AppendLine(@" if FindSubDirectories(basePath, subDirs) then"); sb.AppendLine(@" begin"); sb.AppendLine(@" for i := 0 to GetArrayLength(subDirs) - 1 do"); sb.AppendLine(@" begin"); sb.AppendLine(@" acadExePath := subDirs[i] + '\\acad.exe';"); sb.AppendLine(@" if FileExists(acadExePath) then"); sb.AppendLine(@" begin"); sb.AppendLine(@" SetArrayLength(paths, GetArrayLength(paths) + 1);"); sb.AppendLine(@" paths[GetArrayLength(paths) - 1] := subDirs[i];"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@"end;"); sb.AppendLine(@""); // 查找AutoCAD安装路径 - 简化版本 sb.AppendLine(@"function FindAutoCADInstallations(): TArrayOfString;"); sb.AppendLine(@"var"); sb.AppendLine(@" paths: TArrayOfString;"); sb.AppendLine(@" versions, acadPaths: TArrayOfString;"); sb.AppendLine(@" i, j: Integer;"); sb.AppendLine(@" location: string;"); sb.AppendLine(@" acadExePath: string;"); sb.AppendLine(@"begin"); sb.AppendLine(@" SetArrayLength(paths, 0);"); sb.AppendLine(@" "); sb.AppendLine(@" // 方法1: 通过注册表查找AutoCAD安装路径"); sb.AppendLine(@" if RegGetSubkeyNames(HKEY_LOCAL_MACHINE, 'SOFTWARE\\Autodesk\\AutoCAD', versions) then"); sb.AppendLine(@" begin"); sb.AppendLine(@" for i := 0 to GetArrayLength(versions) - 1 do"); sb.AppendLine(@" begin"); sb.AppendLine(@" if RegGetSubkeyNames(HKEY_LOCAL_MACHINE, 'SOFTWARE\\Autodesk\\AutoCAD\\' + versions[i], acadPaths) then"); sb.AppendLine(@" begin"); sb.AppendLine(@" for j := 0 to GetArrayLength(acadPaths) - 1 do"); sb.AppendLine(@" begin"); sb.AppendLine(@" if RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\\Autodesk\\AutoCAD\\' + versions[i] + '\\' + acadPaths[j], 'Location', location) then"); sb.AppendLine(@" begin"); sb.AppendLine(@" if (location <> '') and DirExists(location) then"); sb.AppendLine(@" begin"); sb.AppendLine(@" // 验证是否真的是AutoCAD目录(检查acad.exe是否存在)"); sb.AppendLine(@" acadExePath := location + '\\acad.exe';"); sb.AppendLine(@" if FileExists(acadExePath) then"); sb.AppendLine(@" begin"); sb.AppendLine(@" SetArrayLength(paths, GetArrayLength(paths) + 1);"); sb.AppendLine(@" paths[GetArrayLength(paths) - 1] := location;"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@" "); sb.AppendLine(@" // 方法2: 检查常见安装路径"); sb.AppendLine(@" if GetArrayLength(paths) = 0 then"); sb.AppendLine(@" begin"); sb.AppendLine(@" // 检查Program Files目录"); sb.AppendLine(@" if DirExists('C:\\Program Files\\Autodesk') then"); sb.AppendLine(@" begin"); sb.AppendLine(@" FindAutoCADInCommonPath('C:\\Program Files\\Autodesk', paths);"); sb.AppendLine(@" end;"); sb.AppendLine(@" "); sb.AppendLine(@" // 检查Program Files (x86)目录"); sb.AppendLine(@" if DirExists('C:\\Program Files (x86)\\Autodesk') then"); sb.AppendLine(@" begin"); sb.AppendLine(@" FindAutoCADInCommonPath('C:\\Program Files (x86)\\Autodesk', paths);"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@" "); sb.AppendLine(@" Result := paths;"); sb.AppendLine(@"end;"); sb.AppendLine(@""); // 检查天正路径 - 必须先定义 sb.AppendLine(@"procedure CheckTArchPath(path: string; var paths: TArrayOfString);"); sb.AppendLine(@"var"); sb.AppendLine(@" subDirs: TArrayOfString;"); sb.AppendLine(@" i: Integer;"); sb.AppendLine(@" sysPath: string;"); sb.AppendLine(@"begin"); sb.AppendLine(@" if DirExists(path) and FindSubDirectories(path, subDirs) then"); sb.AppendLine(@" begin"); sb.AppendLine(@" for i := 0 to GetArrayLength(subDirs) - 1 do"); sb.AppendLine(@" begin"); sb.AppendLine(@" sysPath := subDirs[i] + '\\sys23x64';"); sb.AppendLine(@" if DirExists(sysPath) then"); sb.AppendLine(@" begin"); sb.AppendLine(@" SetArrayLength(paths, GetArrayLength(paths) + 1);"); sb.AppendLine(@" paths[GetArrayLength(paths) - 1] := subDirs[i];"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@"end;"); sb.AppendLine(@""); // 查找天正安装路径 - 简化版本 sb.AppendLine(@"function FindTArchInstallations(): TArrayOfString;"); sb.AppendLine(@"var"); sb.AppendLine(@" paths: TArrayOfString;"); sb.AppendLine(@" versions: TArrayOfString;"); sb.AppendLine(@" i: Integer;"); sb.AppendLine(@" installPath: string;"); sb.AppendLine(@" sysPath: string;"); sb.AppendLine(@"begin"); sb.AppendLine(@" SetArrayLength(paths, 0);"); sb.AppendLine(@" "); sb.AppendLine(@" // 方法1: 通过注册表查找天正安装路径"); sb.AppendLine(@" if RegGetSubkeyNames(HKEY_LOCAL_MACHINE, 'SOFTWARE\\Tangent', versions) then"); sb.AppendLine(@" begin"); sb.AppendLine(@" for i := 0 to GetArrayLength(versions) - 1 do"); sb.AppendLine(@" begin"); sb.AppendLine(@" if RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\\Tangent\\' + versions[i], 'InstallPath', installPath) then"); sb.AppendLine(@" begin"); sb.AppendLine(@" if (installPath <> '') and DirExists(installPath) then"); sb.AppendLine(@" begin"); sb.AppendLine(@" // 验证是否存在sys23x64目录"); sb.AppendLine(@" sysPath := installPath + '\\sys23x64';"); sb.AppendLine(@" if DirExists(sysPath) then"); sb.AppendLine(@" begin"); sb.AppendLine(@" SetArrayLength(paths, GetArrayLength(paths) + 1);"); sb.AppendLine(@" paths[GetArrayLength(paths) - 1] := installPath;"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@" "); sb.AppendLine(@" // 方法2: 检查常见安装路径"); sb.AppendLine(@" if GetArrayLength(paths) = 0 then"); sb.AppendLine(@" begin"); sb.AppendLine(@" // 检查常见天正安装路径"); sb.AppendLine(@" CheckTArchPath('C:\\Program Files\\Tangent', paths);"); sb.AppendLine(@" CheckTArchPath('C:\\Tangent', paths);"); sb.AppendLine(@" CheckTArchPath('D:\\Program Files\\Tangent', paths);"); sb.AppendLine(@" CheckTArchPath('D:\\Tangent', paths);"); sb.AppendLine(@" end;"); sb.AppendLine(@" "); sb.AppendLine(@" Result := paths;"); sb.AppendLine(@"end;"); sb.AppendLine(@""); // 移除acaddoc.lsp文件 sb.AppendLine(@"procedure RemoveAcaddocFromAutoCAD();"); sb.AppendLine(@"var"); sb.AppendLine(@" acadPaths: TArrayOfString;"); sb.AppendLine(@" tarchPaths: TArrayOfString;"); sb.AppendLine(@" i: Integer;"); sb.AppendLine(@" filePath: string;"); sb.AppendLine(@"begin"); sb.AppendLine(@" // 从AutoCAD安装目录删除"); sb.AppendLine(@" acadPaths := FindAutoCADInstallations();"); sb.AppendLine(@" for i := 0 to GetArrayLength(acadPaths) - 1 do"); sb.AppendLine(@" begin"); sb.AppendLine(@" if acadPaths[i] <> '' then"); sb.AppendLine(@" begin"); sb.AppendLine(@" filePath := acadPaths[i] + '\\acaddoc.lsp';"); sb.AppendLine(@" if FileExists(filePath) then"); sb.AppendLine(@" begin"); sb.AppendLine(@" DeleteFile(filePath);"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@" "); sb.AppendLine(@" // 从天正安装目录删除"); sb.AppendLine(@" tarchPaths := FindTArchInstallations();"); sb.AppendLine(@" for i := 0 to GetArrayLength(tarchPaths) - 1 do"); sb.AppendLine(@" begin"); sb.AppendLine(@" if tarchPaths[i] <> '' then"); sb.AppendLine(@" begin"); sb.AppendLine(@" filePath := tarchPaths[i] + '\\sys23x64\\acaddoc.lsp';"); sb.AppendLine(@" if FileExists(filePath) then"); sb.AppendLine(@" begin"); sb.AppendLine(@" DeleteFile(filePath);"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@"end;"); sb.AppendLine(@""); // 复制acaddoc.lsp文件 sb.AppendLine(@"procedure CopyAcaddocToAutoCAD();"); sb.AppendLine(@"var"); sb.AppendLine(@" acadPaths: TArrayOfString;"); sb.AppendLine(@" tarchPaths: TArrayOfString;"); sb.AppendLine(@" i: Integer;"); sb.AppendLine(@" sourceFile, destFile: string;"); sb.AppendLine(@" sourceFound: Boolean;"); sb.AppendLine(@"begin"); sb.AppendLine(@" sourceFound := False;"); sb.AppendLine(@" "); sb.AppendLine(@" // 尝试多个可能的源文件路径"); sb.AppendLine(@" sourceFile := ExpandConstant('{commonappdata}') + '\\Autodesk\\ApplicationPlugins\\Zhongli Mojia Software.bundle\\Zhongli Mojia Software\\net48\\acaddoc.lsp';"); sb.AppendLine(@" if FileExists(sourceFile) then"); sb.AppendLine(@" begin"); sb.AppendLine(@" sourceFound := True;"); sb.AppendLine(@" end"); sb.AppendLine(@" else"); sb.AppendLine(@" begin"); sb.AppendLine(@" sourceFile := ExpandConstant('{commonappdata}') + '\\Autodesk\\ApplicationPlugins\\Zhongli Mojia Software.bundle\\Contents\\acaddoc.lsp';"); sb.AppendLine(@" if FileExists(sourceFile) then"); sb.AppendLine(@" begin"); sb.AppendLine(@" sourceFound := True;"); sb.AppendLine(@" end"); sb.AppendLine(@" else"); sb.AppendLine(@" begin"); sb.AppendLine(@" sourceFile := ExpandConstant('{commonappdata}') + '\\Autodesk\\ApplicationPlugins\\Zhongli Mojia Software.bundle\\acaddoc.lsp';"); sb.AppendLine(@" if FileExists(sourceFile) then"); sb.AppendLine(@" begin"); sb.AppendLine(@" sourceFound := True;"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@" "); sb.AppendLine(@" if sourceFound then"); sb.AppendLine(@" begin"); sb.AppendLine(@" // 复制到AutoCAD安装目录"); sb.AppendLine(@" acadPaths := FindAutoCADInstallations();"); sb.AppendLine(@" for i := 0 to GetArrayLength(acadPaths) - 1 do"); sb.AppendLine(@" begin"); sb.AppendLine(@" if acadPaths[i] <> '' then"); sb.AppendLine(@" begin"); sb.AppendLine(@" destFile := acadPaths[i] + '\\acaddoc.lsp';"); sb.AppendLine(@" try"); sb.AppendLine(@" if FileCopy(sourceFile, destFile, False) then"); sb.AppendLine(@" begin"); sb.AppendLine(@" // 复制成功"); sb.AppendLine(@" end;"); sb.AppendLine(@" except"); sb.AppendLine(@" // 忽略复制错误"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@" "); sb.AppendLine(@" // 复制到天正安装目录"); sb.AppendLine(@" tarchPaths := FindTArchInstallations();"); sb.AppendLine(@" for i := 0 to GetArrayLength(tarchPaths) - 1 do"); sb.AppendLine(@" begin"); sb.AppendLine(@" if tarchPaths[i] <> '' then"); sb.AppendLine(@" begin"); sb.AppendLine(@" destFile := tarchPaths[i] + '\\sys23x64\\acaddoc.lsp';"); sb.AppendLine(@" ForceDirectories(ExtractFilePath(destFile));"); sb.AppendLine(@" try"); sb.AppendLine(@" if FileCopy(sourceFile, destFile, False) then"); sb.AppendLine(@" begin"); sb.AppendLine(@" // 复制成功"); sb.AppendLine(@" end;"); sb.AppendLine(@" except"); sb.AppendLine(@" // 忽略复制错误"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@"end;"); sb.AppendLine(@""); // 卸载步骤处理 sb.AppendLine(@"procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);"); sb.AppendLine(@"var"); sb.AppendLine(@" ResultCode: Integer;"); sb.AppendLine(@"begin"); sb.AppendLine(@" if CurUninstallStep = usUninstall then"); sb.AppendLine(@" begin"); sb.AppendLine(@" // 关闭可能占用文件的进程"); sb.AppendLine(@" Exec('taskkill', '/f /im ""权利档案CAD插件*""', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);"); sb.AppendLine(@" Exec('taskkill', '/f /im ""Zhongli*""', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);"); sb.AppendLine(@" Exec('taskkill', '/f /im ""acad.exe""', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);"); sb.AppendLine(@" "); sb.AppendLine(@" // 等待进程完全关闭"); sb.AppendLine(@" Sleep(2000);"); sb.AppendLine(@" "); sb.AppendLine(@" // 清理AutoCAD相关文件"); sb.AppendLine(@" RemoveAcaddocFromAutoCAD();"); sb.AppendLine(@" "); sb.AppendLine(@" // 删除CAD插件目录"); sb.AppendLine(@" if DirExists(ExpandConstant('{commonappdata}') + '\\Autodesk\\ApplicationPlugins\\Zhongli Mojia Software.bundle') then"); sb.AppendLine(@" begin"); sb.AppendLine(@" DelTree(ExpandConstant('{commonappdata}') + '\\Autodesk\\ApplicationPlugins\\Zhongli Mojia Software.bundle', True, True, True);"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@"end;"); sb.AppendLine(@""); // 安装步骤处理 sb.AppendLine(@"procedure CurStepChanged(CurStep: TSetupStep);"); sb.AppendLine(@"begin"); sb.AppendLine(@" if CurStep = ssPostInstall then"); sb.AppendLine(@" begin"); sb.AppendLine(@" CopyAcaddocToAutoCAD();"); sb.AppendLine(@" end;"); sb.AppendLine(@"end;"); // 修改后的卸载步骤 sb.AppendLine(@"procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);"); sb.AppendLine(@"var"); sb.AppendLine(@" appDir, datFile: string;"); sb.AppendLine(@"begin"); sb.AppendLine(@" if CurUninstallStep = usUninstall then"); sb.AppendLine(@" begin"); sb.AppendLine(@" // 1. 关闭主应用程序"); sb.AppendLine(@" CloseMainApplication();"); sb.AppendLine(@" "); sb.AppendLine(@" // 2. 删除AutoCAD相关文件"); sb.AppendLine(@" RemoveAcaddocFromAutoCAD();"); sb.AppendLine(@" "); sb.AppendLine(@" // 3. 准备删除应用目录"); sb.AppendLine(@" appDir := ExpandConstant('{app}');"); sb.AppendLine(@" datFile := appDir + '\unins000.dat';"); sb.AppendLine(@" "); sb.AppendLine(@" // 4. 尝试安全删除"); sb.AppendLine(@" if not SafeDeleteFile(datFile) then"); sb.AppendLine(@" begin"); sb.AppendLine(@" // 5. 注册重启删除"); sb.AppendLine(@" RegisterRestartDelete(datFile);"); sb.AppendLine(@" MsgBox('文件正在使用中,将在系统重启后删除', mbInformation, MB_OK);"); sb.AppendLine(@" end;"); sb.AppendLine(@" "); sb.AppendLine(@" // 6. 删除整个应用程序目录"); sb.AppendLine(@" if not SafeDeleteDirectory(appDir) then"); sb.AppendLine(@" begin"); sb.AppendLine(@" RegisterRestartDelete(appDir);"); sb.AppendLine(@" MsgBox('目录正在使用中,将在系统重启后删除', mbInformation, MB_OK);"); sb.AppendLine(@" end;"); sb.AppendLine(@" "); sb.AppendLine(@" // 7. 删除CAD插件"); sb.AppendLine(@" if not SafeDeleteDirectory(ExpandConstant('{commonappdata}\Autodesk\ApplicationPlugins\Zhongli Mojia Software.bundle')) then"); sb.AppendLine(@" begin"); sb.AppendLine(@" RegisterRestartDelete(ExpandConstant('{commonappdata}\Autodesk\ApplicationPlugins\Zhongli Mojia Software.bundle'));"); sb.AppendLine(@" end;"); sb.AppendLine(@" end;"); sb.AppendLine(@"end;"); // 安装完成后的步骤 sb.AppendLine(@"procedure CurStepChanged(CurStep: TSetupStep);"); sb.AppendLine(@"begin"); sb.AppendLine(@" if CurStep = ssPostInstall then"); sb.AppendLine(@" begin"); sb.AppendLine(@" CopyAcaddocToAutoCAD();"); sb.AppendLine(@" end;"); sb.AppendLine(@"end;"); return sb.ToString(); } // 修复的编译方法 private bool CompileInnoSetupScript(string scriptPath, string outputPath) { string innoCompiler = FindInnoSetupCompiler(); if (string.IsNullOrEmpty(innoCompiler)) { MessageBox.Show("未找到Inno Setup编译器。请先安装Inno Setup 5或6版本。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } try { ProcessStartInfo psi = new ProcessStartInfo { FileName = innoCompiler, Arguments = $"/Q \"{scriptPath}\"", UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true, WorkingDirectory = Path.GetTempPath() }; using (Process process = new Process()) { process.StartInfo = psi; StringBuilder output = new StringBuilder(); StringBuilder error = new StringBuilder(); process.OutputDataReceived += (s, e) => { if (!string.IsNullOrEmpty(e.Data)) output.AppendLine(e.Data); }; process.ErrorDataReceived += (s, e) => { if (!string.IsNullOrEmpty(e.Data)) error.AppendLine(e.Data); }; process.Start(); process.BeginOutputReadLine(); process.BeginErrorReadLine(); bool exited = process.WaitForExit(60000); // 60秒超时 if (!exited) { process.Kill(); MessageBox.Show("Inno Setup编译超时,请检查系统资源或重试。", "编译超时", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } if (process.ExitCode == 0) { return true; } else { string errorMsg = $"Inno Setup编译失败 (退出代码: {process.ExitCode})"; if (output.Length > 0) errorMsg += $"\n输出: {output}"; if (error.Length > 0) errorMsg += $"\n错误: {error}"; MessageBox.Show(errorMsg, "编译错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } } } catch (Exception ex) { MessageBox.Show($"编译过程中出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } } // 增强的Inno Setup查找方法 private string FindInnoSetupCompiler() { string[] possiblePaths = { @"C:\Program Files (x86)\Inno Setup 6\ISCC.exe", @"C:\Program Files\Inno Setup 6\ISCC.exe", @"C:\Program Files (x86)\Inno Setup 5\ISCC.exe", @"C:\Program Files\Inno Setup 5\ISCC.exe", @"D:\Program Files (x86)\Inno Setup 6\ISCC.exe", @"D:\Program Files\Inno Setup 6\ISCC.exe" }; foreach (string path in possiblePaths) { if (File.Exists(path)) { return path; } } // 尝试从注册表查找 try { string[] registryPaths = { @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Inno Setup 6_is1", @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Inno Setup 5_is1", @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Inno Setup 6_is1", @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Inno Setup 5_is1" }; foreach (string registryPath in registryPaths) { using (RegistryKey key = Registry.LocalMachine.OpenSubKey(registryPath)) { if (key != null) { string installPath = key.GetValue("InstallLocation")?.ToString(); if (!string.IsNullOrEmpty(installPath)) { string compilerPath = Path.Combine(installPath, "ISCC.exe"); if (File.Exists(compilerPath)) return compilerPath; } } } } // 尝试从32位注册表查找 using (RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32) .OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Inno Setup 6_is1")) { if (key != null) { string installPath = key.GetValue("InstallLocation")?.ToString(); if (!string.IsNullOrEmpty(installPath)) { string compilerPath = Path.Combine(installPath, "ISCC.exe"); if (File.Exists(compilerPath)) return compilerPath; } } } } catch (Exception ex) { Debug.WriteLine($"注册表查找失败: {ex.Message}"); } return null; } // 添加附加文件 private void btnAddFile_Click(object sender, EventArgs e) { using (OpenFileDialog openFileDialog = new OpenFileDialog()) { openFileDialog.Multiselect = true; openFileDialog.Filter = "所有文件 (*.*)|*.*"; openFileDialog.Title = "选择附加文件"; if (openFileDialog.ShowDialog() == DialogResult.OK) { foreach (string fileName in openFileDialog.FileNames) { listBoxAdditionalFiles.Items.Add(fileName); } } } } // 移除选中的附加文件 private void btnRemoveFile_Click(object sender, EventArgs e) { if (listBoxAdditionalFiles.SelectedIndex != -1) { listBoxAdditionalFiles.Items.RemoveAt(listBoxAdditionalFiles.SelectedIndex); } } // 清空所有设置 private void btnClear_Click(object sender, EventArgs e) { if (MessageBox.Show("确定要清空所有设置吗?", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { txtMainProgram.Clear(); txtSelectedFolder.Clear(); txtProductName.Text = "忠利模架CAD插件"; txtVersion.Text = "v1.0"; txtIconPath.Clear(); // 重置为默认子目录路径 string appName = txtProductName.Text; txtInstallPath.Text = $@"C:\Program Files (x86)\Autodesk\{appName}"; txtCompanyName.Clear(); treeViewFolder.Nodes.Clear(); pictureBoxIcon.Image = null; listBoxAdditionalFiles.Items.Clear(); progressBar.Value = 0; // 清理临时目录 CleanupTempFolder(); } } // 显示关于信息 private void btnAbout_Click(object sender, EventArgs e) { MessageBox.Show( "安装包打包工具 v4.0\n\n" + "功能特性:\n" + "• 创建专业的 Windows 安装程序 (.exe)\n" + "• 使用 Inno Setup 引擎\n" + "• 支持自定义安装路径\n" + "• 自动设置图标和版本信息\n" + "• 支持附加文件打包\n" + "• 包含卸载功能\n" + "• 自动检测已安装版本\n" + "• 支持卸载旧版本后安装\n" + "• 支持覆盖安装\n" + "• 自动安装CAD插件到AutoCAD\n" + "• 全盘搜索AutoCAD和天正安装目录\n" + "• 自动复制acaddoc.lsp到所有AutoCAD和天正目录\n" + "• 卸载时自动清理所有相关文件\n\n" + "注意: 需要安装 Inno Setup 5 或 6\n" + "版权所有 © 2024", "关于", MessageBoxButtons.OK, MessageBoxIcon.Information); } // 窗体关闭时清理资源 protected override void OnFormClosed(FormClosedEventArgs e) { base.OnFormClosed(e); CleanupTempFolder(); } }
}
生成安装包提示错误
Inno Setup编译失败(退出代码:2)
错误:Error on line 63 in C:\Users\椿
\AppData\Local\Temp\setup script 524aa389b3b14c57b99bc6a2c38753
36.iss: Column 39:
Type mismatch.
Compile aborted.
最新发布