我們開發的系統,有時候會包含一些配置資訊,需要使用者在系統安裝後自己去設定,例如我們有一個GPExSettings.xml檔案,內容如下。
<GPExSettings ArcPythonPath="C:\Python27\ArcGIS10.8\python.exe" IsUseArcPython="False" />
正常情況下,使用者安裝了系統,使用過程中,會對系統進行一些設定,即修改了GPExSettings.xml檔案。過段時間,如果系統更新了,無論是解除安裝後再重新安裝,還是直接安裝系統進行更新,都會把GPExSettings.xml替換掉,這樣使用者自定義的設定就不見了。
這樣使用者體驗還是比較差的,每次安裝後,都要重新設定一遍,如果只有一兩個設定項還可以,如果很多的話,使用者會瘋掉的。或則你在說明書上寫上,在安裝新版本之前,把安裝目錄下的某個xml檔案先複製出來,安裝後,再複製過去,這樣的傻方案,你還別說,剛畢業沒多長時間的時候,我就跟使用者這麼說過。
開發桌面軟體,我打包的時候使用Inno Setup Compiler工具,但都使用裡面比較簡單的功能,例如設定系統名稱、版本號、要打包的檔案、桌面圖示、開始選單和解除安裝選單等。
[Files] Source: "D:\2022\01GeoChem_2022\程式碼\打包\Release\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "D:\2022\01GeoChem_2022\程式碼\打包\DEV\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs [Icons] Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}";IconFilename: "{app}\App.ico" Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{app}\unins000.exe" Name: "{userdesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; IconFilename: "{app}\App.ico";
【Files】部分設定了要打包那些資料夾或者檔案,[Icons]部分設定了開始選單、解除安裝選單以及桌面圖示。如果你想設定GPExSettings.xml檔案在部署的時候,透過安裝目錄下有同名檔案,可以選擇不覆蓋,這個我在網上查了下,新增上一個命令就可以了。但如果有好幾個這樣的檔案,還是比較麻煩的。如果使用者先解除安裝了舊版本,就會把打包的時候,包含的所有檔案都解除安裝掉。那這樣是不是還要加上一條命令,解除安裝的時候不要把GPExSettings.xml檔案解除安裝掉?
這樣的話,感覺太麻煩了,而且我還是想優先保障打包指令碼的簡單性,不想搞那麼複雜,這種靠命令式的指令碼,總感覺不那麼靈活,所以我們就在程式碼中想辦法。
我們可以在程式碼中建立GPExSettings_Bak.xml檔案,可以稱該檔案為GPExSettings.xml的初始或者備份檔案。程式碼在讀取GPExSettings.xml內容的時候,先判斷GPExSettings.xml檔案是否存在,如果存在,則直接讀取,不存在,則複製GPExSettings_Bak.xml檔案,重新命名為GPExSettings.xml,再讀取。
並且打包的時候,不要把GPExSettings.xml打進去,只打包GPExSettings_Bak.xml檔案,這樣就不會存在安裝更新包會把使用者設定後的GPExSettings.xml給覆蓋掉,也不會出現解除安裝的時候把GPExSettings.xml檔案解除安裝掉,就達成了我們的目的。
private static readonly string _XmlFilePath = AppDomain.CurrentDomain.BaseDirectory + "Res\\GPExSettings.xml"; private static readonly string _BakXmlFilePath = AppDomain.CurrentDomain.BaseDirectory + "Res\\GPExSettings_Bak.xml"; /// <summary> /// 執行器的配置資訊 /// </summary> static GPExSettings() { if (File.Exists(_XmlFilePath) == false) { if (File.Exists(_BakXmlFilePath) == false) { throw new ArgumentException("GPExSettings_Bak.xml file not exist."); } File.Copy(_BakXmlFilePath, _XmlFilePath); } try { XmlDocument myXmlD = new XmlDocument(); myXmlD.Load(_XmlFilePath); XmlNode myXmlNode = myXmlD.ChildNodes[0]; ArcPythonPath = myXmlNode.Attributes["ArcPythonPath"].Value; IsUseArcPython = Convert.ToBoolean(myXmlNode.Attributes["IsUseArcPython"].Value); } catch (Exception ex) { throw new ArgumentException("Load GPExSettings.xml fail," + ex.Message); } }