技術分享

[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: 技術分享 | 標籤: | 發表留言

[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: 工作點滴, 技術分享 | 標籤: | 發表留言

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


這篇跟前面這篇類似:

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

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

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

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

新範本

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

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

另存新範本

另存新範本

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

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

第一次新增自訂範本

第一次新增自訂範本

 

選擇自訂目錄的範本

選擇自訂目錄的範本

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

快取的自訂範本

快取的自訂範本

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

用自訂範本建立的新文件

用自訂範本建立的新文件

樣式集

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

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

另存為新樣式集

另存為新樣式集

 

存成自訂的檔名

存成自訂的檔名

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

套用樣式

套用樣式

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

 

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

[cmd] 從 Nas 上更新 system32 目錄檔案


先前開發螢幕保護程式完成後,在 Nas 分享檔案後,由 IT 直接到使用者電腦從 Nas 上複製下來安裝,當時想的是為螢幕保護程式花時間弄個安裝程式有點划不來,而且我越來越偏好拷貝就能用,不太希望透過安裝方式散布。

先前開發的:[VB] 螢幕保護程式支援多螢幕

這次有新公告發布後,發現有個小 bug ,導致撈不到新公告,更新完螢幕保護程式後,剩下的就是如何散佈到使用者電腦去,由於先前已經設定好了,只要能將檔案覆蓋到 C:\Windows\system32 下,一切都好說,但是 Win8 以後強制開啟 UAC ,系統目錄是保護狀態,只好想辦法繞。

最後建了一個捷徑,內容為:

C:\Windows\System32\cmd.exe /K copy \\[Nas上的路徑]\*ScreenSaver.scr C:\Windows\system32

並在捷徑上設定系統管理員身分執行,扔到 Nas 上,請同仁去執行。

在 Nas 上的捷徑
在 Nas 上的捷徑

我個人偏好讓使用者知道發生了啥事,所以我在 cmd 下用 /K 來保留訊息,我不太喜歡靜默安裝。

完成複製
完成複製

使用者看到完成複製後,再手動關閉 命令提示字元 視窗即可。

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

[VB] 螢幕保護程式支援多螢幕


上篇:

[VB] 開發螢幕保護程式

我在開發時,因為使用 15″ LED 的 NB ,也就是單螢幕,所以最近開始在公司電腦安裝後,就有人反應螢幕保護程式只有一個螢幕有,其他螢幕只有底色。

對不起喔,我只是個單螢幕的使用者…

需求來了就得更新,由於預覽模式只有單螢幕,所以要把實際執行跟預覽再切開。

預覽螢幕保護程式
預覽螢幕保護程式

前篇說過,我的開發環境是 .Net framework 4.0 ,所以直接用 .Net 的物件。

 Dim ibs, ubs As Integer
 Dim arrScreens() As Screen = Screen.AllScreens
 ubs = UBound(arrScreens)
 [略]
 Select Case .CommandLineFlag
 [略]
 Case CommandLineOptions.Start
     Dim arrMains(ubs) As frmMain
     For ibs = 0 To ubs
         arrMains(ibs) = New frmMain
         With arrMains(ibs)
             .Show()
             .Left = arrScreens(ibs).Bounds.Left
             .Top = arrScreens(ibs).Bounds.Top
             .WindowState = FormWindowState.Maximized
         End With
     Next
     Application.Run(arrMains(0))
 [略]

用 Screen.AllScreens 取得所有螢幕,在每一個螢幕上丟上螢幕保護的畫面,由於每個畫面座標不同,所以至少左上角要在新螢幕裡,然後在最大化。

剛好我先前輪播圖片的時候,是呼叫統一的 PlayNext ,所以多螢幕化的時候,每個螢幕呼叫 PlayNext 都會將圖片播放下一張,可以讓每個螢幕都播放不同照片,也完成了多螢幕的支援。

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

[RAID] Intel RSTe 自動重建


先前的 Server 多半用的是內建的 RAID ,雖然效能比較差,但是勝在便宜、方便。

公司有一台財務部的合併報表伺服器,大概每季才用一次,只有兩三個人用,所以當初規劃的時候,是用很經濟的 1U Server 搭配 Windows Server 2012r2 Foundation ,再買 SQL Server 2017 Standard,說實在的,要不是軟體商堅持,我看系統使用需求量,其實我想用 W7E + SQL Server Express 來跑,硬碟用的小,CPU 用的小,每季用量小,幹嘛買 Server 。

更舊的 Server 使用主機板內建的 RAID 通常是 LSI MegaRaid ,但 LSI MegaRaid 被併購了,所以這台是使用內建 Intel Raid 。

當初這台買來,因為已經初始化過,所以我這邊只有建立帳號後,就交給財務部跟軟體商用,平常資訊部維運不碰這台,避免責任無法釐清。

昨天資訊部同仁發現這台硬碟亮紅燈,就連線進去看,才注意到這台沒有相關工具軟體可以看 RAID 狀況。重開機過幾次,在 BIOS 畫面顯示 RAID 損壞,就到 Server 官方網站找工具軟體。

工具軟體是 Intel RSTe (Rapid Storage Technology enterprise) ,Server 網站提供的是 5.x 版。裝起來看,顯示硬碟離線。

所以我決定打客服保固 (我習慣 Server 都會加到五年保固) ,打客服前當然就是得先查序號阿,跟同事兩個人趴在機房地上看半天,還把 Server 從機櫃抽出來,都找不到序號貼紙,另一個當初接機的同事進來後,終於在面板處找到一個小凸起,抽出來一看,是序號卡…

把 Server 推回機櫃開機,準備看著畫面跟客服回報,一開機 BIOS 畫面變了,RAID 從損壞改變為重建 (ReBuild)。

Server 開完機後,打開 Intel RSTe ,顯示 自動重建 (0%)… ,然後開始跑 % ,有點慢,估計要 3 小時,看樣子客服電話不用打了。

隔天到公司檢查 Server 狀態,已經重建完畢,正常上線,有可能是接觸不良導致硬碟離線。

順便到 Intel 網站更新 RSTe ,沒想到新版改名為 Intel VROC (Virtual RAID on CPU) ,查了一下,從 6.0 開始改名,新版主要是針對 SSD / M2 這類做 RAID 最佳化,並需要硬體金鑰,不確定是不是支援,反正裝看看,不支援再裝舊版。

滿順利的,可正常跑,也能顯示 RAID 狀態。

Intel VROC 6.2
Intel VROC 6.2

並且會自動更新驅動程式:

Intel C600+/C220+ SATA RAID Conteoller
Intel C600+/C220+ SATA RAID Conteoller

需要的話可以到 Intel 網站搜尋 VROC :

再依據時間由新到舊,尋找相容最新版的驅動程式。

注意,不管是 Intel RST / RSTe / VROC ,都需要點選發行說明,裡面有適用的晶片,Intel 自動更新程式不會管快速儲存技術的 Driver 更新,只能自己手動更新。

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

[Hyper-V] 使用內建的網卡來做 Loopback


習慣是一種很可怕的東西。

我從 Windows 2003 的 Virtual Server 開始用 Microsoft Loopback 網卡後,到了 Win8/10 的 Hyper-V 還是習慣用 Microsoft Loopback 網卡。

當然,到了 Win10 是因為 Visual Studio Emulator For Android 只支援實體網卡,沒辦法用 Hyper-V 來模擬,所以我也忘了初衷,習慣在 Hyper-V 就是用 Microsoft Loopback 網卡。如前一篇:

[Hyper-V] 重設 Win10 2004 的 Loopback 網卡

Visual Studio 2019 新版已經移除 Emulator For Android ,直接用 Google 提供的 Android 模擬器,所以 Hyper-V 如果我只跑 WinXP/7 之類的,實際上並不需要使用 Microsoft Loopback 網卡。

昨天忽然想起這件事,決定把 Hyper-V 改設為標準用法。

1. 首先在 [虛擬交換器管理員] 建立一張內部網卡。

建立內部網卡
建立內部網卡

2. 我把他取名為 [Hyper-V Loopback] 。

Hyper-V Loopback
Hyper-V Loopback

3. 將虛擬機的網卡指向這張 [Hyper-V Loopback] 網卡。

將虛擬網卡指定給虛擬機
將虛擬網卡指定給虛擬機

4. 把實體網卡共用給這張 [Hyper-V Loopback] 網卡。

共用 WiFi
共用 WiFi

5. 啟動虛擬機測試網路是否能正常。

網路測通
網路測通

這邊再重申,Hyper-V 可以直接走實體網卡取得實體 IP ,但這種做法必須網路要通,由實體網路的 DHCP Server 分配 IP,走 Loopback 是在 Host 形成內部網路,由 Host 分配 IP ,所以這個方法主要是給 NB 用,這樣不管實體網路是連接公司、家裡、手機的 WiFi,都不影響網路,虛擬機可以設定固定 IP 給遠端桌面也很容易從 NB 連接。

這次換成 Hyper-V Loopback 也是要測試,看看到時 Win10 半年更新會不會又把我的 Hyper-V 網路環境搞掛。

先前 Microsoft Loopback 網卡速率是 1.2 Gbps ,Hyper-V Loopback 網卡是 10 Gbps ,我本來以為在 WinXP 會顯示 10 Gbps ,沒想到顯示的是 1.4 Gbps ,這個速率有點奇怪,有機會看看其他 OS 是不是也是這個速率。

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

[Hyper-V] 重設 Win10 2004 的 Loopback 網卡


我習慣用 Microsoft Loopback 網卡給 Hyper-V 裡面的 Guest 用。例如先前的文章:

[Hyper-V] 在 Visual Studio Emulator For Android 我的虛擬網路設定

但每次 Win10 的半年版本更新,總會把我 Hyper-V 網路搞掛。八月初被強上 Win10 2004 後,直到九月下旬,因為有隻舊版的 VB6 程式要維護,要使用 Hyper-V 開 VM ,才發現我的 Hyper-V 的網路架構又掛了。

重設的步驟大概如下。

1. 打開 [Hyper-V 管理員]

2. 將所有用到 Microsoft Loopback 網卡的虛擬機,逐一設定網卡為 [未連線] 或其他虛擬網卡,讓 Microsoft Loopback 虛擬網卡不被參照。

3. 刪除舊的 Microsoft Loopback 虛擬網卡。

4. 在 [Hyper-V 管理員] 停用服務。

5. 從裝置管理員刪除舊的 Loopback 網卡,重新加入 Lookback 網卡。

a. 由於 Hyper-V 會把網卡改名,所以可能需要用 [網路連線] 確認正確名稱。

網路連線設定
網路連線設定

b. [網路連線] 可能會因為被 Win10 鎖定而無法刪除網卡,可透過 [裝置管理員] 刪除。

查到的是 3 號網卡
查到的是 3 號網卡

c. 再從 [裝置管理員] [新增傳統硬體]

新增傳統硬體
新增傳統硬體

d. 選取 Microsoft Loopback 網卡

選取 Loopback 網卡
選取 Loopback 網卡

6. 在 [Hyper-V 管理員] 啟動服務。

7. 將 Microsoft Loopback 設為虛擬外部網卡。

8. 將虛擬機的網卡重新設為 Loopback 虛擬網卡。

9. 將無線網路共用給 Loopback 虛擬網卡。

共用網路給虛擬網卡
共用網路給虛擬網卡

再從 [Hyper-V 管理員] 裡面啟用虛擬機,就可以透過 虛擬 Loopback 網卡 > NB WiFi 網卡 連接到網際網路,在沒外部網路的時候,虛擬機跟 NB 的區域網路也能互通。

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

[VB] 開發螢幕保護程式


月初,老闆在主管會議說,他有一天抽問了三位同事,公司的企業文化那12個字,沒人答得出來。所以老闆要資訊部想辦法讓同仁每天都看得到,每天都被提醒,而且新訊息能迅速被傳達。

一般企業都是從入口網來處理,但老闆不要放入口網,老闆希望在電腦桌面就能看到。

回到辦公室測試 Win10 ,Win10 有動態桌面、登入畫面、螢幕保護程式可以試,登入畫面不支援網路芳鄰路徑,動態桌面、螢幕保護程式都支援,再請同事在 Win7/8x 測試,均可支援。

由於很多人桌面放了一堆捷徑,若使用動態桌面,文字可能會被圖示壓住,上市櫃公司在資訊安全基本要求要設定螢幕保護程式,所以就回報使用螢幕保護程式解決此需求。

PC 比較簡單,基本上隨時都能連上公司檔案伺服器,但是公司有一半以上是 NB ,人都在外面跑,所以變得要寫一個螢幕保護程式來處理。由於不用考慮 Win2k/Win95 ,所以我選擇用 .Net framework 4.0 來開發,這樣 Win 10/8x 可以直接拷貝。

為了方便起見,我直接設定死執行的邏輯:

  1. 每 15 秒換一張圖片
  2. 由本機 %USERPROFILE%\Pictures\[軟體名稱] 載入圖片,由最新圖片往舊圖片撥放,若無圖片,維持黑畫面。
  3. 每次啟動時,撥第二張圖片時,會自動檢查 專用網址產生的 檔案清單。
  4. 比對檔案清單,有新檔下載,移除檔案刪除。
  5. 重新撥放,並持續輪播。

所以有新公告就會第一時間先撥放,然後依序撥放舊的圖片。

參考微軟網址:

https://docs.microsoft.com/zh-tw/troubleshoot/windows/win32/screen-saver-command-line

https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms686421(v=vs.85)

序號參數說明
1(無參數)顯示設定對話盒
2/c顯示設定對話盒
3/p <hWnd>在螢幕保護程式設定對話盒的預覽視窗顯示
4/s執行螢幕保護程式
螢幕保護程式的 command line 參數

/c

一開始我在開發測試時,怎樣都無法顯示對話盒,後來透過工作管理員觀察,Win10 的命令列參數根本不是 /c ,而是 /c:nnnnn ,如下圖:

設定畫面
設定畫面

考慮與舊版相容,我在判斷時使用:

Select Case Left(args(0).ToLower, 2)

來判讀。

/p

我在 Windows 預設是 125% (120 DPI) 字型顯示畫面,因此在 VS2019 的 WinForm 預設也變成 125% ,若預設使用 125% ,當透過 Windows API 取得螢幕保護程式設定對話盒時,也要乘上 1.25 才會正確。

Dim rectPreview As RECT

' 取得預覽視窗
rectPreview = GetClientRect(hWndParent)
' 視窗放大 125%
With rectPreview
    .right = 1.25 * .right
    .bottom = 1.25 * .bottom
End With

無參數

無參數我懶得處理,所以我的無參數不會進入 顯示設定對話盒,而是執行螢幕保護程式,若有需要,以後再改,理論上應該不會有人特別直接執行螢幕保護程式。

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

[Win10] 釘選在開始工具列的圖示異常


Windows 7 以後我就常碰上這類問題,這篇是 Adobe Acrobat Reader DC,我比較常碰上的是 Skype。

圖示異常
圖示異常

大部分的問題是軟體更新,導致重新整理時,沒有正常抓到原先的執行檔,少數情況是 Win10 大版本更新,自動重新安裝軟體造成。

解決方式很簡單,讓他不要出現在開始工具列就可以了。

  1. 解除釘選設定
  2. 關閉所有該軟體,直到圖示不再出現。
軟體全部關閉
軟體全部關閉

重新開啟軟體再釘選即可。

圖示已恢復
圖示已恢復

如果介意順序,再自己拖動到要的位置即可。

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

Win10 Update 找回大版本更新可能造成檔案遺失


常常在論壇看到,Win10 自動 Windows Update 後,桌面檔案遺失了,或是使用者的檔案遺失。

先前 Win10 2004 聽說有很多問題,每周我都選延 7 天,6 月底嫌麻煩,一次選擇延 35 天。

8 月初在沒有準備的情況下,忽然被通知已經完成更新,需要重新開機。當天事多,選擇延後到隔天早上上班時間重新開機。

早上來就開始更新,因為是傳統 SATA 硬碟,非 SSD ,所以更新了 4 小時才完成更新。

大版本更新可能是為了恢復 Windows 10 預設狀態,很多軟體資訊可能會受損,必須重新或修復安裝,我碰上 Office 365、MS SQL Server Developer 需要重新安裝。

另外我也碰上桌面檔案消失了。

我自己習慣把工作檔案都放在 D 槽,桌面上是少量的暫存檔,掉了也沒關係,不過我很好奇檔案到哪了,還滿好找的:

Windows.old
Windows.old

原來會產生 C:\Windows.old 來存放資料。

所以桌面檔案就到

C:\Windows.old\使用者\[UserId]\Desktop

舊可以找到,其他可能相關被大版本更新的 Windows Update ,應該也可以在這邊找到,因為沒遺失其他內容,我就沒仔細翻了。

Categories: 工作點滴, 技術分享, 更新與回報 | 標籤: | 發表留言

[SMB] Win10 Pro 的網路芳鄰跨網域設定


大概管 Server 的習慣很好,新電腦的 Win10 網路芳鄰直接就完成設定,用 NB 測試可以連到新電腦後,就扔一邊了。

在公司要存取新電腦檔案,透過 VPN 連回家後,網路芳鄰連不到新電腦,但是 Web 可以,就想起應該是 Win10 防火牆預設問題。

先前在下面這篇有提過,我的網路設備 VPN 與預設網段不能相同:

[Bug] Sapido BR261c 錯誤 VPN 設定將干擾部分安全連線

新電腦的網段在 192.168.x.0/24 下。

我的 VPN 網段在 192.168.y.0/24 下。

先前在 Win8 有發現 Windows 內建防火牆預設會把網路芳鄰關在 Class C 內:

[Win8.1] 網路芳鄰跨網段的設定

Win10 的網路芳鄰預設也是一樣,限定在本機子網路內,如下圖:

Win10 網路芳鄰防火牆預設設定
Win10 網路芳鄰防火牆預設設定

一般家用或小企業只用一個 Class C 的,在這預設值下都可正常用,但我的 VPN 就要走另一個 Class C ,所以我改成下面這張圖後就可以通了:

讓 192.168.*.* 都可以連線
讓 192.168.*.* 都可以連線

所以我在 192.168.*.* 下都可以通,當然反正在防火牆後面,要設定成「任何 IP 位址」也可以。

網路芳鄰相關通訊協定的防火牆都要改,細節請參考前篇:

[Win8.1] 網路芳鄰跨網段的設定

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

在 WordPress.com 建立免費網站或網誌.

%d 位部落客按了讚: