Cordova - Windows版本圖形界面管理工具,告別命令行輸入方式!


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.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM