[iOS] 更新 App


話說,12/11 收到 Apple 寄來的信:


Dear [我的英文名],

Your app, [我的 App 名], app Apple ID: [App 代碼], does not follow one or more of the App Store Review Guidelines.

For details, or to contact App Store Review, visit Resolution Center in App Store Connect.

Best regards,
App Store Review


因為看不出來要幹嘛,所以沒理他。

01/20 收到 Apple 更新的信:


Dear [我的英文名],

On September 1, 2016, we announced that we’re implementing an ongoing process of evaluating and removing apps from the App Store that no longer function as intended, don’t follow current review guidelines, or are outdated.

You were asked to submit an updated version of your app, [我的 App 名], app Apple ID: [App 代碼], for review within 30 days. We noticed that either you did not submit an updated version of your app or the updated version of your app was not approved. As a result, your app has been removed from the App Store.

Next Steps

Your app has not been deleted from your account. To make your app available on the App Store, submit an updated version that follows the latest App Store Review Guidelines. Your app will become available on the App Store if the update is approved. If you submitted an update after the 30 day grace period, please allow time for review.

Additional Information

Learn more about changes to the App Store and keeping your apps up-to-date.

App Store Improvements
App Review Resources
Debugging Your Apps

Best regards,
App Store Review


我還真不知道,Apple 上架後,一定時間內要更新,不然就強制下架,這個時間看起來差不多是三年。

我主要是做 HTML5 網頁去適應手機、平板,所以當初 App 只有做 WebView 框架,只要把 WebView 導向到我的 HTML5 網頁即可,所以只需要重新編譯上傳。

MacBook Pro 很久沒開機了,所以 01/21 主要是在更新 MacBook Pro ,01/22 才開始關關難過關關過。

關卡 1 :MacBook Pro 開不了機

大概是太久沒接電,應該是沒電了,插上電源一開始一直開不了機,而且我可能插錯 Type-C 的充電孔,我看到有兩孔,先插上面那孔 (接近軸承),一直沒作用,大概過 10 分鐘發現到還有一孔,換了一孔後再試,就可以正常開機了,但是 MacBook Pro 完全沒有電源指示燈,再一開始根本不知道哪的問題。

關卡 2:更新 Mac OS / XCode / Visual Studio for Mac

先前的經驗就是得先更新,更新時一定要注意 XCode :[iOS] 環境升級後,無法正常編譯 App

更新 Mac OS 純粹就是花時間而已,下載久,更新久,重開機久,沒想到更新 XCode 也久。

等到看向 Visual Studio for Mac 時,已經更新完了,但是我不認識它了。原來三年前是 Visual Studio 2017 for Mac ,更新完後是 Visual Studio 2019 for Mac 。

關卡 3:重新產生憑證

更新完了以後,從方案總管那邊的選項找到可以填寫版號,專案總管那邊預設溝選繼承方案總管版號,改完以後直接重新編譯,但錯誤訊息卻說找不到憑證可以簽名 (已經過期) 。從 [鑰匙圈存取] (Key Chain) 看得到過期的憑證。

所以就照先前文章開新的憑證:[iOS] 建立 App Store 簽名用的憑證給 Visual Studio for Mac 使用

整別人最後的下場就是整自己,Visual Studio 介面上可以直接產生憑證,我當初放在最後一個畫面,所以我自己又跟著我原先的步驟產生了新的 [iOS Distribution] ,中間 Apple 網站有些有更新的,但是不影響產生佈建用的憑證。

看到最後,Visual Studio 那個畫面,我自己都想揍我自己,當初幹嘛耍寶… 我用 Visual Studio 產生佈建用的憑證時,只剩下新的 [Apple Distribution] 可選,查了一下,新增的 [Apple Distribution] 包含 [iOS Distribution] ,可以只產生 [Apple Distribution] ,此外原先 [iOS Distribution] 在帳號理可同時有 2 個,現在變成只能有 1 個,而新增的 [Apple Distribution] 可同時有兩個。

關卡 4:編譯器無法使用新憑證簽名

編譯時跳錯誤:

/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets(3,3): Error: 無法針對 ‘bin/iPhone/Release/[專案名].app’ 進行程式碼簽署: Warning: unable to build chain to self-signed root for signer “Apple Distribution: 公司名
/Users/support/Projects/[專案名]/[專案名]/bin/iPhone/Release/[專案名].app: errSecInternalComponent

首先想說錯誤訊息有中文,先搜尋了中文相關說明,但是沒有有用的內容。

改用英文錯誤訊息搜尋,參照這篇:Unable to build chain to self-signed root

要求依照官方文件這篇處理:Apple Worldwide Developer Relations Intermediate Certificate Expiration

這篇的意思是說,因為 Apple 有更新相關開發的憑證,我的 MacBook Pro 憑證太舊,我新產生的憑證參照的新憑證不存在,所以不被信任,不可用來簽名。的確,從 [鑰匙圈存取] 看到憑證的狀態是不可信,所以只要照官方文件更新 XCode 即可自動更新憑證,但是我 XCode 已經更新到最新的,怎麼會還是舊的?

參考一位 MVP 的說明:iOS Development 的憑證、簽署識別、佈建設定檔在使用 Xamarin 開發 iOS App 時要如何設定(手動篇I)

從 XCode [Preferences] 新增 開發人員帳號後,點選 [Manage Certificates…] 即可,剛好我 [鑰匙圈存取] 在背景,就看到新增了對應憑證,我的佈建用憑證也變為可信任的,就順利完成編譯。

關卡 5:無法封存以供發行

參考自己先前寫的這篇:[iOS] 上傳 App 到 App Store 供散佈

編譯完成後,經過在不同模擬器跑都正常,就準備封裝以供發行,但跑到上傳前,卻一直跳錯:

unable to vaidate archive

這次只搜尋這個錯誤訊息也找不到有用的訊息,我測試一下,封裝是可以正確產生 [專案名].ipa 的,所以我想是不是 Apple App 設定問題?最後重新輸入我的 [App 專用密碼] 就正常了,沒想到 Visual Studio 自動升級後,記憶的密碼居然是錯的…

我想可能封裝不用檢查發行用的 [App 專用密碼] ,所以可以封裝,但是要上傳 Apple 的 App Store ,會檢查 [App 專用密碼] ,所以無法驗證封裝檔案。

關卡 6:App 版本編號還是舊的

先前說到,我在方案總管、專案總管都有看到可設定版號,我以為是這裡就可以搞定,但是我每次封裝完的 App 都是舊版版號,被拒絕執行下一步,最後在程式碼 [info.plist] 裡面找到版號,更新這邊的版號才有作用。

關卡 7:無法上傳到 App Store

封裝完沒問題後,卻跳出無法上傳到 App Store ,這部份是我自己真的忘了,但我應該知道,我先前也沒紀錄到。

要上傳之前,App Store Connect 那邊要先針對新版號開一個空間,Visual Studio 才能把新版上傳到這個位置,開好就正常了。

Visual Studio 2019 for Mac 不用像 Visual Studio 2017 for Mac ,先產生 [專案名].ipa ,而是直接產生完後就上傳,所以會找不到 [專案名].ipa ,但也方便很多。

關卡 8:要上傳新的螢幕擷圖

回到關卡 7 的網頁,新版本要求要四種版本的畫面擷圖,其中包含 iPhone 6.5 吋跟 iPad Pro 12.9 吋 (第三代) ,起先模擬器我跑 iPhone 13 的,沒想到居然尺寸不對,上 Apple 官方網站查詢以後,改用 iPhone 11 Pro Max ,iPad Pro 12.9 吋就比較單純,模擬器是第五代的,一次搞定。

關卡 9:隱私權聲明

關卡 7 的網頁更新擷圖後,要提交審查,還要求勾選隱私權聲明,就是沒有在 App 裡面蒐集使用者資料。想當然爾,WebView 啥都做不了,勾選了聲明後,終於可以提交審查了。

上架

前次的經驗審查滿久的,這次還算順利,01/22 16:24 完成提交審查,01/23 00:01 開始審查,01/23 08:50 完成審查上架,不過比較奇怪的是先被下架,不知道是不是按錯了,同一分鐘兩種操作。

通過審查重新上架

後記

太久沒用 MacBook Pro 了,我已經忘了擷圖要按哪顆鍵,所以這篇都沒有擷圖可參考…

Categories: 工作點滴, 技術分享 | 標籤: | 發表留言

[RouterOS] 虛擬機試用


這篇最早應該不能算是測試心得,只是最後走到 RouterOS 虛擬機。

2020/07 公司因為業務要經銷資安系統,所以公司也買一套資安系統作為展示與測試的環境。但過了一年,業務決定要放棄,這套資安系統就不續約了,閒置的空主機,在 2021/12 公司決定要導入顧大俠的產品時,就打算安裝在這台閒置主機上。

原先的閒置主機的 OS 是 VMWare ESXi 6.7 (7.0 降級授權) ,當初資安系統虛擬磁碟用了完整佈建 (固定容量大小) ,把閒置主機吃掉近 2 TB 硬碟容量,將近 1/2 實體容量,但虛擬機內實際只吃了 31 GB,而 VMWare ESXi 的相關指令不能縮小這顆虛擬硬碟,所以打算用實體機常用的 ToDo Backup 來做。

由於 VMWare ESXi 實體空間不是很夠,所以分階段降低硬碟容量。

1. 把資安系統的虛擬硬碟做填 0 動作,然後透過磁碟管理盡量縮小容量,縮小後,再找磁碟重整軟體,把後方空間盡量清空,再重作磁碟管理縮小容量,虛擬機關機。

2. 把 Todo Backup 虛擬化開機,然後把資安系統虛擬硬碟掛載到 ToDo Backup ,打算備份到新的虛擬硬碟,沒想到 Todo Backup 免費版不支援空硬碟格式化,挖哩勒…

EaseUS Todo Backup Free 下載點:https://tw.easeus.com/backup-software/todo-backup-free.html

3. 下載 USBoxV6 光碟開機版,裝到 VMWare ESXi ,強制設定永遠從光碟開機,掛載空的虛擬硬碟初始化。

USBoxV6 下載點:https://hsuanthony.pixnet.net/blog/post/225209033

4. 終於 Todo Backup 把新的虛擬硬碟做好,想要備份到檔案伺服器上,才發現 VMWare ESXi 這台在 Server 區,Server 網段不允許 DHCP ,所以 Todo Backup 無法自動取得 IP 連線到檔案伺服器上。

到這邊是我的前提,當然有其他方案可以考慮,我想到我之前還有待辦清單要測試 NTP Server 、Class A、切 16/512/131072 個 IP,所以打算用 RouterOS 虛擬機做橋接,讓 RouterOS 拿 Server 區的固定 IP ,派發虛擬 IP 給 Todo Backup 之類的虛擬機,先用 192.168.0.0/16 來設定,所以在 VMWare ESXi 開了虛擬 Switch192 出來。

RouterOS 虛擬機下載:https://mikrotik.com/download (點選 Cloud Hosted Router 有不同 Host 的虛擬機可下載)

我是掛在 VMWare ESXi ,當然下載 VMDK image 檔,虛擬機配置如下:

項目說明
CPU1 核即可,我配置 2 核
DRAM最好大於 64 MB,我配置 128 MB
HDD選既有的磁碟 (64 MB),配置 IDE (0, 0) ,主要磁碟
網卡 1Server 區的網段
網卡 2vNetwork192
RouterOS 虛擬機配置
啟動配置好的 RouterOS

RouterOS 虛擬機是空機,初始化配置有點複雜,建議對一下既有的硬體配置設定,或是看看相關教材。

網路測通後,Todo Backup 終於能備份到檔案伺服器上,備份完後,我把 Todo 儲存備份檔的虛擬磁碟清空,節省容量。

這又是另一個悲慘的故事,我沒注意到當初資安廠商建立虛擬機時,有用差異快照檔案功能,所以我備份的 vmdk 是建立快照時的空的 Windows ,不含任何資安軟體與 log … 但我已經砍掉了,算了,以後要續約的時候,再請廠商重新安裝。

RouterOS 不同網段測試的部分就不一一列示,我測完 Class A 後,直接把 Class A 的測試檔拿來改,測試切成 16 個 IP 。

快速設定 16 個 IP 網段

IP 計算機可參考:https://www.iptp.net/zh_HK/iptp-tools/ip-calculator/

從 10.1.1.177 切 16 個 IP 範圍是 176 ~ 191 ,前後兩個 IP 不能用,剩下 177 ~ 190 共 14 個 IP 可用,拿 177 做 Gateway ,另外再把 184 ~ 187 共 4 個 IP 設為 DHCP 範圍。

讓 Windows 從 RouterOS 的 DHCP 自動取得 IP :

自動取得 16 個 IP 的網段

RouterOS 的 DHCP 預設會從 IP Pool 最後一個開始分配,滿了以後,會從 Next Pool 開始分配,若都沒有 IP 了,就會分配失敗。所以從 187 自動取得。

RouterOS 的 NTP client 是內建的,NTP Server 是官方外掛套件。

RouterOS 外掛套件下載:https://mikrotik.com/download (虛擬機下載 x86 的 Extra packages)

安裝好 NTP Server

安裝好 NTP Server 會出現在 System 選單中,通常要啟用 NTP Server 時,通常也要啟用 NTP Client ,NTP Client 用來對上游校時,NTP Server 則是給下游校時用。

上游的 NTP Server 很多,例如說 Windows 內建的是 time.windows.com ,但因為是 Windows 內建的,所以幾乎全球的 Windows 都跟它校時,常常連不上。

在台灣可以使用政府標準檢驗局的標準時,由1969年成立的國家時間與頻率標準實驗室發布,是委託給中華電信研究院負責。

國家時間與頻率標準實驗室 網址:https://www.stdtime.gov.tw/

目前國家提供的時間伺服器 (NTP Server) 有:

  • tick.stdtime.gov.tw
  • tock.stdtime.gov.tw
  • time.stdtime.gov.tw
  • clock.stdtime.gov.tw
  • watch.stdtime.gov.tw

既然是國家標準時,自然一堆政府機關、半官方法人、團體等都是對國家標準時校時,所以用戶多,常常碰上連不上 (逾時) 的情況。

既然是中華電信執行,而且公司網路基本上都在中華電信上,所以我一般都跟中華電信校時。

clock.hinet.net (168.95.192.12)

其次是效能不錯的 Google 時間伺服器,早期 Google 分成 4 台時間伺服器,現在用 DNS 做自動平衡,一般使用者用 time.google.com 即可。

別名NTP ServerIPv4IPv6
timetime1216.239.35.02001:4860:4806::
timetime2216.239.35.42001:4860:4806:4::
timetime3216.239.35.82001:4860:4806:8::
timetime4216.239.35.122001:4860:4806:c::
Google 的時間伺服器

所以 RouterOS 對上游校時的主伺服器設定為中華電信,次伺服器設定為 Google 。

Windows 再對 RouterOS 校時即可。

對 RouterOS 校時。

在有 AD 架構下的網域,Windows Client 會自動對 AD Server 校時,另外 Windows Server 可以透過 regedit 修改啟用 NTP Server ,倒不一定要用到這個方案。

我這個方案是要用在現場,現場沒有 Windows Server,而 RouterOS 的硬體都是便宜大碗的工業級設備,支援多 WAN ,多通道的 Site To Site VPN,唯一的缺點就是設定複雜,現場網路設備多需要校時,統一對 RouterOS 校時最好,把校時流量關在 LAN 裡面,只有 RouterOS 走 WAN 去校時。

Categories: 工作點滴, 技術分享 | 標籤: | 發表留言

[RouterOS] 啟用 PPTP Server


RouterOS 因為價美物廉,一直被我拿來用在現場。大部分的網路硬體環境溫度都超過 65 度,基本上是免空調,網孔在 2012 年就是 Gb 級,功能強悍。

現場有需要建立 Site To Site 的 VPN 通道,讓兩邊網段可以直接互聯,速度不需要很高,所以早期我都是用 ADSL ,client 端用 2M/64k ,Server 端用 8M/640k (1 固+7 浮動 IP),當然後來光纖普及了,就會用光纖。

因為設備真的很穩定,所以很少需要維護,甚至到忘了使用者介面的位置在哪。這篇的目的就是提醒我自己。

協力廠商反映現場 client 端不能連線,工程人員去現場,久到連密碼都不可考,所以拆回來,恢復成原廠狀態,再把出機參數還原,還原後才發現 server 端撥不進去。

用 telnet 在公司測試,port 沒開,連到現場檢查,的確 pptp service 沒作用,所以得把 pptp server 啟動。

但太久沒操作,久到連介面都不知道在哪。

只好到原廠官網查,官網都只有命令列模式,所以從命令列模式去下指令,恢復 pptp Server 啟用:

官網的說明:https://help.mikrotik.com/docs/display/ROS/PPTP

pptp Server 啟用

可以看到,先啟用 Terminal 後輸入以下指令:

interface pptp-server
server set enabled=yes

啟用後,client 就撥通 VPN ,自動建立通道完成。

我印象中,pptp Server 是有介面可以啟用,但是就是想不起來在哪。之後開台 VM 放 RouterOS 的映像檔來測:

pptp Server 啟用

原來是選單 選 [PPP] ,點選工具列的 [PPTP Server] ,就有介面可以啟用。為啥我之前就是找不到呢?

寫一篇文提醒自己,下次找不到,回網誌翻就可以了。

Categories: 工作點滴, 技術分享 | 標籤: | 發表留言

[VBA] Excel 安全性調整後,跨檔案所需要的變更


我大概是 Excel 4.0 開始用巨集的,到了 Excel 5.0 (Office 4.2 / 4.3) 轉成 VBA 以後,我就比較經常用,那時 Word 6.0a 的巨集還不是 VBA ,而是 WordBasic ,到 Office 95 才統一為 VBA 。

1996/07 碩畢當兵前要交接研究資料給學弟時,寫了一篇做內部教育訓練。

MS Office 自動化巨集 http://www.tlcheng.tk/TLCheng/Basic/Office/officevb.htm

這篇是在 1999/02/03 網頁化上網分享,念碩士的時候還是 Excel 5.0 + Word 6.0a ,做研究計畫、論文會大量用到 Excel 整理數據,例如我的碩士論文是做人工智慧,用 VB3 寫類神經網路 (BPN) 跟自己修改的模型 (有點類似現在的 RNN) ,在下班後,丟到一堆助理的電腦上去跑,借同學的電腦夜間跑,白天一早來暫停目前類神經網路學習進度儲存後,備份計算結果各台電腦還給大家用,白天我則利用 Excel VBA 整理數據出表格、圖形自動貼到 Word 印出後,跟指導教授討論。

工作後寫 Excel VBA 的機會變少,有大量資料要分析的時候,我才會拎出來用。

Office 2007 以後,基於安全考量,有 VBA 的檔案要存成 .xlsm ,我也開始養成慣例,把 VBA 單獨寫成一個檔案,資料檔跟輸出檔分在不同的檔案,方便安全管理,大概是前三年左右吧,不知道 Excel 哪個安全性更新起,存成 .xlsm VBA 裡面的函數就不能跨黨案使用,必須存成 .xlam 做成增益集。

我以前個人基於安全考量,希望 Excel 開起來是乾乾淨淨的,所以一直沒做成增益集來用,但 Excel 內有些函數功能真的不足,還不如呼叫 VBA 內建函數,所以我就把我常用的 VB 內建函數跟自己常用的函數建成一個 VbaTools.xlam 來引用。

一個新的 .xlsm 開發完成後,可以另存新檔為 .xlam ,這時 Excel 會自動導向存放增益集的路徑,我習慣放在我個人區,移動到其他台電腦用複製貼上即可,但是預設不會啟用,要自己勾選起來。

個人區域設路徑為 %AppData%\Microsoft\AddIns

開啟 Excel 後,左上角 選單 > 檔案 > 選項 > 增益集

自訂增益集

找到自己的增益集後,下方 [管理] 選擇 [Excel 增益集] ,選擇 [執行]。

如果沒有正常出現自己的增益集,可從右側 [瀏覽] 按鈕下去尋找。

勾選自己的工具

勾選後按下確定即可。

接下來就可以在任意檔案中呼叫增益集內的函數。

呼叫增益集內的函數

比如說 Excel 內的 REPLACE 函數,一次呼叫只能替換第一格發現的字串,但是 VBA 內建函數可以一次替換所有可發現的字串,一下子就方便不少。

所以我在前年寫了個兩小時教育訓練排在去年執行,主要是讓同事知道 Excel 還能做甚麼,針對大量重複的行政作業或流程,有需要找資訊部開發。

Excel VBA 內部教育訓練簡報檔

前兩個月執行老闆叫我進行的分析,因為資料量滿大的,所以我在其他 .xlsm 的巨集打算呼叫 VbaTools.xlam 時,發現居然不能直接呼叫。

開啟舊的兩個 .xlsm 也不能互相呼叫了。

我過去的慣例是會把共用的函數 .xlsm 另外開一個檔,專用的函數 .xlsm 自己存一個檔,自先前改用 VbaTools.xlam 後,就把共用的函數轉移進去,而且我記得先前還能用。

兩年前在寫這篇時:

[Excel]白做工了,規劃求解與 VBA https://tlcheng.wordpress.com/2019/05/12/excel%e7%99%bd%e5%81%9a%e5%b7%a5%e4%ba%86%ef%bc%8c%e8%a6%8f%e5%8a%83%e6%b1%82%e8%a7%a3%e8%88%87-vba/

用 測試.xlsm 還能呼叫 規劃求解 的 VBA 函數,連程式碼截圖都在,我也不知道為啥就不行了。

經搜尋新的方案是要加入參照才能呼叫其他 .xlsm / .xlam 的函數:

參照 VbaTools.xlam

參照完舊可以在瀏覽物件瀏覽程式庫時,看到 VbaTools.xlam 函數。

程式庫瀏覽

這個月還沒想到要寫甚麼,怕忘記 Excel 的 VBA 變化,寫下來提醒自己。

Categories: Office, 工作點滴, 技術分享 | 標籤: | 發表留言

[T-SQL] 配合 EXISTS 刪除資料庫重複資料


資料庫裡面有超過兩億筆的資料,每次跑 DELETE 一筆資料,就要跑好久,所以想說把問題資料一次刪除。

流程步驟大概是這樣:

  1. 匯出重複資料到暫存資料庫
  2. 刪除重複資料
  3. 從暫存資料庫匯入不重複資料 (SELECT DISTINCT)

所以這篇要談的是上面步驟 2。

測試語法前,先產生一個測試資料表:

測試資料表

