Cordova本身提供的是命令行管理工具,並沒有提供圖形界面管理工具,雖然命令行管理工具可以完成所有Cordova管理,但是對於我這種懶蛋,可真不希望每次都輸入命令,而且我更擔心一旦輸錯一個字符,命令執行失敗,再次重新輸入,反復執行這種無意義的事情!於是,我就用Delphi編寫了這個Windows下的管理工具,用於執行大多數Cordova命令,能夠滿足我開發Cordova的需求!
由於目前工作緊張,所以暫時未能提供教程,近期完成項目后,會補上詳細使用教程!
全部源碼和編譯好的工具下載:https://download.csdn.net/download/sunylat/10782003
此工具目前還有很少一點點功能需要完善,但不影響正常使用,只是錦上添花!
功能描述:
1,Cordova環境檢查:對Cordova依賴的各種工具進行檢查,看是否滿足Cordova工作需要。
2,Cordova工程管理:新建、刪除、加入已建立工程、在任意工程之間切換。
3,Cordova平台管理:添加、刪除Cordova平台,Windows版,支持Android、IOS、Windows平台,其余平台未在本工具中加入,其實可以隨時加入!
4,Cordova插件管理:添加、刪除所有Cordova官方插件;支持第三方插件安裝、刪除。
5,編譯、發布:支持Android平台APP的編譯、發布,可以發布到模擬器或真機。
工具截圖:
1,
2,
3,
4,
5,
全部源碼:
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.ComCtrls, Vcl.Buttons, System.Generics.collections; type TForm2 = class(TForm) Panel1: TPanel; Panel2: TPanel; clearLogBtn: TButton; logMemo: TMemo; Splitter1: TSplitter; Panel3: TPanel; PageControl1: TPageControl; TabSheet1: TTabSheet; Panel4: TPanel; projectPathEdt: TEdit; Label1: TLabel; TabSheet2: TTabSheet; TabSheet3: TTabSheet; TabSheet4: TTabSheet; TabSheet5: TTabSheet; GroupBox1: TGroupBox; Label2: TLabel; projectNameEdt: TEdit; Label3: TLabel; projectIdEdt: TEdit; openProjectPathBtn: TButton; GroupBox2: TGroupBox; androidCBox: TCheckBox; IOSCBox: TCheckBox; addPlatformBtn: TButton; removePlatformBtn: TButton; windowsCBox: TCheckBox; getPlatformBtn: TButton; installPluginBtn: TButton; Button5: TButton; Button6: TButton; GroupBox3: TGroupBox; checkToolRGroup: TRadioGroup; installCordovaBtn: TButton; checkToolBtn: TButton; GroupBox4: TGroupBox; checkJavaHomeBtn: TButton; setJavaHomeBtn: TButton; GroupBox5: TGroupBox; checkAndroidHomeBtn: TButton; setAndroidHomeBtn: TButton; GroupBox6: TGroupBox; batteryStatusCBox: TCheckBox; cameraCBox: TCheckBox; contactsCBox: TCheckBox; deviceCBox: TCheckBox; deviceMotionCBox: TCheckBox; compassCBox: TCheckBox; dialogsCBox: TCheckBox; fileCBox: TCheckBox; fileTransferCBox: TCheckBox; geolocationCBox: TCheckBox; globalizationCBox: TCheckBox; mediaCBox: TCheckBox; mediaCaptureCBox: TCheckBox; networkCBox: TCheckBox; splashScreenCBox: TCheckBox; vibrationCBox: TCheckBox; statusbarCBox: TCheckBox; consoleCBox: TCheckBox; inappbrowserCBox: TCheckBox; selectPluginBitBtn: TBitBtn; GroupBox7: TGroupBox; downloadGradleBtn: TButton; configGradleBtn: TButton; Label7: TLabel; OpenDialog1: TOpenDialog; GroupBox8: TGroupBox; Label8: TLabel; pluginNameEdt: TEdit; selectLocalPluginBtn: TButton; isInstallThirdCBox: TCheckBox; GroupBox9: TGroupBox; buildBtn: TButton; GroupBox10: TGroupBox; sendToEmulatorBtn: TButton; Label10: TLabel; GroupBox11: TGroupBox; Label11: TLabel; sendToDeviceBtn: TButton; Label12: TLabel; isRebuildCBox: TCheckBox; selectPlatformBitBtn: TBitBtn; delPluginInfoLab: TLabel; pluginInfoLab: TLabel; projectListBox: TListBox; deleteProjectBtn: TButton; addOldProjectBtn: TButton; getProjectInfoBtn: TButton; Button8: TButton; createProjectBtn: TButton; curProjectNameEdt: TEdit; Label4: TLabel; openAndroidBuildPathBtn: TButton; openGradleDirBtn: TButton; chcpRGroup: TRadioGroup; doChcpBtn: TButton; buildPlatformRGroup: TRadioGroup; buildTypeRGroup: TRadioGroup; procedure clearLogBtnClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure createProjectBtnClick(Sender: TObject); procedure openProjectPathBtnClick(Sender: TObject); procedure checkToolBtnClick(Sender: TObject); procedure installCordovaBtnClick(Sender: TObject); procedure getProjectInfoBtnClick(Sender: TObject); procedure getPlatformBtnClick(Sender: TObject); procedure addPlatformBtnClick(Sender: TObject); procedure removePlatformBtnClick(Sender: TObject); procedure installPluginBtnClick(Sender: TObject); procedure Button5Click(Sender: TObject); procedure Button6Click(Sender: TObject); procedure buildBtnClick(Sender: TObject); procedure Button8Click(Sender: TObject); procedure checkJavaHomeBtnClick(Sender: TObject); procedure checkAndroidHomeBtnClick(Sender: TObject); procedure selectPluginBitBtnClick(Sender: TObject); procedure downloadGradleBtnClick(Sender: TObject); procedure configGradleBtnClick(Sender: TObject); procedure sendToEmulatorBtnClick(Sender: TObject); procedure sendToDeviceBtnClick(Sender: TObject); procedure Label12Click(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure selectPlatformBitBtnClick(Sender: TObject); procedure TabSheet4Show(Sender: TObject); procedure deleteProjectBtnClick(Sender: TObject); procedure addOldProjectBtnClick(Sender: TObject); procedure projectListBoxDblClick(Sender: TObject); procedure selectLocalPluginBtnClick(Sender: TObject); procedure openAndroidBuildPathBtnClick(Sender: TObject); procedure openGradleDirBtnClick(Sender: TObject); procedure doChcpBtnClick(Sender: TObject); private { Private declarations } // 是否程序正在運行 function isExeRunning(exeName: string): boolean; // 終止進程 procedure KillProc(procname: string); // 得到特殊目錄 function GetSpecialDir(SpecialDirID: Integer): string; // 得到用戶目錄 function GetAppDir: string; public { Public declarations } procedure MyLog(tempLog: string); // log方法 // 關閉DOS窗口 procedure KillDosWindow; // 執行單條DOS命令 procedure RunDosCommand(commandStr: string; isPause: boolean); Overload; { // 同時執行多條DOS命令 stringList:包含要執行DOS命令的TStringList。 isPause:是否執行完畢暫停當前窗口,不關閉 } procedure RunDosCommand(var stringList: TStringList; isPause: boolean); Overload; // 判斷是否Cordova工程目錄 function IsCordovaDir(projectDir: string): boolean; // 進入Cordova工程目錄的DOS命令字符串 function CdCordovaDirCommandStr(CordovaDir: string): string; { 得到選中的插件 isAdd:是否添加插件操作(tru,添加;false,刪除) } function GetSelectedPlugin(isAdd: boolean): string; // 選擇插件 procedure SelectPlugin(isSelectAll: boolean); { 得到選中的平台 isAdd:是否添加插件平台(tru,添加;false,刪除) } function GetSelectedPlatform: string; // 選擇平台 procedure SelectPlatform(isSelectAll: boolean); // 顯示被管理工程信息 procedure ShowProjectInfo(var projectDic: TDictionary<string, string>; var projectListBox: TListBox); // 通過工程全路徑名稱得到工程路徑和名稱 procedure GetProjectPathAndName(projectDir: string; var projectPath: string; var projectName: string); // 對ini文件內容操作(添加和刪除) procedure OperateIniFile(iniFileName, section, key, value: string; isAdd: boolean); // 同步數據 procedure SyncProjectes(var projectDic: TDictionary<string, string>; var projectListBox: TListBox; iniFileName: string; isDicToIni: boolean); // 延時方法 procedure Delay(msecs: Integer); end; const { Gradle工具在用戶目錄中存放的路徑名稱 注意:當前cordova版本:8.0.0,如果cordova版本不同,需要注意正在使用的cordova存放Gradle工具目錄還是不是這個名稱, 如果不是,則直接把下面常量修改成正在使用的Gradle存放目錄名稱就可以了 我當前版本cordova存放Gradle全路徑: C:\Users\sunylat\.gradle\wrapper\dists\gradle-4.1-all\bzyivzo6n839fup2jbap0tjew } GradleDirInUserHome : string = '.gradle\wrapper\dists\gradle-4.1-all\bzyivzo6n839fup2jbap0tjew'; // cordova命令使用的常量 Cordova: String = 'cordova '; // ini配置文件名稱 configFile: string = 'config.ini'; // 默認的工程ID defaultProjectID: string = 'io.cordova.hellocordova'; // 默認的工程名稱 defaultProjectName: string = 'HelloCordova '; // DOS連接命令符合(前面命令必須成功執行,才能執行后面命令) DosJoinCode: string = '&'; // DOS空白行命令 DosBlankLine: string = 'echo.'; var Form2: TForm2; logInfo: string; // log信息 // ----------------------------------------- curProjectPath: string; // 當前工程路徑(不包括cordova工程目錄) curProjectName: string; // 當前cordova工程名稱 curProjectDir: string; // cordova工程全路徑名稱(curProjectPath + curProjectName) DosCommand: string; // Dos命令 iniFileName: string; // ini文件 isSelectPlugin: boolean; // 是否選中插件 isSelectPlatfom: boolean; // 是否選中平台 // 被管理全部工程的Dictionary projectDictionary: TDictionary<string, string>; implementation {$R *.dfm} uses FileCtrl, System.IOUtils, inifiles, ShellAPI, TLHelp32, ShlObj, System.StrUtils; procedure TForm2.addOldProjectBtnClick(Sender: TObject); var tempStr: string; tempProjectPath, tempProjectName: string; // 臨時用的工程路徑和工程名稱 begin // 選擇工程目錄 if SelectDirectory('請選擇已有工程的目錄!', '', tempStr) = true then begin // 通過選擇的工程全路徑名稱得到工程路徑和工程名稱 self.GetProjectPathAndName(tempStr, tempProjectPath, tempProjectName); // 把選中的工程信息加入到ni文件中 self.OperateIniFile(iniFileName, 'projectes', tempProjectName, tempProjectPath, true); // 同步數據 self.SyncProjectes(projectDictionary, projectListBox, iniFileName, false); end; end; procedure TForm2.addPlatformBtnClick(Sender: TObject); var tempList: TStringList; tempCommand: string; platformStr: string; // 要添加平台命令字符串 begin // 得到選中平台 platformStr := trim(self.GetSelectedPlatform); if platformStr <> '' then begin try tempList := TStringList.Create; // 加入進入工程目錄的DOS命令 tempCommand := self.CdCordovaDirCommandStr(curProjectDir); tempList.Add(tempCommand); // 加入添加平台的cordova命令 tempCommand := 'cordova platform add ' + platformStr + ' --save'; tempList.Add(tempCommand); // 執行所有命令 self.RunDosCommand(tempList, true); finally tempList.Free; end; end else begin showmessage('請選擇要添加的平台,隨后執行添加平台操作!'); end; end; procedure TForm2.checkJavaHomeBtnClick(Sender: TObject); begin // 查看JAVA_HOME環境變量 DosCommand := 'echo %JAVA_HOME%'; // 執行DOS命令 self.RunDosCommand(DosCommand, true); end; procedure TForm2.checkAndroidHomeBtnClick(Sender: TObject); begin // 查看ANDROID_HOME環境變量 DosCommand := 'echo %ANDROID_HOME%'; // 執行DOS命令 self.RunDosCommand(DosCommand, true); end; procedure TForm2.openAndroidBuildPathBtnClick(Sender: TObject); const // android debug程序編譯輸出目錄 androidDebugOutputPath = 'platforms\android\app\build\outputs\apk\debug'; // windows phone debug程序編譯輸出目錄 windowsDebugOutputPath = 'platforms\windows\build\windows\debug\anycpu'; var projectDir, openDir: string; begin projectDir := trim(projectPathEdt.Text); if projectDir <> '' then begin if buildPlatformRGroup.ItemIndex = 0 then begin openDir := projectDir + '\' + androidDebugOutputPath; end else if buildPlatformRGroup.ItemIndex = 1 then begin openDir := projectDir + '\' + windowsDebugOutputPath; end; ShellExecute(Handle, 'open', 'Explorer.exe', PChar(openDir), nil, SW_SHOWNORMAL); end; end; procedure TForm2.openProjectPathBtnClick(Sender: TObject); begin if (trim(curProjectPath) <> '') and (trim(curProjectName) <> '') then begin ShellExecute(Handle, 'open', 'Explorer.exe', PChar(curProjectDir), nil, SW_SHOWNORMAL); end else begin showmessage('請確認是否已經創建過工程?'); end; end; procedure TForm2.createProjectBtnClick(Sender: TObject); var projectID: string; // 工程ID tempIniFile: TInifile; // ini配置文件 // 創建工程 procedure CreateProject; begin DosCommand := 'cordova create '; { A,執行添加工程命令 } // 1,在執行命令中加入工程路徑 DosCommand := DosCommand + curProjectPath + '\' + curProjectName + ' '; // 工程ID projectID := trim(projectIdEdt.Text); if projectID = '' then begin projectID := defaultProjectID; end; // 2,在執行命令中加入工程ID DosCommand := DosCommand + projectID + ' '; // 3,在執行命令中加入工程名稱 DosCommand := DosCommand + curProjectName; // 執行創建工程命令 self.RunDosCommand(DosCommand, true); { B,把剛創建工程寫入ini文件 } try tempIniFile := TInifile.Create(iniFileName); // 當前工程名稱 tempIniFile.WriteString('curProject', 'name', curProjectName); // 當前工程目錄(不包括cordova工程目錄的全路徑名稱) tempIniFile.WriteString('curProject', 'path', curProjectPath); finally tempIniFile.Free; end; { C,把剛創建工程加入工程管理Dictionary中 } projectDictionary.Add(curProjectName, curProjectPath); { D,重新顯示全部工程信息 } self.ShowProjectInfo(projectDictionary, projectListBox); end; begin // 選擇工程目錄 if SelectDirectory('請選擇保存當前工程的上級文件夾,系統自動創建工程文件夾!', '', curProjectPath) then begin // 工程名稱 if trim(projectNameEdt.Text) <> '' then begin curProjectName := trim(projectNameEdt.Text); end else begin curProjectName := defaultProjectName; end; if rightStr(curProjectPath, 1) = '\' then begin // 工程全路徑名稱 curProjectDir := curProjectPath + curProjectName; end else begin // 工程全路徑名稱 curProjectDir := curProjectPath + '\' + curProjectName; end; if TDirectory.Exists(curProjectDir) = true then begin // 2,創建cordova工程 if TDirectory.IsEmpty(curProjectDir) = false then begin if MessageBox(0, '執行創建工程操作,如果當前選中工程存放目錄已經存在同名工程名稱文件夾,則此文件夾將被徹底刪除,確定創建嗎?', '提醒', MB_YESNO + MB_ICONWARNING) = IDYES then begin // 刪除已有文件夾(包括所有子文件夾和文件) TDirectory.Delete(curProjectDir, true); self.Delay(1500); // 重新創建工程目錄 TDirectory.CreateDirectory(curProjectDir); // 執行創建工程 CreateProject; end; end else begin // 創建工程目錄 TDirectory.CreateDirectory(curProjectDir); // 執行創建工程 CreateProject; end; end else begin // 創建工程目錄 TDirectory.CreateDirectory(curProjectDir); // 執行創建工程 CreateProject; end; // 顯示當前工程名稱 curProjectNameEdt.Text := curProjectName; // 顯示創建工程的全路徑名稱 projectPathEdt.Text := curProjectDir; // 同步工程信息 SyncProjectes(projectDictionary, projectListBox, iniFileName, true); end; end; procedure TForm2.sendToEmulatorBtnClick(Sender: TObject); var tempList: TStringList; tempCommand: string; runCommand: string; // 運行安卓程序命令 begin try tempList := TStringList.Create; tempCommand := self.CdCordovaDirCommandStr(curProjectDir); tempList.Add(tempCommand); // 組裝把安卓程序發送到模擬器運行的命令 if isRebuildCBox.Checked = true then begin runCommand := 'cordova run android --emulator'; end else begin runCommand := 'cordova run android --nobuild --emulator'; end; // 加入把安卓程序發送到模擬器運行的命令 tempList.Add(runCommand); self.RunDosCommand(tempList, true); finally tempList.Free; // 窗口最小化到任務欄 Application.Minimize; end; end; procedure TForm2.TabSheet4Show(Sender: TObject); var tempStr: string; begin { 1,第三方插件安裝方法 } tempStr := '第三方插件安裝方法:必須選中"安裝第三方插件"復選框后,采用下面兩種方式安裝。' + #13; tempStr := tempStr + '1,遠程下載:在"插件名稱或URL"文本框輸入下載插件的url。' + #13; tempStr := tempStr + '2,本地安裝:點擊"選擇本地插件"按鈕,選擇本地插件。'; // 顯示設置第三方插件安裝方法 pluginInfoLab.Caption := tempStr; { 2,第三方插件刪除方法 } tempStr := '第三方插件刪除方法:在"插件名稱或URL"文本框輸入刪除插件名稱。' + #13; tempStr := tempStr + '注意:刪除的插件名稱和安裝時候的名稱不一樣!' + #13; tempStr := tempStr + '刪除的插件名稱是安裝時候的名稱的最后一部分,' + #13; tempStr := tempStr + '是去掉整個名稱的"cordova-plugin-"之后剩余的字符串!,' + #13; tempStr := tempStr + '例如:camera插件' + #13; tempStr := tempStr + '安裝名稱:cordova-plugin-camera' + #13; tempStr := tempStr + '刪除名稱:camera'; delPluginInfoLab.Caption := tempStr; end; procedure TForm2.sendToDeviceBtnClick(Sender: TObject); var tempList: TStringList; tempCommand: string; runCommand: string; // 運行安卓程序命令 begin try tempList := TStringList.Create; tempCommand := self.CdCordovaDirCommandStr(curProjectDir); tempList.Add(tempCommand); // 組裝把安卓程序發送到模擬器運行的命令 if isRebuildCBox.Checked = true then begin runCommand := 'cordova run android --device'; end else begin runCommand := 'cordova run android --nobuild --device'; end; // 加入把安卓程序發送到模擬器運行的命令 tempList.Add(runCommand); self.RunDosCommand(tempList, true); finally tempList.Free; // 窗口最小化到任務欄 Application.Minimize; end; end; procedure TForm2.installPluginBtnClick(Sender: TObject); var tempList: TStringList; tempCommand: string; pluginStr: string; // 插件列表 { 刪除攝像頭插件配置文件,如果不刪除,則再次安裝時候報錯,這可能是一個BUG } procedure DeleteCameraXml(tempProjectDir: string); const // 攝像頭插件的配置文件 cameraXml: string = 'platforms\android\app\src\main\res\xml\camera_provider_paths.xml'; var tempFile: string; // 臨時變量 begin // 攝像頭插件的配置文件的全路徑名稱 tempFile := tempProjectDir + '\' + cameraXml; if TFile.Exists(tempFile) = true then begin TFile.Delete(tempFile); end; end; begin // 安裝第三方插件 if isInstallThirdCBox.Checked = true then begin // 得到要安裝插件名稱或者url pluginStr := trim(pluginNameEdt.Text); // 可以安裝,則直接安裝 if pluginStr = '' then begin showmessage('要安裝的第三方插件名稱或者Url不能為空!'); pluginNameEdt.SetFocus; end; end else // 安裝Cordova官方插件 begin // 得到要安裝的插件列表 pluginStr := self.GetSelectedPlugin(true); end; // 如果有要安裝的插件,則執行安裝 if trim(pluginStr) <> '' then begin // 1,刪除攝像頭插件配置文件 DeleteCameraXml(curProjectDir); // 2,安裝指定的插件 try tempList := TStringList.Create; // 1,加入進入Cordova工程目錄命令 tempCommand := self.CdCordovaDirCommandStr(curProjectDir); tempList.Add(tempCommand); // 2,加入執行安裝插件命令 tempCommand := 'cordova plugin add ' + pluginStr + ' --save --searchpath ../plugins'; tempList.Add(tempCommand); // 3,執行安裝插件命令 self.RunDosCommand(tempList, true); finally tempList.Free; end; end else begin showmessage('請選擇要安裝的插件后,在執行安裝插件操作!'); end; end; procedure TForm2.openGradleDirBtnClick(Sender: TObject); var GradleSaveDir: string; // Gradle最終保持目錄名稱 userHome: string; // 用戶目錄 begin // 得到用戶目錄 userHome := StringReplace(self.GetAppDir, 'AppData\Roaming', '', [rfReplaceAll]); // Gradle最終保持目錄名稱 GradleSaveDir := userHome + GradleDirInUserHome; ShellExecute(Handle, 'open', 'Explorer.exe', PChar(GradleSaveDir), nil, SW_SHOWNORMAL); end; procedure TForm2.Button5Click(Sender: TObject); var tempList: TStringList; tempCommand: string; pluginStr: string; // 插件列表 begin // 安裝Cordova官方插件 if isInstallThirdCBox.Checked = false then begin // 得到要刪除的插件列表 pluginStr := self.GetSelectedPlugin(false); end else // 安裝第三方插件 begin // 得到要安裝插件名稱或者url pluginStr := trim(pluginNameEdt.Text); // 可以安裝,則直接安裝 if pluginStr = '' then begin showmessage('要安裝的第三方插件名稱或者Url不能為空!'); pluginNameEdt.SetFocus; end; end; // 執行刪除插件命令 if trim(pluginStr) <> '' then begin try tempList := TStringList.Create; // 1,加入進入Cordova工程目錄命令 tempCommand := self.CdCordovaDirCommandStr(curProjectDir); tempList.Add(tempCommand); // 2,加入執行刪除插件命令 tempCommand := 'cordova plugin rm ' + pluginStr + ' --save'; tempList.Add(tempCommand); // 3,執行刪除插件命令 self.RunDosCommand(tempList, true); finally tempList.Free; end; end else begin showmessage('請選擇要刪除的插件后,在執行刪除插件操作!'); end; end; procedure TForm2.Button6Click(Sender: TObject); var tempList: TStringList; tempCommand: string; begin try tempList := TStringList.Create; tempCommand := self.CdCordovaDirCommandStr(curProjectDir); tempList.Add(tempCommand); tempList.Add('cordova plugin ls'); self.RunDosCommand(tempList, true); finally tempList.Free; end; end; procedure TForm2.buildBtnClick(Sender: TObject); var tempList: TStringList; tempCommand: string; begin try tempList := TStringList.Create; // 1, 加入進入當前工程目錄命令 tempCommand := self.CdCordovaDirCommandStr(curProjectDir); tempList.Add(tempCommand); if buildPlatformRGroup.ItemIndex = 0 then begin // 2,加入編譯cordova在安卓平台的程序 if buildTypeRGroup.ItemIndex = 0 then begin tempList.Add('cordova build android --debug'); end else if buildTypeRGroup.ItemIndex = 1 then begin // tempList.Add('cordova build android --release -- --keystore="..\android.keystore" --storePassword=android --alias=mykey'); end; end else if buildPlatformRGroup.ItemIndex = 1 then begin // 2,加入編譯cordova在windows平台的程序 if buildTypeRGroup.ItemIndex = 0 then begin tempList.Add('cordova build windows --debug'); end else if buildTypeRGroup.ItemIndex = 1 then begin // tempList.Add('cordova build android --release -- --keystore="..\android.keystore" --storePassword=android --alias=mykey'); end; end; // 執行命令 self.RunDosCommand(tempList, true); finally tempList.Free; end; end; procedure TForm2.Button8Click(Sender: TObject); var tempList: TStringList; tempCommand: string; begin try tempList := TStringList.Create; tempCommand := self.CdCordovaDirCommandStr(curProjectDir); // browser ~5.0.1 // osx ~4.0.1 // windows ~5.0.0 // www ^3.12.0 tempList.Add(tempCommand); tempList.Add('cordova requirements '); self.RunDosCommand(tempList, true); finally tempList.Free; end; end; procedure TForm2.getProjectInfoBtnClick(Sender: TObject); var stringList: TStringList; tempStr: string; projectDisk: string; // 工程目錄存放磁盤的盤符 tempProjectPath: string; begin // 通過工程全路徑名稱得到所在磁盤盤符 projectDisk := ExtractFileDrive(curProjectDir); // 得到去除盤符之后的路徑名稱 tempProjectPath := rightStr(curProjectDir, length(curProjectDir) - 3); // 命令例子:cd cordovaTest\test\HelloCordova if projectDisk = 'C:' then begin tempStr := 'cd ' + curProjectDir; end else begin tempStr := 'cd ' + tempProjectPath; end; // 創建並執行查看工程信息命令 try stringList := TStringList.Create; stringList.Add(projectDisk); stringList.Add(tempStr); stringList.Add('echo 工程信息:'); stringList.Add(DosBlankLine); stringList.Add('cordova info'); // 測試信息 stringList.Add(DosBlankLine); stringList.Add('cordova platform ls'); self.RunDosCommand(stringList, true); finally stringList.Free; end; end; procedure TForm2.getPlatformBtnClick(Sender: TObject); var tempList: TStringList; tempCommand: string; begin try tempList := TStringList.Create; tempCommand := self.CdCordovaDirCommandStr(curProjectDir); tempList.Add(tempCommand); tempList.Add('cordova platform ls'); self.RunDosCommand(tempList, true); finally tempList.Free; end; end; procedure TForm2.checkToolBtnClick(Sender: TObject); var ItemIndex: Integer; // 工具選中ID begin ItemIndex := checkToolRGroup.ItemIndex; if ItemIndex = -1 then begin showmessage('請選擇要檢測的工具!'); end else begin // 如果沒有項目選中,則提示用戶選擇 if ItemIndex = 0 then begin // 查看node.js版本 DosCommand := 'node -v'; // 執行DOS命令 self.RunDosCommand(DosCommand, true); end else if ItemIndex = 1 then begin // 查看phonegap版本 DosCommand := 'git --version'; // 執行DOS命令 self.RunDosCommand(DosCommand, true); end else if ItemIndex = 2 then begin // 查看cordova版本 DosCommand := 'cordova -v'; // 執行DOS命令 self.RunDosCommand(DosCommand, true); end; end; end; procedure TForm2.clearLogBtnClick(Sender: TObject); begin logMemo.Clear; // projectDictionary.Add('ccc', 'e:\abc\def'); // projectDictionary.Add('dddd', 'f:\uio\wer'); // self.SyncProjectes(projectDictionary, projectListBox, iniFileName, true); // self.SyncProjectes(projectDictionary, projectListBox, iniFileName, false); // MyLog(projectDictionary.ToString); // MyLog(IntToStr(projectDictionary.Count)); end; procedure TForm2.configGradleBtnClick(Sender: TObject); var GradleZipFileName: string; // gradle下載文件名 GradleSaveDir: string; // Gradle最終保持目錄名稱 destFile: string; // 存放gradle的文件名 userHome: string; // 用戶目錄 begin if OpenDialog1.Execute then begin // 得到用戶目錄 userHome := StringReplace(self.GetAppDir, 'AppData\Roaming', '', [rfReplaceAll]); // Gradle最終保持目錄名稱 GradleSaveDir := userHome + GradleDirInUserHome; { 1,准備gradle存放目錄 } // 刪除非空的gradle存放目錄 if TDirectory.Exists(GradleSaveDir) = true then begin TDirectory.Delete(GradleSaveDir, true); end; // 創建gradle存放 TDirectory.CreateDirectory(GradleSaveDir); // 2,拷貝下載文件到gradle存放目錄 GradleZipFileName := ExtractFileName(OpenDialog1.FileName); destFile := GradleSaveDir + '\' + GradleZipFileName; TFile.Copy(trim(OpenDialog1.FileName), destFile); MyLog('gradle配置完畢!'); end; end; procedure TForm2.deleteProjectBtnClick(Sender: TObject); var delProjectName: string; // 要刪除工程名稱 iniFile: TInifile; begin if projectListBox.ItemIndex <> -1 then begin // 得到要刪除工程名稱 delProjectName := trim(projectListBox.Items[projectListBox.ItemIndex]); try iniFile := TInifile.Create(iniFileName); // 1,從全部被管理工程里面刪除當前要刪除的工程 iniFile.DeleteKey('projectes', delProjectName); // 同步數據 self.SyncProjectes(projectDictionary, projectListBox, iniFileName, false); { 如果刪除工程是當前管理工程,則進一步處理, A,清理當前工程全局變量 B,從程序界面上消除顯示信息 c,刪除ini配置信息 } if delProjectName = curProjectName then begin // A,清理當前工程全局變量 curProjectPath := ''; curProjectName := ''; curProjectDir := ''; // B,從程序界面上消除顯示信息 curProjectNameEdt.Clear; projectPathEdt.Clear; // c,刪除ini配置信息 iniFile.WriteString('curProject', 'name', ''); iniFile.WriteString('curProject', 'path', ''); end; finally iniFile.Free; end; end; end; procedure TForm2.doChcpBtnClick(Sender: TObject); var tempList: TStringList; tempCommand: string; ItemIndex: Integer; // 選中項目ID begin // 得到選中項目ID ItemIndex := chcpRGroup.ItemIndex; // 有項目選中,則執行具體操作 if ItemIndex <> -1 then begin try tempList := TStringList.Create; if ItemIndex = 3 then begin tempList.Add('npm install -g cordova-hot-code-push-cli'); end else begin // 1, 加入進入當前工程目錄命令 tempCommand := self.CdCordovaDirCommandStr(curProjectDir); tempList.Add(tempCommand); case ItemIndex of 0: begin tempList.Add('cordova-hcp build'); end; 1: begin tempList.Add('cordova-hcp server'); end; 2: begin tempList.Add('cordova-hcp init'); end; end; end; // 執行命令 self.RunDosCommand(tempList, true); finally tempList.Free; end; end; end; procedure TForm2.downloadGradleBtnClick(Sender: TObject); const // Gradle配置文件名稱 GradleWapperFile : string = '\platforms\android\gradle\wrapper\gradle-wrapper.properties'; GradleUrlKey: string = 'distributionUrl'; // 下載Gradle的網址key var WapperFile: string; // Gradle配置文件權路徑名稱 tempList: TStringList; tempUrl: string; begin WapperFile := curProjectDir + GradleWapperFile; // 如果Gradle配置文件存在,則獲取下載url,並且下載對應版本的Gradle if TFile.Exists(WapperFile) = true then begin try tempList := TStringList.Create; tempList.LoadFromFile(WapperFile); // 得到配置文件中當前版本的gradle下載地址 tempUrl := tempList.Values[GradleUrlKey]; // 去掉"\" tempUrl := StringReplace(tempUrl, '\', '', [rfReplaceAll]); // 打開瀏覽器下載gradle ShellExecute(0, nil, PChar(tempUrl), nil, nil, 1); finally tempList.Free; end; end else begin showmessage('Gradle配置文件不存在,請確認是否添加了Android平台,如果未添加,請添加后執行此操作!'); end; end; procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction); begin // 關閉打開的DOS窗口 self.KillDosWindow; // 釋放被管理工程Dictionary projectDictionary.Free; end; procedure TForm2.FormCreate(Sender: TObject); var iniFile: TInifile; tempList: TStringList; i: Integer; begin // 是否選中插件默認值為false isSelectPlugin := false; // 是否選中平台默認值為false isSelectPlatfom := false; // -------------------------------------------- // 從ini文件獲取被管理的工程 // 被管理全部工程的Dictionary projectDictionary := TDictionary<string, string>.Create; try // ini配置文件 iniFileName := ExtractFilePath(ParamStr(0)) + configFile; // 實例化inifile類 iniFile := TInifile.Create(iniFileName); { A,得到當前正在管理工程信息 } // 1,得到cordova工程目錄 curProjectPath := iniFile.ReadString('curProject', 'path', ''); // 2,得到工程名稱 curProjectName := iniFile.ReadString('curProject', 'name', ''); curProjectNameEdt.Text := curProjectName; // 工程目錄 // curProjectDir := curProjectPath + '\' + curProjectName; if trim(curProjectName) <> '' then begin if rightStr(curProjectPath, 1) = '\' then begin // 工程全路徑名稱 curProjectDir := curProjectPath + curProjectName; end else begin // 工程全路徑名稱 curProjectDir := curProjectPath + '\' + curProjectName; end; // 顯示工程目錄 projectPathEdt.Text := curProjectDir; end; { B,得到全部被管理工程信息 } tempList := TStringList.Create; iniFile.ReadSectionValues('projectes', tempList); // 如果有被管理網站,則繼續處理 if tempList.Count > 0 then begin // 遍歷被管理網站 for i := 0 to tempList.Count - 1 do begin // 加入管理Dictionary中 projectDictionary.Add(tempList.KeyNames[i], tempList.ValueFromIndex[i]); // 在程序界面顯示被管理網站名稱 projectListBox.Items.Add(tempList.KeyNames[i]); end; end; finally iniFile.Free; tempList.Free; end; end; procedure TForm2.installCordovaBtnClick(Sender: TObject); begin if MessageBox(0, 'node.js和git已經都安裝完畢了嗎?', '提醒', MB_YESNO + MB_ICONWARNING) = IDYES then begin // // 關閉正在打開的DOS窗口 // self.KillDosWindow; // 安裝cordova DosCommand := 'npm install -g cordova'; // 執行DOS命令 self.RunDosCommand(DosCommand, true); end; end; // log方法 procedure TForm2.MyLog(tempLog: string); var temp: string; oldLog: string; begin if trim(tempLog) <> '' then begin oldLog := trim(logMemo.Text); logMemo.Clear; temp := FormatDateTime('yyyy-mm-dd hh:mm:ss', now) + ' ' + trim(tempLog); if oldLog = '' then begin logMemo.Lines.Add(temp); logMemo.Lines.Add(''); end else begin logMemo.Lines.Add(temp); logMemo.Lines.Add(''); logMemo.Lines.Add(oldLog); end; end; end; procedure TForm2.removePlatformBtnClick(Sender: TObject); var tempList: TStringList; tempCommand: string; platformStr: string; // 要添加平台命令字符串 begin // 得到選中平台 platformStr := trim(self.GetSelectedPlatform); if platformStr <> '' then begin try tempList := TStringList.Create; // 加入進入工程目錄的DOS命令 tempCommand := self.CdCordovaDirCommandStr(curProjectDir); tempList.Add(tempCommand); // 加入添加平台的cordova命令 tempCommand := 'cordova platform rm ' + platformStr + ' --save'; tempList.Add(tempCommand); // 執行所有命令 self.RunDosCommand(tempList, true); finally tempList.Free; end; end else begin showmessage('請選擇要刪除的平台,隨后執行刪除平台操作!'); end; // try // tempList := TStringList.Create; // // tempCommand := self.CdCordovaDirCommandStr(projectDir); // // tempList.Add(tempCommand); // tempList.Add('cordova platform rm android ios windows --save'); // // self.RunDosCommand(tempList, true); // // finally // tempList.Free; // end; end; // 關閉DOS窗口 procedure TForm2.KillDosWindow; const dosName: string = 'cmd.exe'; // DOS程序名稱 begin // 如果有DOS窗口打開,則強制關閉 if self.isExeRunning(dosName) = true then begin // 關閉DOS窗口 self.KillProc(dosName); // 延時,以便先前DOS窗口徹底關閉 sleep(50); end; end; // 執行DOS命令 procedure TForm2.RunDosCommand(commandStr: string; isPause: boolean); const // DOS命令加暫停關閉窗口的語句 commandHead: string = '/c '; PauseWindow: string = ' & pause'; var DosCommand: string; // Dos命令 begin // tempStr := '/c ping 192.168.1.1 & pause'; KillDosWindow; // 組裝DOS命令 DosCommand := commandHead + trim(commandStr); // 添加執行完操作后的暫停命令 if isPause = true then begin DosCommand := DosCommand + PauseWindow; end; // 打開DOS窗口,執行指定的命令 ShellExecute(Handle, nil, 'cmd.exe', PChar(DosCommand), nil, sw_normal); end; // 判斷是否Cordova工程目錄 function TForm2.IsCordovaDir(projectDir: string): boolean; const wwwDir: string = 'www'; // Cordova工程目錄中的"www"目錄名 pluginsDir: string = 'plugins'; // Cordova工程目錄中的"plugins"目錄名 platformsDir: string = 'platforms'; // Cordova工程目錄中的"plugins"目錄名 hooksDir: string = 'hooks'; // Cordova工程目錄中的"plugins"目錄名 var tempWwwDir: string; tempPluginsDir: string; tempPlatformsDir: string; tempHooksDir: string; isTrue: boolean; begin // Cordova工程目錄中的"www"目錄 tempWwwDir := trim(projectDir) + '\' + wwwDir; // Cordova工程目錄中的"plugins"目錄 tempPluginsDir := trim(projectDir) + '\' + pluginsDir; // Cordova工程目錄中的"plugins"目錄 tempPlatformsDir := trim(projectDir) + '\' + platformsDir; // Cordova工程目錄中的"plugins"目錄 tempHooksDir := trim(projectDir) + '\' + hooksDir; // 只有同時這四個目錄都存在時候,才判斷當前目錄是Cordova工程目錄 if (TDirectory.Exists(tempWwwDir) = true) and (TDirectory.Exists(tempPluginsDir) = true) and (TDirectory.Exists(tempPlatformsDir) = true) and (TDirectory.Exists(tempHooksDir) = true) then begin isTrue := true; end; result := isTrue; end; procedure TForm2.RunDosCommand(var stringList: TStringList; isPause: boolean); const // DOS連接命令符合(前面命令必須成功執行,才能執行后面命令) DosJoinCode: string = '&&'; dosName: string = 'cmd.exe'; var i: Integer; commandStr: string; begin // 如果有要執行的命令,則拼裝命令 if stringList.Count > 0 then begin // 拼裝命令 for i := 0 to stringList.Count - 1 do begin // 第一個命令,直接賦值 if i = 0 then begin commandStr := stringList[i]; end else begin // 其余命令依次添加到先前命令后,並且加入DOS多個命令鏈接符號"&&" commandStr := commandStr + DosJoinCode + stringList[i]; end; end; // MyLog(commandStr); // // 關閉正在打開的DOS窗口 // self.KillDosWindow; // 執行DOS命令 self.RunDosCommand(commandStr, isPause); end; end; procedure TForm2.selectLocalPluginBtnClick(Sender: TObject); begin if OpenDialog1.Execute then begin pluginNameEdt.Text := trim(OpenDialog1.FileName); end; end; // 是否程序正在運行 function TForm2.isExeRunning(exeName: string): boolean; var lppe: TProcessEntry32; isFound: boolean; Hand: THandle; tempName: string; // 程序名稱 temp: boolean; // 返回值變量 judgePos: Integer; // 擴展名判斷位置 begin Hand := CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0); lppe.dwSize := Sizeof(lppe); // 必須設置此值 isFound := Process32First(Hand, lppe); temp := false; // 返回的布爾值 // 程序名稱變量 tempName := trim(exeName); // 擴展名分隔符位置 judgePos := Pos('.', tempName); // 判斷是否有擴展名 if judgePos = 0 then begin tempName := tempName + '.exe'; // 添加".exe"擴展名 end else begin if length(Copy(tempName, judgePos, 4)) < 4 then begin // 刪除不符合添加的擴展名 Delete(tempName, judgePos, (length(tempName) - judgePos + 1)); // 添加".exe"擴展名 tempName := tempName + '.exe'; end; end; // 循環判斷是否有相同名稱程序 while isFound do begin // 判斷當前程序名稱和指定程序名稱相同 if lppe.szExeFile = tempName then begin temp := true; Break; end; // Memo1.Lines.Add(IntToStr(i) + ' : ' +IntToStr(lppe.th32ProcessID)+' '+ StrPas(lppe.szExeFile)); isFound := Process32Next(Hand, lppe); end; result := temp; end; procedure TForm2.selectPluginBitBtnClick(Sender: TObject); begin if isSelectPlugin = false then begin self.SelectPlugin(true); end else begin self.SelectPlugin(false); end; end; // 殺死進程 procedure TForm2.KillProc(procname: string); const PROCESS_TERMINATE = $0001; var ExeFileName: String; ContinueLoop: Bool; FSnapshotHandle: THandle; FProcessEntry32: TProcessEntry32; begin ExeFileName := procname; FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); FProcessEntry32.dwSize := Sizeof(FProcessEntry32); ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32); while Integer(ContinueLoop) <> 0 do begin if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFile) = UpperCase(ExeFileName))) then TerminateProcess(OpenProcess(PROCESS_TERMINATE, Bool(0), FProcessEntry32.th32ProcessID), 0); ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32); end; end; procedure TForm2.Label12Click(Sender: TObject); const asHelpUrl = 'https://www.cnblogs.com/sunylat/p/9674666.html'; begin ShellExecute(Handle, 'open', 'Explorer.exe', PChar(asHelpUrl), nil, 1); end; // 進入Cordova工程目錄的DOS命令字符串 function TForm2.CdCordovaDirCommandStr(CordovaDir: string): string; var dirStr: string; // 不包含盤符的cordova工程全路徑名 commandStr: string; begin dirStr := trim(CordovaDir); commandStr := 'cd /d ' + dirStr; result := commandStr; end; // 得到選中的插件 function TForm2.GetSelectedPlugin(isAdd: boolean): string; const spaceLetter: string = ' '; var tempStr: string; begin tempStr := ''; // 1,電池狀態 if batteryStatusCBox.Checked = true then begin tempStr := tempStr + 'cordova-plugin-battery-status' + spaceLetter; end; // 2,照相機 if cameraCBox.Checked = true then begin tempStr := tempStr + 'cordova-plugin-camera' + spaceLetter; end; // 3,通訊錄 if contactsCBox.Checked = true then begin tempStr := tempStr + 'cordova-plugin-contacts' + spaceLetter; end; // 4,設備 if deviceCBox.Checked = true then begin tempStr := tempStr + 'cordova-plugin-device' + spaceLetter; end; // 5,加速計 if deviceMotionCBox.Checked = true then begin tempStr := tempStr + 'cordova-plugin-device-motion' + spaceLetter; end; // 6,指南針 if compassCBox.Checked = true then begin tempStr := tempStr + 'cordova-plugin-device-orientation' + spaceLetter; end; // 7,通知 if dialogsCBox.Checked = true then begin tempStr := tempStr + 'cordova-plugin-dialogs' + spaceLetter; end; // 8,文件 if fileCBox.Checked = true then begin tempStr := tempStr + 'cordova-plugin-file' + spaceLetter; end; // 9,文件傳輸 if fileTransferCBox.Checked = true then begin tempStr := tempStr + 'cordova-plugin-file-transfer' + spaceLetter; end; // 10,地理位置 if geolocationCBox.Checked = true then begin tempStr := tempStr + 'cordova-plugin-geolocation' + spaceLetter; end; // 11,國際化 if globalizationCBox.Checked = true then begin tempStr := tempStr + 'cordova-plugin-globalization' + spaceLetter; end; // 12,多媒體 if mediaCBox.Checked = true then begin tempStr := tempStr + 'cordova-plugin-media' + spaceLetter; end; // 13,多媒體采集 if mediaCaptureCBox.Checked = true then begin tempStr := tempStr + 'cordova-plugin-media-capture' + spaceLetter; end; // 14,網絡 if networkCBox.Checked = true then begin tempStr := tempStr + 'cordova-plugin-network-information' + spaceLetter; end; // 15,閃屏 if splashScreenCBox.Checked = true then begin tempStr := tempStr + 'cordova-plugin-splashscreen' + spaceLetter; end; // 16,震動 if vibrationCBox.Checked = true then begin tempStr := tempStr + 'cordova-plugin-vibration' + spaceLetter; end; // 17,狀態欄 if statusbarCBox.Checked = true then begin tempStr := tempStr + 'cordova-plugin-statusbar' + spaceLetter; end; // 18,控制台 if consoleCBox.Checked = true then begin tempStr := tempStr + 'cordova-plugin-console' + spaceLetter; end; // 19,內置瀏覽器 if inappbrowserCBox.Checked = true then begin tempStr := tempStr + 'cordova-plugin-inappbrowser' + spaceLetter; end; // 刪除插件操作,需要把"cordova-plugin-"這些字符去掉 if isAdd = false then begin if trim(tempStr) <> '' then begin // 替換字符串 tempStr := StringReplace(tempStr, 'cordova-plugin-', '', [rfReplaceAll]); end; end; result := tempStr; end; // 選擇插件 procedure TForm2.SelectPlugin(isSelectAll: boolean); begin // 1,電池狀態 batteryStatusCBox.Checked := isSelectAll; // 2,照相機 cameraCBox.Checked := isSelectAll; // 3,通訊錄 contactsCBox.Checked := isSelectAll; // 4,設備 deviceCBox.Checked := isSelectAll; // 5,加速計 deviceMotionCBox.Checked := isSelectAll; // 6,指南針 compassCBox.Checked := isSelectAll; // 7,通知 dialogsCBox.Checked := isSelectAll; // 8,文件 fileCBox.Checked := isSelectAll; // 9,文件傳輸 fileTransferCBox.Checked := isSelectAll; // 10,地理位置 geolocationCBox.Checked := isSelectAll; // 11,國際化 globalizationCBox.Checked := isSelectAll; // 12,多媒體 mediaCBox.Checked := isSelectAll; // 13,多媒體采集 mediaCaptureCBox.Checked := isSelectAll; // 14,網絡 networkCBox.Checked := isSelectAll; // 15,閃屏 splashScreenCBox.Checked := isSelectAll; // 16,震動 vibrationCBox.Checked := isSelectAll; // 17,狀態欄 statusbarCBox.Checked := isSelectAll; // 18,控制台 consoleCBox.Checked := isSelectAll; // 19,內置瀏覽器 inappbrowserCBox.Checked := isSelectAll; // 設置是否已經選擇全部插件的值 isSelectPlugin := isSelectAll; if isSelectAll = true then begin selectPluginBitBtn.Caption := '全 不 選'; selectPluginBitBtn.Font.Color := clRed; end else begin selectPluginBitBtn.Caption := '全 選'; selectPluginBitBtn.Font.Color := clBlue; end; end; // 得到特殊目錄 function TForm2.GetSpecialDir(SpecialDirID: Integer): string; var pidl: PItemIDList; Path: array [0 .. MAX_PATH] of Char; begin SHGetSpecialFolderLocation(0, SpecialDirID, pidl); SHGetPathFromIDList(pidl, Path); result := Path; end; // 得到用戶目錄 function TForm2.GetAppDir: string; begin result := GetSpecialDir(CSIDL_APPDATA); end; { 得到選中的平台 isAdd:是否添加插件平台(tru,添加;false,刪除) } function TForm2.GetSelectedPlatform: string; const spaceLetter: string = ' '; var tempStr: string; begin tempStr := ''; // 1,androidwindows if androidCBox.Checked = true then begin tempStr := tempStr + 'android' + spaceLetter; end; // 2,ios平台 if IOSCBox.Checked = true then begin tempStr := tempStr + 'ios' + spaceLetter; end; // 3,windows平台 if windowsCBox.Checked = true then begin tempStr := tempStr + 'windows' + spaceLetter; end; result := tempStr; end; // 選擇平台 procedure TForm2.SelectPlatform(isSelectAll: boolean); begin // 安卓平台 androidCBox.Checked := isSelectAll; // IOS平台 IOSCBox.Checked := isSelectAll; // Windows(8.1, 10,Phone 8.1) windowsCBox.Checked := isSelectAll; isSelectPlatfom := isSelectAll; if isSelectAll = true then begin selectPlatformBitBtn.Caption := '全 不 選'; selectPlatformBitBtn.Font.Color := clRed; end else begin selectPlatformBitBtn.Caption := '全 選'; selectPlatformBitBtn.Font.Color := clBlue; end; end; procedure TForm2.selectPlatformBitBtnClick(Sender: TObject); begin if isSelectPlatfom = false then begin self.SelectPlatform(true); end else begin self.SelectPlatform(false); end; end; // 顯示被管理工程信息 procedure TForm2.ShowProjectInfo(var projectDic: TDictionary<string, string>; var projectListBox: TListBox); var i: Integer; siteNameStr: string; // 被管理網站名稱 begin // 清除先前顯示信息 projectListBox.Clear; // 如果有被管理網站,則繼續處理 if projectDic.Count > 0 then begin // 遍歷被管理網站 for siteNameStr in projectDic.Keys do begin // 添加被管理網站名稱到ListBox上 projectListBox.Items.Add(siteNameStr); end; end; end; // 通過工程全路徑名稱得到工程路徑和名稱 procedure TForm2.GetProjectPathAndName(projectDir: string; var projectPath: string; var projectName: string); var lastPos: Integer; // 全路徑名稱中最后一個"\"出現位置 begin // 全路徑名稱中最后一個"\"出現位置 lastPos := LastDelimiter('\', projectDir); // 得到路徑名稱 projectPath := LeftStr(projectDir, lastPos - 1); // 得到工程名稱 projectName := rightStr(projectDir, length(projectDir) - lastPos); end; // 對ini文件內容操作(添加和刪除) procedure TForm2.OperateIniFile(iniFileName, section, key, value: string; isAdd: boolean); var iniFile: TInifile; begin try iniFile := TInifile.Create(iniFileName); if isAdd = true then begin iniFile.WriteString(section, key, value); end else begin iniFile.DeleteKey(section, key); end; finally iniFile.Free; end; end; procedure TForm2.projectListBoxDblClick(Sender: TObject); begin if projectListBox.ItemIndex <> -1 then begin // 被選中工程名稱 curProjectName := trim(projectListBox.Items[projectListBox.ItemIndex]); curProjectNameEdt.Text := curProjectName; // 工程路徑 curProjectPath := projectDictionary.Items[curProjectName]; // 工程名稱 if rightStr(curProjectPath, 1) = '\' then begin // 工程全路徑名稱 curProjectDir := curProjectPath + curProjectName; end else begin // 工程全路徑名稱 curProjectDir := curProjectPath + '\' + curProjectName; end; projectPathEdt.Text := curProjectDir; // 把工程名稱寫入當前工程名稱 self.OperateIniFile(iniFileName, 'curProject', 'name', curProjectName, true); // 把工程路徑寫入當前工程路徑 self.OperateIniFile(iniFileName, 'curProject', 'path', curProjectPath, true); logInfo := '當前工程已更換為:' + #13#10; logInfo := logInfo + curProjectName; self.MyLog(logInfo); end; end; // 同步數據 procedure TForm2.SyncProjectes(var projectDic: TDictionary<string, string>; var projectListBox: TListBox; iniFileName: string; isDicToIni: boolean); var iniFile: TInifile; tempList: TStringList; i: Integer; key: string; begin try iniFile := TInifile.Create(iniFileName); tempList := TStringList.Create; if isDicToIni = true then begin // 刪除被管理工程原有小節信息 iniFile.EraseSection('projectes'); // 清除ListBox顯示數據 projectListBox.Clear; // 把Dictionary中所有被管理工程信息寫入Ini for key in projectDic.Keys do begin // 寫入ini文件 iniFile.WriteString('projectes', key, projectDic.Items[key]); // 在ListBox上顯示數據 projectListBox.Items.Add(key); end; end else begin // 清除Dictionary先前數據 projectDic.Clear; // 清除ListBox顯示數據 projectListBox.Clear; iniFile.ReadSectionValues('projectes', tempList); // 如果有被管理網站,則繼續處理 if tempList.Count > 0 then begin // 遍歷被管理網站 for i := 0 to tempList.Count - 1 do begin // 加入管理Dictionary中 projectDic.Add(tempList.KeyNames[i], tempList.ValueFromIndex[i]); // 在程序界面顯示被管理網站名稱 projectListBox.Items.Add(tempList.KeyNames[i]); end; end; end; finally iniFile.Free; tempList.Free; end; end; // 延時 procedure TForm2.Delay(msecs: Integer); var Tick: DWORD; Event: THandle; begin Event := CreateEvent(nil, false, false, nil); try Tick := GetTickCount + DWORD(msecs); while (msecs > 0) and (MsgWaitForMultipleObjects(1, Event, false, msecs, QS_ALLINPUT) <> WAIT_TIMEOUT) do begin Application.ProcessMessages; msecs := Tick - GetTickCount; end; finally CloseHandle(Event); end; end; end.