【Cs】套件相關
簡單紀錄用
套件的階層關係
可參考:c# - How to view a NuGet package's dependency hierarchy - Stack Overflow
個人使用的是其中使用 NPM 的選項:nuget-tree - npm
然後因為研究階層的原因是為了部分 System. 開頭的套件版本衝突,因此有照上方提示加上 --showSystem 參數。
UPDATE LOG
115. 01/21 開新篇
存放所有 blog。
主要 for 自我回顧好抄 (咦)
可能有的:coding、翻譯、my 娛樂用、雜七雜八不知道
分類內 GAME: 奇迹暖暖 (奇暖)、世界計畫 (PrSk)
簡單紀錄用
可參考:c# - How to view a NuGet package's dependency hierarchy - Stack Overflow
個人使用的是其中使用 NPM 的選項:nuget-tree - npm
然後因為研究階層的原因是為了部分 System. 開頭的套件版本衝突,因此有照上方提示加上 --showSystem 參數。
115. 01/21 開新篇
基於好奇研究一下通用規則。
(起因是個人寫方法名稱都很沒有規律QQ)
ref: Names of Type Members - Framework Design Guidelines | Microsoft Learn
方法名稱:先v. 後 n./adj.
ref: Capitalization Conventions - Framework Design Guidelines | Microsoft Learn
方法名稱:PascalCasing
屬性、欄位:camelCasing
ref: General Naming Conventions - Framework Design Guidelines | Microsoft Learn
方法名稱:避免簡寫,例如 GetWindow() (O)、GetWin (X)
115. 01/16 開新篇
這次要改成把檔案塞去 Google Cloud Storage,一樣用服務帳戶
起因是需求要把所有檔案通通塞雲端,不要夾帶檔案。
需求:pdf-上傳、開檔案共享連結、刪除
一樣先建好服務帳戶。
服務帳戶建立方法可參見前篇,有加上如何建立的段落。
接下來是...
開 Bucket、上傳、開檔案共享連結、刪除
使用刪除的原因是檔案留存在 Cloud Storage 越久,費用越高
不如在不需要用到該檔案時,用程式觸發刪除。
那麼因為雖然存放時間不一定,但一定不會超過半個月,所以這裡就選擇 Standard 了。
詳細想自行決定可參考:Cloud Storage 教學―費用節省訣竅、使用方式完整介紹 - Cloud Ace
裡面有表格告知儲存空間級別的差別。
需要 Bucket 的原因是檔案要留在 Cloud Storage,就需要有個 Bucket 存放。
從下圖點開

按 [建立]

填寫,這裡個人幾乎都保留預設值

右側面板可以簡單預估可能產生的費用
以下是個人有用到的套件:
Google.Apis.Auth
(需要:Google.Apis、Google.Apis.Core)
Google.Cloud.Storage.V1
(需要:Google.Apis.Storage、Google.Api.Gax、Google.Api.Gax.Rest)
Google.Api.Gax v4.9.0
Google.Api.Gax.Rest v4.9.0
Google.Apis v1.73.0
Google.Apis.Auth v1.73.0
Google.Apis.Core v1.73.0
Google.Apis.Storage.v1 v1.69.0.3707
Google.Cloud.Storage.V1 v4.13.0
沒有身分給驗證是不能做事的!
回到開好的 Bucket,點選 [授予存取權]

在打開的右側面板,填上剛剛建好的服務帳戶的電子郵件

指派角色,這裡先嘗試選擇使用者

好了按 [儲存]。
程式中如何取得服務帳戶,原本想參照前篇 【Cs】Google Drive 自動上傳檔案並共享-取得權限
然而發現完全不能通用QQ 那版是走 Drive 的,不是 GCS
諮詢了 Claude 給出的解法:
string jsonPath = @"C:\path\to\your-service-account-key.json";
GoogleCredential credential = GoogleCredential.FromFile(jsonPath);
具體就修改為自己的資訊就好了。
*** 在我研究的期間,Google.Apis.Auth.OAuth2 從 v1.69.0 更新到 v1.73.0
因此憑證撈取寫法稍微改動了,在 .FromFile() 那出現了警告:
CS0618 'GoogleCredential.FromJson(string)' is obsolete:
'This method is being deprecated because of a potential security risk.
Use the methods in the CredentialFactory class instead.
A GoogleCredential object can then be created by calling the .ToGoogleCredential() method on the returned specific credential. '
處理來源 Pull request:
feat: Add credential type parameter to CredentialFactory by robertvoinescu-work · Pull Request #3064 · googleapis/google-api-dotnet-client
如果想改成最新版寫法,請見:
c# - Firebase version 3.4.0 not support GoogleCredential.FromFile("") - Stack Overflow
官方ref: 上傳和下載 | Cloud Storage | Google Cloud Documentation
因為是第一次嘗試,所以先用單一要求上傳試試看。
接著,因為是從本機做檔案上傳,所以繼續參照
官方ref: 從檔案系統上傳物件 | Cloud Storage | Google Cloud Documentation
所需權限的部分
因為上傳跟刪除是不同系統,所以分開需求
1. storage.objects.create 跟 storage.objects.delete
2. storage.objects.delete
(依照官方文件,delete 是在覆蓋檔案用的。)
Warning
GCS 跟 Google Drive 不同的是同名檔案在 GCS 內會被覆蓋
若不想覆蓋,要另外啟用功能 物件版本管理。
純上傳的部分,官方文件就有給出:
從檔案系統上傳物件 | Cloud Storage | Google Cloud Documentation
個人是用 C#,照抄稍微調一下就好。
*** 記得指定 content type 參數!以 pdf 為例,指定好可以利用連結直接預覽檔案。
上傳成功的話,會出現

再次上傳一次,因為個人沒有特別需求,所以同樣檔名上傳會蓋掉原檔案。
官方文件:List Objects | Cloud Storage | Google Cloud Documentation
很基本的使用了:
## 列出值區中的物件 | List Objects | Cloud Storage | Google Cloud Documentation
官方文件給出的 C# 一丟就能用了,因此不在此做過多描述。
官方提供了兩個可供篩選的選項:前綴、delimiter(定界符)
前綴:給定前綴字串,可以篩選列出所有前綴為它的物件們
delimiter(定界符): 可限制是否只在給定的目錄底下搜尋
這裡因為個人只需要用到前綴,所以只研究前綴撰寫。
撰寫方式跟列表差不多,只差在加上一個前綴參數就好。
原本:
加上前綴:需求是跟前篇一樣,使用連結可以打開 pdf 預覽。
先看一眼檔案:

其中「已通過驗證的網址」是我可能需要的預覽 pdf 連結,所以目標是抓到它。
程式面上,只找到最相近的官方文件是 下載物件 | Cloud Storage | Google Cloud Documentation
因此決定直接摸索從 列表 那撈出的 Google.Apis.Storage.v1 dll (?)
.Data.Object 內觀察:
.MediaLink: Media download link. =>應該是下載用的連結?.SelfLink: The link to this object. =>沒看懂發現那兩個參數給出的結果跟前面兩個網址都不一樣@@
所以也不對。
於是問了 Claude,得到以下解法:
方案 1:使用 Signed URL(推薦)
相關官方文件:
因此:

具體實作:
objectName 是檔名喔。(應該...?總之個人用檔名送有成功)
/// <summary>
/// 取得 Signed Url
/// </summary>
/// <param name="objectName"></param>
/// <returns></returns>
private string GenerateSignedUrl(string objectName)
{
// 載入憑證
GoogleCredential credential = GetGcsCredential();
// 建立 UrlSigner
UrlSigner urlSigner = UrlSigner.FromCredential(credential);
// 設定有效期限 (這裡個人設7天)
TimeSpan duration = TimeSpan.FromDays(7);
// 產生 Signed URL
return urlSigner.Sign(bucketName, objectName, duration);
}
雖說預覽有做有效期限,但個人需求並不是永久保留檔案在 GCS 上
(考量到檔案留越久費用越高問題)
因此需要做個刪除處理。
官方文件:刪除物件 | Cloud Storage | Google Cloud Documentation
Info
這裡只需求一次刪一筆,所以不探討 ## 大量刪除物件 | 刪除物件 | Cloud Storage | Google Cloud Documentation。
刪除前記得先確認好官方提示:

官方文件給出的 C# 一丟就能用了,因此不在此做過多描述。
115. 01/09 開新文
意外需要正式使用了...
原本要調一調 【雜記】自架 BugZilla 那篇擴充,但發現架構太冗+那篇是雜記,因此改成開新篇。
v5.2
建立帳號並登入後的首先:
點選上方導覽列內的 [Administration]
然後 > [Products] > [Add] a product
會看到以下畫面:

一開始有點疑惑為甚麼 Component 是必填,因此問了 Claude:
## Bugzilla 的資料結構設計
Bugzilla 的 bug 追蹤系統採用階層式架構:
- **Product**(產品)
- **Component**(元件)← 必須存在
- **Bug**(問題單)
在這個設計中,每個 bug 必須同時關聯到一個產品和一個元件。這是 Bugzilla 資料庫架構的基本要求,bug 表格中的 component_id 欄位是必填的。
## 為什麼這樣設計
### 1. 責任歸屬的明確性
元件機制強制您在組織層面就思考清楚責任劃分。每個元件都必須指定預設負責人(Default Assignee),確保每個提交的 bug 都有明確的處理人員。
### 2. 避免過於粗糙的分類
如果只有產品層級,大型專案會面臨所有 bug 都混在一起的問題。強制使用元件可以防止這種情況,促使團隊進行更細緻的問題分類。
### 3. 通知機制的精準度
元件層級的 CC 清單和負責人設定,讓相關人員只接收到他們關心的領域的通知,避免資訊過載。
## 實務上的應對方式
如果您的專案確實很小或很簡單,不需要複雜的分類,可以採用以下策略:
### 最簡方案
建立一個通用元件,例如:
- 元件名稱:「General」或「Default」
- 描述:「一般性問題」或「未分類問題」
這樣至少滿足系統要求,之後如果專案成長需要更細的分類,再新增其他元件即可。
### 實際考量
即使是小專案,通常還是能找到基本的功能區分,例如:
- Frontend / Backend
- UI / API / Database
- Documentation / Code
這樣的基本分類對後續問題追蹤和統計分析也會有幫助。
## 結論
Bugzilla 強制要求元件不是為了增加複雜度,而是為了確保問題追蹤的品質和可維護性。這是系統設計的核心理念之一。如果您的使用場景真的非常簡單,建立一個預設的通用元件就能滿足需求,不會造成太大負擔。
因為個人還沒預備好要細分,因此先給名字「Default」。
[version] 欄位放上該系統目前已釋出的最新版本 (先簡單打個 1.0.0)
[Default Assignee] 必填,所以先填了自己。(方式是打上自己的帳號,打到一部分的時候系統會自動跳出自己的下拉選項,選擇就好)
[Default CC list] 非必填,個人還是選擇填自己
其他維持預設。
填寫結束後點選 [Add]。
為了讓別人方便依照我想要的格式,決定改 Component 成兩個:
Feature、Bug
這樣就可以各自給模板了!

點選右上角的 [New] 進入下圖頁面:

選擇要回報的 Product 進入下圖頁面:


How severe the bug is, or whether it's an enhancement.
也就是 bug 的嚴重程度 or 純希望增強的功能。
(以下名詞解釋都有參考網路)

PC: 應該可以認知為 Windows 相關產品?
Macintosh: 查網路得知是 Mac 5
Other: 安卓的手機平板應該就填這裡了
選擇想要回報的 [Component] 及 [Version]
[Summary]
如果有在回報 GitHub 之類的 issue 應該大概都知道要寫啥
總之就是短小精煉 & 方便被後來人搜尋到關鍵字。
以及內部公司使用記得界定好模板寫法。
輸入期間底下會多出 [Possible Duplicates],可以檢查一下有沒有類似的回報避免重複回報:

[Description]
似乎沒有支援 Markdown 語法?
[Attachment]
要附上截圖啥的好地方。
點選 [Add an attachment] 會得到下圖:

看檔案大小限制,應該只能丟截圖。
(略為翻了一下以前的影片檔,6秒就4千多kb了)
ref: How To Delete Bugs in Bugzilla – devZing Blog
官方建議是不要刪除,但我加了一個測試 email 有沒有寄信到我這裡的 bug 要怎麼刪除?
allowbugdeletion,改成 [On],然後 [Save Changes]Trash component)
要注意的是該參數的描述:
The pages to edit products and components can delete all associated bugs when you delete a product (or component). Since that is a pretty scary idea, you have to turn on this option before any such deletions will ever happen.
(在編輯產品及子產品的頁面刪除一項產品或子產品時,可以刪除所有相關的 bug。)
刪除該 component 會出現提示:

所以如果可以的話,請不要刪掉 bug...
114. 12/02 開新篇