SN 是我的資料項目代號,如果不容易理解,可以換個想法,當作大學全校學生的考試成績,SN 是科目代號,DataTime 是考試時間,DataValue 是考試分數,Quality 是學生代號,大學生每個人選修科目都不同,所以不能直接做橫向列表來紀錄成績。

所以這個資料表沒有 PK ,只有 SN / DataValue / Quality 有可重複的索引值。

而在這個超過兩億筆的資料裡面,目前檢查有 29k 筆資料重複,如果逐筆刪除,會消耗大量時間,所以測試我不熟的 EXISTS 來刪除。

由於我的資料項目代號並不重複,我就省掉 Quality 的欄位,所以撈出重複資料的語法很單純:

SELECT SN, DataTime
FROM (
	SELECT SN, DataTime, COUNT(SN) AS nCount
	FROM Data_Temp
	GROUP BY SN, DataTime
) AS Data_Limit
WHERE nCount > 1

我一直以為搭配 EXISTS 是類似子查詢,把上面語法嵌入即可,不過實際上不是,需要把 WHERE 條件合併,測試時,先用 SELECT 測:

用 SELECT 測試 EXISTS
SELECT *
FROM Data_Temp
WHERE EXISTS (
	SELECT SN, DataTime
	FROM (
		SELECT SN, DataTime, COUNT(SN) AS nCount
		FROM Data_Temp
		GROUP BY SN, DataTime
	) AS Data_Limit
	WHERE nCount > 1 AND Data_Temp.SN=Data_Limit.SN AND Data_Temp.DataTime=Data_Limit.DataTime
) 
;

如上面語法,其中,下底線加粗體字的條件,基本上就是 JOIN 在 ON 後面的條件,要一起組進去,組好測試無誤後,把 SELECT 改成 DELETE 即可。

最後測試完成的語法:

DELETE 
FROM Data_Temp
WHERE EXISTS (
	SELECT SN, DataTime
	FROM (
		SELECT SN, DataTime, COUNT(SN) AS nCount
		FROM Data_Temp
		GROUP BY SN, DataTime
	) AS Data_Limit
	WHERE nCount > 1 AND Data_Temp.SN=Data_Limit.SN AND Data_Temp.DataTime=Data_Limit.DataTime
) 
;

實際在用的時候,要在 GROUP BY 之前再加入一個 WHERE DataTime<=’日期’ 的條件,避免有即時備份重複資料時,有即時最新的重複資料沒備份到,而執行刪除重複資料時,卻被刪除到。

Categories: 工作點滴, 技術分享 | 標籤: | 發表留言

[Web] frame 的 name 生命空間


我個人很喜歡使用 frame (框架) ,這樣可以減少我重複的頁頭、頁尾,比如說選單、工具列之類的功能性網頁,我不需要為每個網頁插入選單,這也可以減少選單的重複傳輸、載入。

在 HTML4 的年代,框架為王,到了 HTML5 建議不要使用 frame ,最多用 iframe ,所以現代的網頁幾乎都是一頁滾輪到底的網頁,包含選單,框架變的沒人用,也很麻煩。

麻煩 1:安全性變更。

框架限制只能存取同網站的內容,整個 frame 屬性都無法存取,這部分可以避免跨網站取得資料,比如說早期騙帳號密碼的,用框架包起來,絕對是看起來跟原網站一模一樣,當然,用 proxy 概念的代理機器人,也能讓網頁看起來一模一樣。

跨框架存取位置

麻煩 2:同時開啟多個頁籤時,命名空間會共用。

在 IE11 開相容 IE10 的模式下,會以 IE10 的架構去跑,但使用 HTML5 就會共用。如下圖:

框架名稱順序

在舊板的網頁架構下,同時開多個頁籤,工具列網頁使用:

<base target="main">

預設會走藍色路線,也就是說不用管多個頁籤,自己會在自己框架命名空間下正確執行。

但在 HTML5 會當成共用的命名空間,所以就會走紅色路線,通通到第一個 資料頁 去顯示內容。

要改善這個問題,就是依框架樹狀結構搜尋,先往上層走到樹跟或是指定的框架後,列舉下方所有的框架名稱,再使用該框架變數變更。

若是其中一個框架是麻煩1 的狀況,那個框架名稱就會無法列舉,就只能回去用名稱。

比如說頁籤2 某個功能不會用,從 data.name.com 導向 help.name.com 查線上說明後,因為 資料頁 這個框架的網站不同,已不可列舉,無法使用 frame 的權限存取,所以只能回去用 window.open(路徑, “資料頁"); 去更新內容,則新的內容會在頁籤1 呈現,而不是在頁籤2 呈現。

消極的解決方案不要同時多開有框架的網頁。

積極的解決方案是框架名稱依規則產生唯一名稱,在工具列呼叫時,依照該規則唯一名稱顯示更新的內容。

我喜歡框架,可是 HTML5 不喜歡它。

Categories: 工作點滴, 技術分享 | 標籤: | 發表留言

[IPv6] 非預期的遭遇戰


話說離開學校後,就沒碰過 IPv6 的環境,大概有 17 年沒碰過了。

今天女兒在校外租的地方碰上網路異常,最後的結果很瞎,所以我先說背景。

女兒有手機、平板、筆電要上網,所以我幫他準備了 TotoLink AC3 無線基地台,1 WAN / 2 LAN / 300 MHz:

https://www.totolink.tw/products_view/N200REplus

女兒都是透過這台無線基地台上網,這台無線基地台則上接牆孔。

女兒反映,筆電部份網站不能連線,比如說成大首頁,但多數網站可以連線,比如說 Google 首頁、Youtube ,但 iPad 則都可以連線,因為要上傳作業,要連到系上,問我怎麼辦。

我確認女兒是都用 AC3 無線上網後,先行排除 AC3 異常,請女兒跑 ipconfig /all 給我看,DNS 如下:

無法連到成大的 DNS

我離開成大 17 年,但我還是記的 163.28.112.1 是成大在用的 DNS ,我一開始以為她在學校,但是不是,檢查網卡 DNS 設定,又是自動設定,所以顯然這 DNS 是上游散布下來的。

我讓她手動設定 DNS 為 8.8.8.8 測試,可以解析 http://www.ncku.edu.tw ,但是仍然連不上。

把 DNS 改回自動後,又回到 163.28.112.1 ,我一度以為是快取問題,所以請女兒把 iPhone 開無線分享給 NB 測試,女兒使用 iPhone 無線上網則一切正常,我順便跑 tracert http://www.ncku.edu.tw ,意外發現 iPhone 無線基地台的 IP 是 172.20.10.1 。

切回 AC3 後,網路設定還是回到上圖,我一度以為會不會是同學使用 VPN 連到成大,網路設定錯誤導致被覆蓋或混淆,或是房東的網路設定錯誤,導致牆孔異常。

既然女兒可以連線到 Youtube ,我請女兒測試 tracert http://www.youtube.com ,果然,可以正確連上。

都是 ipv6

一看,是從 HiNet 出去,果然是用校外網路,但是越看越不對,怎麼全部都是 ipv6 的節點?

請女兒把網卡 IPv6 關閉後,就變成完全不能上網了,但是還是能連線到 AC3 。忽然想到,該不會女兒 WAN 端接錯了吧?請女兒把 AC3 系統狀態貼給我看,果然,WAN 是斷的,女兒把網路線插到 LAN1 去了。

問題找到就一下解決了,改插到 WAN 就恢復正常。

當然,網卡有快取,iPad 是關閉網路再重開才恢復正常。

至於先前網路會通,我是這樣判斷:

假定房東裝的是中華電信光纖到府,預設有開啟 Router (WiFi) ,所以直接插網孔就能上網,例如 AC3 取得 WAN 的 IP 是 192.168.1.116 。

假定中華電信數據機的 IPv6 是開著。

所以當女兒接到 LAN1 時,筆電 > WiFi > LAN1 (Switch) > 數據機 IPv6 上網。

接回 WAN 時,筆電 > WiFi > WAN (Router) > 數據機 IPv4 上網。

也就是說我判斷數據機那邊會直接分配 IPv6 的 IP 上網。

至於 163.28.112.1 這個 DNS ,我記得是在高速網域,不在成大網域內,當初是 IPv6 的備用 DNS 的樣子,還好有點印象,還會聯想到。

這次遭遇戰,完全沒有準備,被打得莫名其妙。

Categories: 自用整理, 技術分享 | 標籤: | 發表留言

[Web] JavaScript 事件掛載的順序


因為我的網頁還有些 Windows XP Embedded (XPE) 要支援,所以我寫網頁時,還要測試 Internet Explorer (IE) 舊版本的相容。

前陣子我在大量將 VBScript 網頁改寫為 JavaScript 網頁時,我打算調整部分網頁架構,讓共用的部分在一開始就事件掛載共用函數,在執行到需要的功能時,再追加事件掛載差異的函數。

在 IE 相容測試時,IE9 以後都能正常依順序執行,IE8 以前卻是反序執行,主要是因為 IE9 以後支援 HTML5 ,使用 H5 的事件呼叫 addEventListener ,但 IE8 以前不支援,必須改呼叫 attachEvent ,掛載單一事件還沒感覺,多個事件就會出問題了。

下面這段程式碼在多數的網站都可以搜尋到:

// 設定事件掛載
function SetEventHandler(obj, eventName, pointFunction) {
   try {  // Chrome、FireFox、Opera、Safari、IE9.0及其以上版本
      obj.addEventListener(eventName, pointFunction, false);
   } catch (e) {
      try {  // IE8.0及其以下版本
         obj.attachEvent('on' + eventName, pointFunction);
      } catch (e) {  // 早期瀏覽器
         obj['on' + eventName] = pointFunction;
      }
   }
}

測試程式碼用一個按鈕 cmdTest 來接收:

// 設定 window_onload 事件
function window_onload() {
   SetEventHandler(cmdTest, "click", fun1);
   SetEventHandler(cmdTest, "click", fun2);
   SetEventHandler(cmdTest, "click", fun3);
}

function fun1() {
	console.log("fun1");
}

function fun2() {
	console.log("fun2");
}

function fun3() {
	console.log("fun3");
}

Edge / IE9 等支援 HTML5 的瀏覽器都能依照預期執行 (after):

Edge 依序執行
IE9 依序執行

但是 IE8 呼叫舊方法,則是反序執行 (Before):

IE8 反序執行

最後沒辦法,還是回到 VBScript 時代的做法,在最後才掛載事件一次,而在被掛載的事件去呼叫共用方法。

留個紀錄提醒自己,不然真的是會忘。

Categories: 工作點滴, 技術分享 | 標籤: | 發表留言

[Virus] 不明的惡意程式


小女兒在玩手機,忽然女兒電腦跳出要求提高權限執行,女兒問我是啥,我就幫忙看看。

部分內容沒保存,直接刪了,簡單的描述一下。

首先是小紅傘攔了一個批次檔,放在 %LocalAppData% 下,因為批次檔不執行就沒事,我先把他從小紅傘還原回來檢查。

看起來是透過 Windows 內建的 SmartScreen 提高權限允許做某些事,但是那些指令我沒研究過,之後呼叫 PowerShell 處理幾個目錄:

%LocalAppData%\Update
%LocalAppData%\Updates
%LocalAppData%\Google\Update
%LocalAppData%\Microsoft\Update
%LocalAppData%\Mozilla\Update
%LocalAppData%\Packages\Update

檢查這幾個目錄,目錄裡面都被塞入下圖這些檔案,看起來部分程式是用 python 寫的,或是要偽裝成正常程式?

自動產生目錄的惡意程式

先看工作管理員,看不到可疑程式,就先把上面的目錄全砍了,砍完後沒幾分鐘,這幾個目錄就生出來了。

近期看到很多惡意程式是透過排程啟動,檢查排程後,發現下圖由 OS 建立的排程,分別每 10 分鐘執行各目錄下的 updates.exe

惡意排程

除了一個排程 ServiceGPUTaskUpdate 是使用者登入時觸發外,其他 UpdateCore0x30? 都是每 10 分鐘觸發一次,分別對應到上述不同目錄的執行檔。

所以要刪除前,先把所有服務停用,再分別刪除上述目錄,再刪除服務即可。

Google 相關關鍵字還沒找到是甚麼病毒,最近要稍微關注一下。

Categories: 技術分享 | 標籤: | 發表留言

[T-SQL] 評估 PVIOT 加速資料組成效益


關於 PVIOT 官方說明請參考:

https://docs.microsoft.com/zh-tw/sql/t-sql/queries/from-using-pivot-and-unpivot

前篇 [T-SQL] WITH 通用資料表運算式:暫時資料表 有提到,要來介紹 PVIOT ,我在實際運用時,是測完 WITH 後,直接進入 PVIOT ,所以實際上 WITH 並沒用在系統中,只有測試過。

使用暫存資料庫、WITH 的範例語法請參考前篇,這篇就著重在 PVIOT ,範例也可以看看官方說明。

PVIOT 語法比 LEFT JOIN 簡潔

前篇是使用專案資料庫,資料筆數少,所以很難正確評估效益,這篇改用主資料庫,先用 COUNT 把資料庫筆數撈出來,有 158,673,734 ,也就是說有 1.58 億筆資料。

資料庫筆數

之後同時比較三種查詢方式的執行計畫:

將執行計劃時間整理如下表:

動作時間(秒)估計筆數
插入資料到暫存資料庫2.806202809
從暫存資料表查詢並組合資料0.0923038960
使用 WITH 查詢並組合資料3956.86894E+44
使用 PVIOT 查詢並組合資料2.4524782

我很驚訝 WITH 使用時間是 PVIOT 的 161 倍,我推論 WITH 並非原先想像先完成查詢結果集放在記憶體內的暫時資料表 (@MSSQL2017) ,應該是 T-SQL 字串的變數,因此每次 LEFT JOIN 都從 1.58 億筆內資料撈,導致 Cross 乘積 達到 6.86894E+44 那麼大。

也還好我實際系統沒用 WITH ,直接跳過去用 PVIOT ,少了踩雷,難怪如前篇般,我根本想不起 WITH 這個關鍵字。

去掉 WITH 查詢後,重跑執行計畫:

將執行計劃時間整理如下表:

動作時間(秒)估計筆數
插入資料到暫存資料庫2.956202809
從暫存資料表查詢並組合資料0.0873038960
使用 PVIOT 查詢並組合資料2.4144782

PVIOT 的確有增速效益,但並不如想像中明顯,大概為 1.26 倍。

這篇最大的心得是 WITH 是個雷… PVIOT 加速其實也有限。

Categories: 資料庫, SQL, 工作點滴, 技術分享 | 標籤: | 發表留言

[VBNET] 取得文字盒的游標位置


這個主題應該到處都搜尋得到,這邊討論一下我沒找到的部分。

我不確定我原始碼最早從哪來,也是天下文章一大抄,在 VB6 抄的,移植到 VBNET ,這邊假定我原始碼是抄 cww 的:

參考位置:http://www.hosp.ncku.edu.tw/~cww/html/q00221.html

原先的原始碼,會在超過約 32kb 以上的內容發生定位錯誤,當然就是溢位錯誤導致計算為負,google 後大部分原始碼都是這樣,所以只好自己偵錯。

首先先研讀 Windows API 說明,微軟已經把 Windows API 說明中文化了,所以不要再因為閱讀障礙不去看:

EM_GETSEL: https://docs.microsoft.com/zh-tw/windows/win32/controls/em-getsel

EM_LINEFROMCHAR: https://docs.microsoft.com/zh-tw/windows/win32/controls/em-linefromchar

EM_LINEINDEX: https://docs.microsoft.com/zh-tw/windows/win32/controls/em-lineindex

從 EM_GETSEL 說明中,可以看到,其實分成目前游標及選擇區域 (反白) 兩種模式,為了不把問題複雜化,只看目前游標。

傳回位置有提到分成 LOWORD (低位元組) 與 HIWORD (高位元組) ,任何一數超過 65536 則傳回 -1 ,我猜很多人看到超過回傳 -1 ,就沒管了,這也是網路上搜尋到的範例基本上只適合小文字檔。

說明也提到建議使用 wParam / lParam ,我測出這兩參數回傳結果都是 0 ,暫時放棄。

由於 HIWORD 是 65536 ,但 VBNET 的 Integer 的 HIWORD 只能到 32768 ,所以 32 kb 以上文件會出問題。因此這邊將 Windows API 呼叫改為 UInt32 來接收:

<Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="SendMessage")>
Public Function SendMessageUInt32(
	hWnd As Integer,
	wMsg As enuWindowMessageId,
	wParam As Integer,
	lParam As Integer

) As UInt32
End Function

所以解決了 64 kb 以下檔案問題。

經過測試,EM_GETSEL 超過 64kb 並不會回傳 -1 ,所以應該是原始文件誤植,或是微軟已經擴充功能後沒有正確更新文件。

所以游標計算方式更新如下:

Public Function GetCaretPos(ByVal EditControl As Control) As System.Drawing.Point
	Dim i, j, k As Long
	Dim lineNo, colNo As Integer
	Dim lParam, wParam As Integer
	i = SendMessageUInt32(EditControl.Handle, EditTextMessage.EM_GETSEL, wParam, lParam)
	j = Int(i / 65536)
	lineNo = SendMessageUInt32(EditControl.Handle, EditTextMessage.EM_LINEFROMCHAR, -1, 0) + 1
	k = SendMessageUInt32(EditControl.Handle, EditTextMessage.EM_LINEINDEX, -1, 0)
	colNo = ((j + 65536 - (k Mod 65536)) Mod 65536) + 1
	Return New System.Drawing.Point(lineNo, colNo)
End Function

VBNET 並不完全支援 UInt32 ,很多函數僅支援 VBNET 內建型別,因此在收 SendMessageUInt32 回傳值時,都立刻改為 Long 。

j 在算 HIWORD ,這個數值超過 65535 後,會從 0 再開始,類似里程表。

而在呼叫 EM_LINEFROMCHAR 時,依照 Windows API 說明,回傳目前位置是使用 -1 ,有用到選擇範圍時才用 lParm ,所以直接改成 -1 。

在計算欄位置時 (每行第幾個字元) ,j 僅 65536 以下,k 可超過 65536 ,所以這邊要先取餘數,但我現在還沒碰到這樣的文字檔,測試 TextBox 超過 1024 字元會自動換行,所以暫時先擺著。

以後有碰到可以測試的文字檔再來測,有問題再修改這篇。目前側到 4MB 的 log 都能正常跑。

Categories: 工作點滴, 技術分享 | 標籤: | 發表留言

[T-SQL] WITH 通用資料表運算式:暫時資料表


在微軟文件是寫暫存資料表,不過我覺得會跟 tempdb 裡面的暫存資料表混淆,所以我把暫存改為暫時。

WITH 我用到的機會不多,所以我以為我在 blog 上寫過跟 WITH 相關的主題,以便提醒自己。前天我要在 SSMS 下個 T-SQL ,要使用到 WITH ,但太久沒用了,完全想不起來關鍵字,google 暫存資料表不是舊的 tempdb ,不然就是 MSSQL 2016 以後支援的記憶體暫存資料表,根本找不到我想要的,翻了好久才翻到,所以這次要記下來,不然下次找不到。

在一個複雜或是資料龐大的查詢中,如果後續還要繼續對這個查詢做處理,最好把他寫到暫存資料表後再重複利用。

MSSQL 很早就有這功能,就是利用 tempdb ,使用 T-SQL 語法去處理,可以不用刪暫存資料表,SQL Server 會在斷線後自動刪除。

暫存資料表的命名就是以 # 為起頭。

詳見:https://docs.microsoft.com/zh-tw/sql/t-sql/statements/create-table-transact-sql?view=sql-server-ver15

這裡面的缺點就是建立暫存資料表時,硬碟會有大量的 IO ,所以從 SQL Server 2016 起,支援在記憶體內建立暫存資料表,以節省硬碟 IO 並加速查詢。

另一個在 SQL Server 也支援很久的就是暫時資料表。

這篇的 SQL 語法可改用 PVIOT 加速,下次來說,這篇主要是介紹 WITH。

詳見:https://docs.microsoft.com/zh-tw/sql/t-sql/queries/with-common-table-expression-transact-sql?view=sql-server-ver15

因為不用建立暫存資料表,所以上圖的 1/2/3/6 行都沒了,只剩下 4/5 行。上圖的第 4 行轉成 WITH 語法就是下圖的 1 ~ 3 行,上圖的第 5 行為了強調重複利用暫存資料表,把它展開成 4 ~ 18 行。WITH 建立的這篇稱為暫時資料表。

從這個案例來說明,原先的資料在 Data_Hour 超過 2 億筆 (row) ,如果每次 JOIN 都從原始資料撈,會浪費大量的 IO 與計算時間。所以透過暫存資料表或暫時資料表,可以加速查詢。

暫時資料表也可以多個,甚至類似巢狀,把上圖 1 ~ 3 行拆成兩個,如 1 ~ 7 行,8 行以後維持不變。

這邊是假設第二次查詢比較複雜,所以先建立 Data_Init 查詢結果後,再由 Data_CTE 經過複雜的 WHERE 運算得到新的暫時資料表,給下方的查詢使用。

我要找 WITH 是想到有個庫齡計算的 T-SQL 語法可以透過 WITH 加速,但太久沒用,一直想不起來關鍵字,自己記錄一篇提醒自己。

Categories: 工作點滴, 技術分享 | 標籤: | 1 則迴響

[Office] 365 商業版續約可能會發生使用者無法存取 Office


我們公司是從 Office 365 開始訂閱,去年已經續約 Microsoft 365 了,今年又到續約的時間,前一個月已經完成跟經銷商的下訂,確保續約正常。

原先的訂閱週期是 06/10 ~ 06/09 ,今年續約改續約一年半,以便跟另一批 Office 365 切齊,所以訂閱 06/10 ~ 12/31 。

06/09 這天,有同事數個反應,開啟 Office 365 時,顯示沒有使用權限。

一位 IT 負責跟經銷商聯繫,查了一天沒找到問題,主要就是重新授權或是把使用者刪除重新加入,但仍然不能使用。

想說看看 06/10 後會不會恢復正常,但到了 06/10 後還是不能用,經銷商打算開 Microsoft Ticket 找微軟工程師來處理,另一位 IT 忽然想起他哥公司的案例,檢查了個人軟體細項授權,果然被不明原因拔除。

找到問題就單純了,同事逐位使用者檢視細項授權,重新把相關權限勾起來,最慘的是所有功能全部沒勾。

看起來有可能是微軟續約系統的問題,續約時,部分功能可能會移除,年底續約另一批 Office 365 時,要特別注意。

Categories: 工作點滴, 技術分享 | 標籤: | 發表留言

[T-SQL] 從資料記錄裡面抽出 IP


在自訂的事件紀錄裡面,由程式碼觸發的自動紀錄,原先只是當作備查用,就如同 Windows 內建的事件檢視器,資料庫欄位有 事件類別、事件代碼、事件時間、事件內容等,並沒有把 IP 當作獨立欄位拉出來,IP 會出現在事件內容的任何地方。

最近覺得系統效能不太正常,想確認是否有異常攻擊,打算依照 IP 來做排序計算,就變成一個困擾。

好在,不用管 IPv6 或是 domain name ,原先全部都有轉換成 IP 。

檢視資料紀錄後,發現 IP 大概有幾種紀錄格式存在事件內容中,有可能出現在一開始、中間或最末行:

IP=xx.xx.xx.xx
IP:xx.xx.xx.xx
IP: xx.xx.xx.xx
yy=xx.xx.xx.xx
yy:xx.xx.xx.xx

T-SQL 語法中並沒有正規運算式可用,所以組出來很麻煩,我組出來大概是這樣:

'%[:=]%[0-9]%.[0-9]%.[0-9]%.[0-9]%'
項目說明
%[:=]%先找出 yy: 或 yy= ,並包含可能有空白的項目
[0-9]%. IP 由數字開頭,1~3位數,後接小數點
[0-9]% 第四碼 IP 後方不知道還有多長
條件項目說明

測試的 T-SQL 語法為:

SELECT *, LEFT(cl, PATINDEX('%[^.0-9]%', cl) - 1) AS cIP	
FROM (
	SELECT *, (TRIM(SUBSTRING(cs, PATINDEX('%[:=]%[0-9]%.[0-9]%.[0-9]%.[0-9]%', cs) + 1, 17)) + ' ') AS cl
	FROM (
		SELECT ' IP: 172.16.1.1 User' AS cs
	) AS ts
) AS ts

因為條件式只能抓到滿足的 事件內容 ,我的重點是要抽出 IP ,所以用 SubString 抓出中間字串,利用 PatIndex 抓到符合的開始位置,因為不確定 IP 的具體長度,先抓 17 個長度下來。

接下來要把 IP 尾端無效內容去除,由於 IP 由數字 0 ~ 9 跟小數點組成,所以比較單純,直接把其他字元抓出來砍。由於 IP 可能會出現在最後,所以在前一段先加一個空白字元,確保這段可以找到非 IP 的字元進行運算。

會這麼繞,是真的不知道 T-SQL 可以怎樣抽 IP 出來,只能先抓開頭,再減尾巴,最後把 IP 剪出來,如果有更好的方法,也請不吝分享。

Categories: 工作點滴, 技術分享 | 標籤: | 發表留言

[Web] JavaScript 迴圈隱式變數是全域變數


很少有機會在網頁裡面寫遞迴。最近剛好有個邏輯要用遞迴,結果寫下去就變無窮迴圈了…

所以我做了個簡單的測試範例後,用這個範例萬事問臉書。如下圖:

EnumData 為一個列舉資料的遞迴函數測試範例

當時我並沒有注意到右邊箭號的分區。

這張圖中,變數 ibd 是一個在迴圈內的隱式宣告,一般迴圈的範例都是這樣,所以我也照用了,而在遞迴呼叫中,被呼叫的 ibd 會被重置為 0 ,以至於上層的迴圈永遠無法跑到 2 ,永遠就在 0, 1 打轉。

黃忠成老師給個建議,改用:

for (let ibd=0; ibd<dbArray.length; ibd++){

果然可以。但是我的網頁需要相容 IE 舊版,經查 let 為 ES6 (ES2015) 的規範,所以在 IE 舊版並不支援。

就在苦無對策的時候,忽然發現,右側視窗中,ibd 在全域變數內?隱式宣告預設是全域變數不是區域變數?我一直以為隱式宣告是類似 using 之類的區塊變數,只在迴圈中有效。

既然知道是全域變數,就改成:

var ibd;
for (ibd=0; ibd<dbArray.length; ibd++){

則 ibd 變成函數層級的變數,其實變成函數層級變數就可以了,到不用勉強一定要區域變數,這樣遞迴的變數就不會互相干擾,搞定收工。

當然我也測過 Chrome ,不過截圖就用以 Chrome 為底的 Edge ,因為開發工具畫面是中文,比較親善:

迴圈變數的隱式宣告在 Chrome 也是全域變數

開發者要養成寫測試專案或測試例,這樣有助於縮小範圍鎖定問題,也容易跟其他人溝通。

謝謝黃忠成老師。

Categories: 工作點滴, 技術分享 | 標籤: | 發表留言

[Web] 前端 JavaScript 開發與除錯


前幾天,我針對一個 VBScript for IE 升級到 JavaScript 的網頁加入新功能除錯,由於網頁很亂,所以我考慮用 Visual Studio Code 的 console.log 來除錯,但不知道是不是因為我都用可攜版 (免安裝版) ,我的 JavaScript Runner 跑起來不正常,無法用來除錯,所以我就考慮用網頁來除錯器。

首先先搜尋了一些 OnLine 的 JavaScript ,包含 w3school ,但都不是十分滿意,所以決定自己來寫一個簡單除錯器:

JavaScript 執行器:http://www.tlcheng.tk/Tools/Runner/Runner.htm

IE11 預設執行畫面

畫面預設分幾個區塊,用一個 HelloScript 程式碼作為預設功能展示,點選 [執行] 按鈕,會跑 eval(程式碼 + 執行指令) 送到 輸出,執行指令有點像 IDE 的即時運算視窗。

所以當點選 [執行] 按鈕時,會跑藍色線,依據執行指令 HelloScript 呼叫原始碼 HelloScript ,這也表示原始碼可以有一些無關的程式碼在那,這樣有助於將 .js 檔案內容直接複製進來測試。

在原始碼 HelloScript 使用了常見三個輸出,訊息盒 (alert)、綠線是前端網頁 (使用 divOutput)、紅線是輸出 (函數回傳),輸出結果如下。

訊息盒輸出
網頁及回傳輸出

當 JavaScript 發生錯誤時,會把錯誤碼、錯誤訊息、堆疊訊息送到 [輸出],例如故意在 [執行命令] 把函數名寫錯。

常用的 console.log 可正常輸出到瀏覽器開發工具的主控台。

IE11 console.log 測試
IE11 開發工具輸出到主控台
新的 Edge console.log 測試
新的 Edge 開發工具輸出到主控台
Chrome console.log 測試
Chrome 開發工具輸出到主控台

把 StrTools.js 內容全部貼到 [程式碼],測試瀏覽器的開發工具是否能正常除錯。

貼入 js 檔案內容進行測試
IE11 開發工具可針對貼入程式碼除錯
新 Edge 開發工具可針對貼入程式碼除錯
Chrome 開發工具可針對貼入程式碼除錯

完成了除錯器開發後,我當然找到我的問題,但這是一個很悲傷的故事。

new Date(1899, 12, 30); // 回傳 1900/01/30

一般直覺以為,上面的物件是 1899/12/30 ,但是 JavaScript 是 1900/01/30 ,因為 Month 引數是 0 ~ 11 ,不是 1 ~ 12 啊~~~ 我回翻我所有的原始碼發現,我在 StrTools.js 這個公用函數中,2018 以前的版本都有在 Month 處 加減 1,不知道何時忘了,這個事件必須記錄下來,以警惕自身。

微軟 JavaScript 的線上手冊

Categories: 工作點滴, 技術分享 | 標籤: | 發表留言

[Edge] 關閉 89 版新增快速啟動


這周 Edge 配合 Chrome 89 版一起升級,新的 89 版號稱

  1. 減少 Edge 啟動時間
  2. 減少 Edge CPU 及 RAM 的浪費

我家裡電腦基本上是不關機,利用 Win10 專業版的 IIS 放以前寫的網站,公司電腦則是每天下班時會關機。

所以當我 Edge 全關的時候,在家裡電腦會是這個樣子:

關閉 Edge 後一堆卡在電腦裡

關閉 Edge 後一堆卡在電腦裡

我個人很不習慣這樣。

現在很多網頁用 AJAX 或 WebSocket API 背景通訊,如果程式沒寫好,就會發生關掉瀏覽器時,背景還卡在通訊關不掉,我常常在 Facebook 網頁碰到。

所以我一直習慣每天睡前關閉瀏覽器後,會看工作管理員是否確認全部被關閉,這個習慣也延伸到 Outlook ,若是重啟 Outlook ,我一定會檢查工作管理員的 Outlook 是否完全被關閉,舊版的 hotmail 的外掛就常常會造成 Outlook 卡在記憶體裡面,如果 Outlook 沒有完全關閉,重啟是沒用的。

找了一下,預設設定變成下圖:

Edge v89 預設自動執行

Edge v89 預設自動執行

把啟動加速關閉,就可以關掉 Edge 時,完全關閉:

關閉啟動加速

關閉啟動加速

 

為了比較效果,我公司電腦特意沒動,反正每天關機都能確保記憶體正確被釋放,不用人工檢查。不過經過一周過去,我對於沒關的沒啥感覺,可能是現在電腦速度都太快,第一次啟動 Edge 所減少的時間可以忽略,所以不是人類能感受的。

所以我個人是偏好還是關掉好,為了快速啟動,耗個 2 ~ 300 MB 的記憶體不知道要幹嘛。

 

Categories: 技術分享 | 標籤: | 1 則迴響

[Edge] Windows Update 後 IE 捷徑自動更新為 Edge


公司在 2012 年導入鼎新的 ERP ,當時的電子簽核 Easyflow 是使用 ActiveX 寫的,還綁在 IE (Internet Explorer) 上,公司打算完成上櫃後再更新 ERP ,避免會計流程變更影響上櫃重新審查。

IE 被各大公司拋棄是不爭的事實,也沒打算替他平反,平常同事都使用其他瀏覽器上網,但是上電子簽核,還是得用 IE ,因此 IT 幫同事設定電腦時,會在 Win10 下方的開始工具列釘選 IE ,並且把 Easyflow 的捷徑,從 IE 網址列拖到桌面,以便方便使用 IE 開啟電子簽核。

不知道是哪個 Windows Update 搞的鬼,二月有零星個案,三月有十幾個個案,都是開始工具列、桌面捷徑全部被改為 Edge 。

開啟桌面捷徑的內容,其連結已經被改變,所以不管怎樣操作,都會先開 IE 再自動轉 Edge ,很難搞。

比較簡單的做法:

用檔案總管開啟以下位置檔案:C:\Program Files\Internet Explorer\iexplore.exe

等到 IE 開啟後,重新釘選到開始工具列,並且連上公司電子簽核後,就可以重新使用 IE 了。

我另外調整了瀏覽器設定再繼續觀察。

Edge 與 IE 預設行為

Edge 與 IE 預設行為

Categories: 工作點滴, 技術分享 | 標籤: | 1 則迴響

[Office] Word 365/2016/2019 變更樣式集 (庫)


這篇跟前面這篇類似:

一點通 – 如何在 Word 2007 中變更樣式庫

你可以把樣式庫當成標準文件的範本,比如說做 ISO 文件、企業內部文件、計畫報告、學位論文通常會規範文件的版面、行距、字的大小,所以 Word 很早就引用樣式庫的架構來將文件標準化,我最早用的時候大概是 Word 6.0a ,跟網站的 css 也挺像的。

首先先準備好一個已經標準化的文件,比如說版面、內文、標題1、標題2、圖表格式或目錄樣式都已完成設定的檔案。

如果希望新的空白文件有預設的封面、目錄、章節,保留適當的說明在這個文件上,其他刪除,如果希望開起來純粹是空白文件,請將內容刪除。

新範本

範本用在建立一個新文件上,新文件通常版面相關設定會有規範,比如說紙張留白的設定、頁碼設定,如果有預留章節也屬於範本的一部分。

將前面完成的標準化文件另存範本。

另存新範本

另存新範本

上面在存範本時,可以建立子目錄,比如說依照部門建立目錄,或是不同用途建立目錄。

後續第一次要以此範本新增文件時,先選個人,若前一步驟有建目錄,再選目錄,就可以依照自定的範本建立新文件。

第一次新增自訂範本

第一次新增自訂範本

 

選擇自訂目錄的範本

選擇自訂目錄的範本

第一次新增過自訂範本後,Word 會自動快取建立捷徑,以後預設開新文件可以直接選。

快取的自訂範本

快取的自訂範本

以自訂範本建立的新文件,會自動帶入相關的樣式及預留的內容。

用自訂範本建立的新文件

用自訂範本建立的新文件

樣式集

樣式集在舊版的 Word 翻成樣式庫,我印象中舊版的 Word 套用樣式庫的時候,版面設定會生效,不過年代久遠,已經不記得了。目前的 Word 版本,套用不同樣式集時,版面設定不會變化,只有樣式會變化,因此若是要依據規定製作標準文件,最好從範本就正確選擇,樣式集比較用在版面相同的文件上,當然版面不相同也可以用樣式集,就看個人實際的需求。

前面準備好的標準文件在此選擇另存為新樣式集,如果需要預覽內容,樣式集需要保留一些文字。

另存為新樣式集

另存為新樣式集

 

存成自訂的檔名

存成自訂的檔名

需要用時,就從文件選擇該樣式集即可套用。

套用樣式

套用樣式

範本、樣式集主要是給標準文件或長文件使用,樣式集還有一種用途是草稿模式,例如論文要印出給教授審閱,可能需要有雙行行距,教授才能在空白處寫上意見,則可分為草稿版樣式集、正式版樣式集,或是有分年長者版,要特別大字,也可以分成年長者版、正式版,印出前選個樣式套用即可。

 

Categories: Office, 工作點滴, 技術分享 | 標籤: | 發表留言

[Win10] Edge 在更新到 Win10 20H2 後使用 alt-tab 會同時呈現


我個人用 Windows 很多年了,老用戶就習慣使用熱鍵,我在切換視窗時,常常用 alt-tab。

例如下圖:

Alt-Tab 預覽視窗

Alt-Tab 預覽視窗

在 Win10 2004 (包含舊版的 OS) 之前,Edge 多頁籤會只有一個視窗,如果有特別要持續使用的網頁,可以拖出來變成獨立視窗,就可以在 Alt-Tab 單獨選擇。

但到了 Win10 20H2 以後,Edge 預設會如上,即使在同一視窗不同頁籤,也會跑出一堆視窗,這樣在工作時就不方便切換,例如在 Office 與 Edge 網頁查詢結果中切換。

好在微軟沒把功能寫死,可以關閉,不然真的想揍人了…

所有設定 > 系統 > 多工

切換 Edge 在 Alt-Tab 下的顯示模式

切換 Edge 在 Alt-Tab 下的顯示模式

將 Alt-Tab 設定 為 僅限開啟視窗 ,就可以恢復原來的模式了。

媽的,微軟真的常會沒事找事…

 

Categories: 工作點滴 | 標籤: | 1 則迴響

在WordPress.com寫網誌.

%d 位部落客按了讚: