2024年11月12日 星期二

[研究]SQL Server 動態資料遮罩 (Dynamic Data Masking, DDM) 試用

[研究]SQL Server 動態資料遮罩 (Dynamic Data Masking, DDM) 試用

2024-11-08x

環境:Visual Studio 2022 + ASP.NET + WebForm + Web Application + C# + SQL Server 2019 + SQL Server Management Studio (SSMS) 19

********************************************************************************

SSMS (SQL Server Management Studio)

CREATE DATABASE DynamicDataMaskTestDB
GO
USE DynamicDataMaskTestDB
GO

CREATE TABLE Employees(
		ID varchar(11) primary key,
        CName nvarchar(10),
		Birthday date,
		Marriage char(1),
        Email varchar(255),                   
        Tel varchar(20),
        Salary numeric(13,2),
        )
GO

INSERT INTO Employees
	VALUES ('A123456789', N'趙一', '20010102', 0, 'a01@company.com', '02-12345678', 20000)
	     , ('B123456789', N'錢二', '20020304', 1, 'b02@company.com', '03-23456789', 30000)
	     , ('C123456789', N'孫三', '20040405', 1, 'c03@company.com', '04-34567890', 40000)
SELECT * FROM [DynamicDataMaskTestDB].[dbo].[Employees]



********************************************************************************

遮罩

USE DynamicDataMaskTestDB
ALTER TABLE Employees ALTER COLUMN Birthday ADD MASKED WITH(FUNCTION='default()')
ALTER TABLE Employees ALTER COLUMN Marriage ADD MASKED WITH(FUNCTION='default()')
ALTER TABLE Employees ALTER COLUMN Tel ADD MASKED WITH(FUNCTION='default()')
ALTER TABLE Employees ALTER COLUMN Salary ADD MASKED WITH(FUNCTION='default()')







********************************************************************************

SQL Server, 多低的帳號,在動態資料遮罩(DDM Dynamic Data Mask)  時看不到遮罩內容 ?

ChatGPT 說:

在 SQL Server 中,當啟用動態資料遮罩 (Dynamic Data Mask, DDM) 時,只有擁有以下許可權的帳號可以看到被遮罩的實際資料內容:

  • UNMASK 權限:只要擁有 UNMASK 權限,該帳號無論是何種角色或權限等級,都可以直接存取完整的資料,而不會受到 DDM 影響。
  • sysadmin 固定伺服器角色:此角色中的成員預設擁有 UNMASK 權限,因此可以查看完整的資料內容,而不受遮罩影響。
  • db_owner 角色:資料庫的 db_owner 成員也擁有 UNMASK 權限,能查看未遮罩的實際資料。

因此,任何沒有這些高權限(如 UNMASK 權限、sysadmin 或 db_owner 角色)的帳號,即使有 SELECT 權限,仍然只能看到被遮罩過的資料內容。

********************************************************************************

db_datareader, db_datawriter 可以看到被遮罩資料? 

ChatGPT 說:

不可以。只有擁有 UNMASK 權限 或屬於 sysadmin 或 db_owner 角色的帳號,才可以看到未被遮罩的資料內容。沒有這些高權限的帳號,即使具備讀寫權限,仍會看到被遮罩的資料格式。

********************************************************************************

db_owner 可以設定為 UNMASK  嗎?

ChatGPT 說:無法。

********************************************************************************

SQL Server 類帳號僅有 datareader 和 datawriter,可以執行伺服器端操作嗎?例如 UPDATE、BULK INSERT(T-SQL)、SELECT INTO、INSERT..SELECT 等

ChatGPT 說:

若 SQL Server 類帳號(SQL Server Login)僅被授予 db_datareader 和 db_datawriter 角色,則其對資料庫的操作權限會有以下限制:

  • UPDATE:db_datawriter 角色允許對表格進行 INSERT、UPDATE、DELETE 操作,因此這些帳號可以執行 UPDATE 操作。
  • SELECT INTO:SELECT INTO 會將查詢結果插入到一個新的表格,這需要 CREATE TABLE 權限。單純的 db_datareader 和 db_datawriter 角色不包括 CREATE TABLE 權限,因此無法直接使用 SELECT INTO。
  • BULK INSERT:BULK INSERT 操作需要 BULK ADMIN 伺服器級別權限,db_datareader 和 db_datawriter 角色無法滿足此需求。如果需要執行 BULK INSERT,必須顯式分配 BULK ADMIN 角色或相應權限。
  • INSERT..SELECT:INSERT..SELECT 允許從一個表格或查詢結果插入資料到另一個已存在的表格。由於 db_datawriter 角色允許執行 INSERT 操作,因此可以使用 INSERT..SELECT。

總結來說,僅有 db_datareader 和 db_datawriter 權限的帳號可以執行 UPDATE 和 INSERT..SELECT 操作,但無法執行 SELECT INTO 和 BULK INSERT。
********************************************************************************
【伺服器角色】

【資料庫角色】


SQL Server 2019 請問那些 伺服器角色 看不到 DDM 遮罩欄位內容 ?
bulkadmin
dbcreator
diskadmin
processadmin
public
securityadmin
serveradmin
setupadmin
sysadmin

ChatGPT 說:

總結來說,除了 sysadmin 外,其他伺服器角色皆無法看到。

****************************************

SQL Server 2019 請問那些 資料庫角色 看不到 DDM 遮罩欄位內容 ?
db_accessadmin
db_backupoperator
db_datareader
db_datawriter
db_ddladmin
db_denydatareader
db_denydatawriter
db_owner
db_securityadmin
public

ChatGPT 說:

總結來說,除了 db_owner 資料庫角色以外,其他資料庫角色皆無法看到。
********************************************************************************

(完)

相關

[研究]SQL Server 動態資料遮罩 (Dynamic Data Masking, DDM) 試用
https://shaurong.blogspot.com/2024/11/sql-server-dynamic-data-masking-ddm.html

[研究]Microsoft SQL Server 數據加密技術比較
https://shaurong.blogspot.com/2024/06/microsoft-sql-server.html

[研究]SQL Server 角色權限、可執行 SQL 指令、可檢視動態資料遮罩 (Dynamic Data Masking, DDM)比較
https://www.blogger.com/blog/post/edit/3479310643037793626/5394507395545162744

[研究]ASP.NET,WebForm, SQL Server Always Encrypted 加密資料行、加密資料庫試用
https://shaurong.blogspot.com/2024/06/aspnetwebform-sql-server-always.html

[研究]VMware Fusion 和 Workstation 從2024/11/11開始對所有使用者免費

[研究]VMware Fusion 和 Workstation 從2024/11/11開始對所有使用者免費

2024-11-12

https://blogs.vmware.com/cloud-foundation/2024/11/11/vmware-fusion-and-workstation-are-now-free-for-all-users/



我們很高興地宣布一項重大變化,這反映了我們致力於讓 VMware Fusion 和 VMware Workstation 比以往更易於使用的承諾。從 2024 年 11 月 11 日開始,這些功能強大的桌上型虛擬機器管理程式產品將免費提供給所有人(商業用戶、教育用戶和個人用戶)。

發生了什麼變化?

即日起,VMware Fusion 和 VMware Workstation 都將放棄付費訂閱模式,這意味著您現在可以免費使用這些工具。這些產品的付費版本(Workstation Pro 和 Fusion Pro)不再可供購買。 

(完)

2024年11月11日 星期一

[研究]Outlook 2019每次加簽或加密寄信都要求允許使用 電子郵件憑證,哪裡取消詢問?

[研究]Outlook 2019每次加簽或加密寄信都要求允許使用 電子郵件憑證,哪裡取消詢問?

2024-11-11

Outlook 每次加簽或加密寄信都要求允許使用 電子郵件憑證,哪裡取消詢問?

ChatGPT 說:

在 Outlook 中,如果每次寄信時都要求您允許使用電子郵件憑證,您可以通過調整信任中心的設定來取消此詢問。請按照以下步驟進行:

  1. 開啟 Outlook,點擊左上角的 [檔案]。
  2. 選擇 [選項],然後在左側選擇 [信任中心]。
  3. 點擊 [信任中心設定] 按鈕。
  4. 在 [電子郵件安全性] 頁籤中,找到 [加密的電子郵件]區域,按下 [設定]按鈕。
  5. 按下[選擇]按鈕,選擇沒過期、正確的Email憑證。

這樣應該就能停止每次寄信的詢問提示。如果還是無法解決,可能需要檢查您的憑證狀態或考慮重新安裝電子郵件憑證。








(完)


2024年11月8日 星期五

[研究]ASP.NET, bootstrap 3.4.1 升級 5.3.3 時 bootstrap.css 覆寫與否測試

[研究]ASP.NET, bootstrap 3.4.1 升級 5.3.3 時 bootstrap.css 覆寫與否測試

2024-11-08x

環境:Visual Studio 2022 + ASP.NET + WebForm + Web Application + C# + SQL Server 2019 + SQL Server Management Studio (SSMS) 19

********************************************************************************

【都不覆寫】



略看一下,版面疑似正常。

但功能有問題,左邊選單,無法展開;收合、展開功能故障。

********************************************************************************

【都覆寫】

整個版面嚴重變化。

********************************************************************************

bootstrap.css  3.4.1 版和 5.3.3 版比較,改的非常大,幾乎全改


********************************************************************************

bootstrap menu 3.x 升級 5.x 要改甚麼 ?

Bootstrap 5.x 相對於 3.x 有很多的變化,需要修改的地方也較多。以下是一些主要的修改點:

  • 移除 jQuery 依賴:Bootstrap 5.x 移除了對 jQuery 的依賴,改為使用純 JavaScript。
  • CSS 類別名稱變更:Bootstrap 5.x 中一些 CSS 類別名稱被修改了,例如 .navbar-default 改為 .navbar-light,.panel-default 改為 .card-default 等等。
  • 移除不必要的元素:Bootstrap 5.x 中一些不必要的元素被移除了,例如 .navbar-brand 元素中的 data-toggle="collapse" 屬性等等。
  • 格線系統變更:Bootstrap 5.x 中的格線系統有所變更,新增了 .row-cols-{breakpoint}-{number} 類別,可以更方便地調整列中的列數。
  • 新增元素:Bootstrap 5.x 中新增了一些元素,例如 .offcanvas、.toast、.spinner-border 等等。

總之,Bootstrap 5.x 相對於 3.x 的變化較大,需要仔細地檢查和修改程式碼。建議參考 Bootstrap 5.x 官方文件進行修改。

********************************************************************************

bootstrap 3.x 升級 5.x 主要的修改中,與選單的張開、收合有關的CSS屬性是甚麼 ?

在 Bootstrap 3.x 和 4.x 中,選單的張開、收合是使用 .collapse 和 .in 這兩個 CSS 類別來實現的。但在 Bootstrap 5.x 中,這兩個 CSS 類別被棄用了,改為使用 .collapse 和 .show 這兩個 CSS 類別來實現選單的張開、收合。

具體來說,如果你想要讓一個選單項目(例如 .navbar-collapse)在點擊時展開,可以使用以下程式碼:

<div class="navbar-collapse collapse">

  <!-- 選單內容 -->

</div>

然後使用 JavaScript(或者純 CSS)來動態添加 .show 類別,例如:

document.querySelector('.navbar-collapse').classList.add('show'); 

這樣就可以實現選單的展開了。注意,由於 Bootstrap 5.x 移除了對 jQuery 的依賴,所以如果你使用的是 jQuery,則需要修改相應的程式碼。

********************************************************************************

舉例,Bootstrap 3.x 和 4.x 中,選單的張開、收合如何使用 .collapse 和 .in ?

再舉例,改成 Bootstrap 5.x,範例要如何修改 ?

在 Bootstrap 3.x 和 4.x 中,使用 .collapse 和 .in 這兩個 CSS 類別來實現選單的張開、收合。以下是一個範例:

<div class="panel-group">
  <div class="panel panel-default">
    <div class="panel-heading">
      <h4 class="panel-title">
        <a data-toggle="collapse" href="#collapse1">Collapsible panel</a>
      </h4>
    </div>
    <div id="collapse1" class="panel-collapse collapse in">
      <div class="panel-body">Panel Body</div>
      <div class="panel-footer">Panel Footer</div>
    </div>
  </div>
</div>

在這個範例中,使用 .collapse 類別來實現選單的折疊效果,使用 .in 類別來指定選單預設為展開狀態。

在 Bootstrap 5.x 中,使用 .collapse 和 .in 這兩個 CSS 類別已經被棄用,改為使用 .collapse 和 .show 這兩個 CSS 類別。以下是一個將上述範例修改為 Bootstrap 5.x 的範例:

<div class="accordion" id="accordionExample">
  <div class="accordion-item">
    <h2 class="accordion-header" id="headingOne">
      <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
        Collapsible panel
      </button>
    </h2>
    <div id="collapseOne" class="accordion-collapse collapse show" aria-labelledby="headingOne" data-bs-parent="#accordionExample">
      <div class="accordion-body">
        Panel Body
      </div>
      <div class="accordion-footer">
        Panel Footer
      </div>
    </div>
  </div>
</div>

在這個範例中,使用 .collapse 類別來實現選單的折疊效果,使用 .show 類別來指定選單預設為展開狀態。同時,使用 data-bs-toggle="collapse" 和 data-bs-target="#collapseOne" 來實現選單的展開和收合,使用 data-bs-parent="#accordionExample" 來指定父元素的 ID,以實現多個選單互不干擾的效果。

********************************************************************************

對於 Content\bootstrap.css,bootstrap 3.x 升級 5.x 主要修改了甚麼 ?

Bootstrap 5.x 中對於 Content\bootstrap.css 文件進行了多項修改,主要包括以下幾點:

  • 移除了對 IE 8 和 IE 9 的支援。
  • 移除了部分過時和不常用的樣式。
  • 更新了顏色、字體和間距等方面的設計。
  • 使用了更多的自定義屬性(例如 --bs-*)來實現更靈活的樣式定制。
  • 移除了部分過時的 CSS 類別,例如 .glyphicon 和 .panel 等,並新增了一些新的 CSS 類別,例如 .dropup 和 .position-sticky 等。

此外,在 Bootstrap 5.x 中,Content\bootstrap.css 文件的結構和命名也有所調整,例如:

  • 使用了 :root 偽類來定義全局 CSS 變量。
  • 將樣式定義分為不同的區塊,例如 .reboot、.base、.typography 和 .utilities 等。
  • 將 .container 和 .container-fluid 的樣式定義移至獨立的文件 Content\containers.css 中。

總體來說,Bootstrap 5.x 中對於 Content\bootstrap.css 文件進行了大量的優化和調整,使得它更加現代化、靈活且易於使用。

********************************************************************************

bootstrap 3.x 升級 5.x 過程,若保留  Content\bootstrap.css 會發生甚麼問題 ?

若您保留 Bootstrap 3.x 中的 Content\bootstrap.css 文件並直接升級到 Bootstrap 5.x,可能會發生以下幾個問題:

  • 兼容性問題:Bootstrap 5.x 中有些樣式類別的命名可能已經變更,且有些類別已被刪除或更改了樣式定義,因此直接使用舊版的 Content\bootstrap.css 文件可能會導致兼容性問題。
  • 錯誤的樣式定義:由於 Bootstrap 5.x 中對樣式定義進行了大量的修改和優化,因此舊版的 Content\bootstrap.css 文件可能包含一些過時或不正確的樣式定義,這可能會導致頁面顯示錯誤的樣式。
  • 缺少新功能:Bootstrap 5.x 中新增了許多新的樣式類別和功能,這些新功能可能需要使用新的樣式定義才能正確顯示。如果您仍然使用舊版的 Content\bootstrap.css 文件,則可能會缺少這些新功能。

總之,為了確保順利升級到 Bootstrap 5.x,建議您不要保留舊版的 Content\bootstrap.css 文件,而是使用最新版的文件,或者根據需要進行必要的修改和優化。

********************************************************************************

bootstrap 3.x 升級 5.x 後,Visual Studio 要置換方案中那些文字成為新文字 ?

若您將一個使用 Bootstrap 3.x 開發的網站升級到 Bootstrap 5.x,建議您在 Visual Studio 中進行以下修改:

  • 將 bootstrap.css 替換為 bootstrap.min.css:在您的網站代碼中將所有引用 bootstrap.css 的地方改為引用 bootstrap.min.css,這是 Bootstrap 5.x 中的壓縮版本。
  • 將 bootstrap-theme.css 替換為 bootstrap.min.css:在您的網站代碼中將所有引用 bootstrap-theme.css 的地方改為引用 bootstrap.min.css,這是 Bootstrap 5.x 中的壓縮版本。
  • 更新樣式類別:Bootstrap 5.x 中新增了一些新的樣式類別,並有些類別的命名方式也有所調整。因此,請將您的代碼中所有舊版 Bootstrap 的樣式類別替換為對應的 Bootstrap 5.x 樣式類別。
  • 更新 JavaScript 插件:Bootstrap 5.x 中一些 JavaScript 插件的用法和 API 有所變更,因此請更新您的代碼以符合最新的 API 要求。
  • 更新圖標字體:Bootstrap 5.x 中移除了 Glyphicons 字體圖標,建議使用其他的圖標庫,例如 Font Awesome 等。

總之,在進行 Bootstrap 3.x 到 Bootstrap 5.x 的升級過程中,您需要仔細檢查您的代碼,將舊版的元素、樣式類別和 JavaScript 插件替換為對應的 Bootstrap 5.x 元素、樣式類別和 JavaScript 插件,以確保您的網站能夠正常運作。

********************************************************************************

有工具可以幫忙自動修改 or 找到 Bootstrap 3.x 升級 5.x 後需要手動修改的部分嗎 ?

Bootstrap 3.x 到 5.x 的升級是一個相對複雜的過程,並且可能需要對代碼進行大量修改。目前,並沒有任何一種工具可以完全自動化這個過程,但有些工具可以幫助您找到需要修改的部分,並提供一些提示和建議,以簡化升級過程。

以下是幾種可能有用的工具:

  • Bootstrap Upgrade Tool:Bootstrap 官方提供的升級工具,可以將您的 Bootstrap 3.x 代碼轉換為 Bootstrap 4.x 或 5.x 代碼。這個工具可以幫助您找到需要手動修改的部分,並提供一些提示和建議。請注意,這個工具不是完全自動化的,您仍然需要手動修改一些部分。
    註:Migrating to v5 · Bootstrap v5.0
    https://getbootstrap.com/docs/5.0/migration/
  • Bootlint:這是一個 Bootstrap HTML 驗證器,可以幫助您檢查您的代碼是否符合 Bootstrap 的最佳實踐和建議。這個工具可以幫助您找到一些需要修改的部分,並提供一些提示和建議。
  • VS Code Extension:有些 Visual Studio Code 的擴展可以幫助您進行 Bootstrap 3.x 到 5.x 的升級,例如 Bootstrap 3 to 4 Upgrade,可以自動將一些常見的代碼更改為 Bootstrap 4.x 或 5.x 的版本。這個工具仍然需要您手動檢查和修改一些部分,但可以節省一些時間和工作量。

需要注意的是,這些工具仍然需要您仔細檢查和修改您的代碼,以確保您的網站能夠正常運作。因此,在升級過程中,建議您仔細閱讀 Bootstrap 官方的文檔和指南,並遵循最佳實踐和建議,以確保您的網站能夠正常運作。

********************************************************************************

哪個 Visual Studio Code Extension 可幫助 Bootstrap 3.x 到 5.x 的升級

您可以使用 "Bootstrap 4 Upgrade" 擴展程式幫助升級 Bootstrap 3.x 到 4.x。 該擴展程式提供了一個命令,可以將您的 HTML、CSS 和 JavaScript 代碼升級到 Bootstrap 4.x 的版本。

至於升級到 Bootstrap 5.x,目前似乎還沒有相應的 Visual Studio Code Extension,但您可以參考 Bootstrap 官方文件中提供的升級指南,手動進行升級。這可能需要進行一些程式碼調整,以使您的代碼與 Bootstrap 5.x 版本兼容。

********************************************************************************

你建議 bootstrap 從 3.x 升級 4.x, 再從 4.x 升級到 5.x ; 或者直接從 3.x 升級到 5.x 呢 ?

我建議您直接從 Bootstrap 3.x 升級到 5.x,而跳過 Bootstrap 4.x。這是因為 Bootstrap 4.x 做了很多重大的更改,包括移除了一些類、引入了新的佈局工具、更改了許多組件的外觀和行為等。這些更改可能需要您重新學習 Bootstrap 的某些方面,而且如果您已經習慣了 Bootstrap 3.x 的使用方式,可能會感到比較困難。

而 Bootstrap 5.x 與 3.x 相比,更像是一次較小的更新,只是在原有的基礎上進行了一些改進和更新,包括優化了網格系統、改進了表單控件、增加了一些新的組件等。因此,從 3.x 直接升級到 5.x 可能會更加順暢和高效。

當然,如果您正在使用 Bootstrap 4.x 並且已經適應了它的使用方式,那麼升級到 5.x 也是可行的。不過,如果您已經習慣了 Bootstrap 3.x 的使用方式,那麼直接跳過 4.x 並直接升級到 5.x 可能更加方便。

********************************************************************************

(完)

相關

[研究]ASP.NET, ZipFile 同時存在於 DotNetZip.Reduced 1.9.1.8 和 DotNetZip 1.16.0

[研究]ASP.NET, ZipFile 同時存在於 DotNetZip.Reduced 1.9.1.8 和 DotNetZip 1.16.0

2024-11-08


********************************************************************************

packages.config 中

  <package id="DotNetZip" version="1.16.0" targetFramework="net48" />

  <package id="DotNetZip.Reduced" version="1.9.1.8" targetFramework="net48" />


因為 NuGet 安裝 OdsReaderWriter 1.0.10 會安裝 DotNetZip.Reduced 1.9.1.8,可移除。


(完)






[研究]ASP.NET, X.PagedList.10.2.1 升級 X.PagedList.10.5.7,編譯出錯

[研究]ASP.NET, X.PagedList.10.2.1 升級 X.PagedList.10.5.7,編譯出錯

2024-11-07

官方網站

https://andrew.gubskiy.com/projects/item/open-source

https://www.nuget.org/packages/X.PagedList/10.2.1

https://www.nuget.org/packages/X.PagedList/10.5.7

********************************************************************************

【PagedList.10.2.1】

Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" 
    Inherits="WebApplication1.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:GridView ID="gvData" runat="server" AutoGenerateColumns="true"></asp:GridView>
        <br />
        <asp:Repeater ID="pager" runat="server" OnItemCommand="pager_ItemCommand">
            <ItemTemplate>
                <asp:LinkButton ID="lnkPage" runat="server" CommandName="Page" 
                    CommandArgument='<%# Container.DataItem %>'
                    Text='<%# Container.DataItem %>'></asp:LinkButton>
            </ItemTemplate>
        </asp:Repeater>
    </form>
</body>
</html>


Default.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI.WebControls;
using X.PagedList;

namespace WebApplication1
{
    public partial class Default : System.Web.UI.Page
    {
        private const int PageSize = 10; // 每頁顯示的項目數量

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                BindData(1); // 預設顯示第 1 頁
            }
        }

        private void BindData(int pageNumber)
        {
            // 模擬資料來源
            List<string> data = Enumerable.Range(1, 100).Select(i => "Item " + i).ToList();

            // 使用 X.PagedList 進行分頁
            var pagedData = data.ToPagedList(pageNumber, PageSize);

            // 綁定分頁資料至 GridView
            gvData.DataSource = pagedData;
            gvData.DataBind();

            // 設定分頁按鈕
            pager.DataSource = Enumerable.Range(1, pagedData.PageCount);
            pager.DataBind();

            // 儲存目前頁碼
            ViewState["CurrentPage"] = pageNumber;
        }

        protected void pager_ItemCommand(object source, System.Web.UI.WebControls.RepeaterCommandEventArgs e)
        {
            if (e.CommandName == "Page")
            {
                int pageNumber = Convert.ToInt32(e.CommandArgument);
                BindData(pageNumber);
            }
        }
    }
}

實際測試OK



********************************************************************************

更新:

X.PagedList.10.2.1 -> X.PagedList.10.5.7

Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1 -> Microsoft.CodeDom.Providers.DotNetCompilerPlatform.4.1.0


嚴重性 程式碼 說明 專案 檔案 隱藏項目狀態

錯誤 CS1061 'List<string>' 未包含 'ToPagedList' 的定義,也找不到可接受類型 'List<string>' 第一個引數的可存取擴充方法 'ToPagedList' (是否遺漏 using 指示詞或組件參考?) WebApplication1 C:\CodeTemp3\WebApplication1\WebApplication1\Default.aspx.cs 27 作用中


********************************************************************************

【X.PagedList.10.5.7】

測試把

using X.PagedList;   

換成

using X.PagedList.Extensions;   

執行正常。

(完)

相關



[研究]ASP.NET,WebForm,用 FreeDataExports 1.1.11 匯出 SqlDataSource1 資料成 .ods (MIT)

[研究]ASP.NET,WebForm,用 FreeDataExports 1.1.11 匯出 SqlDataSource1 資料成 .ods (MIT)

2024-11-08

環境:Visual Studio 2022 + ASP.NET + WebForm + Web Application + C# + SQL Server 2019 + SQL Server Management Studio (SSMS) 19

********************************************************************************

https://www.nuget.org/packages/FreeDataExports/1.1.11/License

授權是 MIT



********************************************************************************

官方網站
https://github.com/ryankueter/FreeDataExports

官方的程式範例有問題。

Web.Config

<?xml version="1.0" encoding="utf-8"?>
<!--
  如需如何設定 ASP.NET 應用程式的詳細資訊,請前往
  https://go.microsoft.com/fwlink/?LinkId=169433
  -->
<configuration>
  <connectionStrings>
    <add name="MyDBConnectionString" connectionString="Data Source=.;Initial Catalog=MyDB;User ID=sa;Password=密碼"
      providerName="System.Data.SqlClient" />
  </connectionStrings>
  <system.web>
    <compilation debug="true" targetFramework="4.8" />
    <httpRuntime targetFramework="4.8" />
  </system.web>
  <system.codedom>
    <compilers>
      <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701" />
      <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
    </compilers>
  </system.codedom>
</configuration>

Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
</head>
<body>
<form id="form1" runat="server">
        <asp:SqlDataSource ID="SqlDataSource_Field2" runat="server"
            ConnectionString="<%$ ConnectionStrings:MyDBConnectionString %>"
            SelectCommand="SELECT N'全部' AS [Field2], 0 AS Priority
            UNION
            SELECT DISTINCT [Field2], 1 AS Priority FROM [MyTable] ORDER BY Priority, [Field2]"></asp:SqlDataSource>
        <asp:DropDownList ID="DropDownList_Field2" runat="server"
            AutoPostBack="True" DataSourceID="SqlDataSource_Field2"
            DataTextField="Field2" DataValueField="Field2">
        </asp:DropDownList>
        <br />
        <asp:Button ID="Button_Export_ODS" runat="server" Text="匯出(.ods)"
            OnClick="Button_Export_ODS_Click" /><br />
        <asp:Button ID="Button_Export_ODS2" runat="server" Text="匯出2(.ods)"
            OnClick="Button_Export_ODS2_Click" /><br />
        <asp:Button ID="Button_Export_ODS3" runat="server" Text="匯出3(.ods)"
            OnClick="Button_Export_ODS3_Click" /><br />
        <asp:Label ID="Label_MSG1" runat="server" Text="Label"></asp:Label>
        <br />
        <asp:SqlDataSource ID="SqlDataSource1" runat="server"
            ConnectionString="<%$ ConnectionStrings:MyDBConnectionString %>"
            SelectCommand="--TSQL--
            SELECT * FROM [MyTable]
            WHERE ([Field2]=@Filed2 OR @Filed2=N'全部');">
            <SelectParameters>
                <asp:ControlParameter ControlID="DropDownList_Field2" Name="Filed2" PropertyName="SelectedValue" />
            </SelectParameters>
        </asp:SqlDataSource>
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="SN" DataSourceID="SqlDataSource1">
            <Columns>
                <asp:BoundField DataField="SN" HeaderText="SN" InsertVisible="False" ReadOnly="True" SortExpression="SN" />
                <asp:BoundField DataField="Field1" HeaderText="Field1" SortExpression="Field1" />
                <asp:BoundField DataField="Field2" HeaderText="Field2" SortExpression="Field2" />
            </Columns>
        </asp:GridView>

    </form>
</body>
</html>

Default.aspx.cs

using System;
using System.Data.SqlClient;

namespace WebApplication1
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }

        protected void Button_Export_ODS_Click(object sender, EventArgs e)
        {
            string[] columnNameArray = { "流水號", "欄位1", "欄位2" };
            SqlParameter[] sqlParameters = OdsCommon.ConvertParameters(SqlDataSource1.SelectParameters, this.Page);
            OdsCommon.ExportODS("匯出檔案名稱", columnNameArray, SqlDataSource1.SelectCommand, sqlParameters);
        }

        protected void Button_Export_ODS2_Click(object sender, EventArgs e)
        {
            string[] columnNameArray = { "流水號", "欄位1", "欄位2" };
            SqlParameter[] sqlParameters = OdsCommon.ConvertParameters(SqlDataSource1.SelectParameters, this.Page);
            OdsReaderWriterSystemIOCompressionCommon.ExportODS("匯出檔案名稱", columnNameArray, SqlDataSource1.SelectCommand, sqlParameters);
        }
        protected void Button_Export_ODS3_Click(object sender, EventArgs e)
        {
            string[] columnNameArray = { "流水號", "欄位1", "欄位2" };
            SqlParameter[] sqlParameters = OdsFreeDataExportsCommon.ConvertParameters(SqlDataSource1.SelectParameters, this.Page);
            OdsFreeDataExportsCommon.ExportODS("匯出檔案名稱", columnNameArray, SqlDataSource1.SelectCommand, sqlParameters);
        }
    }
}



Default.aspx.cs

using FreeDataExports;
using System;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Web;
using System.Web.Configuration;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication1
{
    public class OdsFreeDataExportsCommon
    {
        //【匯出(.ods)】
        #region === public void ExportODS(string odsFilename, string sqlDataSourceSelectCommand) ===
        public static void ExportODS(string odsFilename,
            string[] columnNameArray,
            string sqlDataSourceSelectCommand,
            SqlParameter[] parameters)
        {
            // Import
            // https://docs.microsoft.com/en-us/office/open-xml/how-to-parse-and-read-a-large-spreadsheet

            // Export
            // https://docs.microsoft.com/en-us/office/open-xml/how-to-create-a-spreadsheet-document-by-providing-a-file-name

            //Insert text into a cell in a spreadsheet document(Open XML SDK)
            //https://docs.microsoft.com/zh-tw/office/open-xml/how-to-insert-text-into-a-cell-in-a-spreadsheet

            string mainFileName = odsFilename;

            // 若檔案名稱有中文字或特殊符號,Response.AddHeader() 輸出檔案名稱要編碼
            string outFileName = HttpUtility.UrlEncode(mainFileName, System.Text.Encoding.UTF8) + "-" +
                DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-fff") + ".ods";

            // XLWorkbook.SaveAs() 輸出檔案名稱不要用 HttpUtility.UrlEncode 編碼
            // Response.TransmitFile() 輸出檔案名稱不要用 HttpUtility.UrlEncode 編碼
            string dirFileName = @"D:\Production\TempImageFiles\" + mainFileName + "-" +
                DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-fff") + ".ods";
            try
            {
                System.Web.HttpContext.Current.Response.Clear();
                System.Web.HttpContext.Current.Response.Buffer = true;
                System.Web.HttpContext.Current.Response.Charset = "";

                #region === Export ODS ===

                // [EXCEL] Excel打開是亂碼?快速找回資料的最好方法!
                // http://blog.e-happy.com.tw/excel-excel%E6%89%93%E9%96%8B%E6%98%AF%E4%BA%82%E7%A2%BC%EF%BC%9F%E5%BF%AB%E9%80%9F%E6%89%BE%E5%9B%9E%E8%B3%87%E6%96%99%E7%9A%84%E6%9C%80%E5%A5%BD%E6%96%B9%E6%B3%95%EF%BC%81/

                // Excel開啟CSV時的中文編碼問題補遺
                //https://blog.darkthread.net/blog/csv-encoding-again/

                //Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                System.Web.HttpContext.Current.Response.ContentType = "application/vnd.oasis.opendocument.spreadsheet";    // ODF/.ods
                System.Web.HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=" + outFileName);
                using (MemoryStream MyMemoryStream = new MemoryStream())
                {
                    StreamWriter odsFileStreamWriter = new StreamWriter(MyMemoryStream);
                    StreamReader odsFileStreamReader = new StreamReader(new MemoryStream());
                    string dataText = "";

                    DataSet ds = new DataSet("DS1");
                    //DataTable dt = new DataTable();
                    DataTable dt = ds.Tables.Add("工作表1");

                    //                    string[] columnNameArray = {
                    //"流水號"
                    //,"欄位1"
                    //,"欄位2"
                    //        };
                    foreach (string columnName in columnNameArray)
                    {
                        DataColumn dataColumnName = new DataColumn
                        {
                            DataType = System.Type.GetType("System.String"),
                            ColumnName = columnName
                        };
                        dt.Columns.Add(dataColumnName);
                    }

                    DataRow dataColumnNameRow = dt.NewRow();
                    int ii = 0;
                    foreach (string columnName in columnNameArray)
                    {
                        dataColumnNameRow[ii] = columnName;
                        ii++;
                    }
                    dt.Rows.Add(dataColumnNameRow);

                    //string queryString = SqlDataSource.SelectCommand;
                    string queryString = sqlDataSourceSelectCommand;
                    using (SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["MyDBConnectionString"].ConnectionString))
                    {
                        SqlCommand command = new SqlCommand(queryString, connection);
                        //command.Parameters.Clear();
                        //command.Parameters.AddWithValue("@cname", cname);
                        //command.Parameters.AddWithValue("@myemail", myemail);

                        if (parameters != null)
                        {
                            foreach (SqlParameter parameter in parameters)
                            {
                                command.Parameters.Add(parameter);
                            }
                        }

                        connection.Open();

                        //Get All column 
                        //var columnNames = Enumerable.Range(0, reader.FieldCount)
                        //                        .Select(reader.GetName)
                        //                        .ToList();

                        ////Create headers
                        //sb.Append(string.Join(",", columnNames));

                        ////Append Line
                        //sb.AppendLine();


                        try
                        {
                            using (SqlDataReader reader = command.ExecuteReader())
                            {
                                while (reader.Read())
                                {
                                    //Console.WriteLine(String.Format("{0}", reader[0]));
                                    DataRow datarow = dt.NewRow();
                                    for (int i = 0; i < reader.FieldCount; i++)
                                    {
                                        dataText = reader[i].ToString();
                                        // 換掉影響 CSV 顯示效果的字元
                                        dataText = dataText.Replace("\r", "").Replace("\n", "").Replace("\t", "").Replace(",", ",").Replace("'", "′").Replace(@"""", "”");
                                        //if (i > 0)
                                        //{
                                        //    datarow[i - 1] = dataText;
                                        //}
                                        datarow[i] = dataText;
                                        //if (i == 1)
                                        //{
                                        //    //if (csvContent=="")
                                        //    //    csvContent = dataText;
                                        //    //else
                                        //    //csvContent = csvContent + "\r\n" + dataText;
                                        //    csvContent.Append("\r\n" + dataText);

                                        //}
                                        //else
                                        //{
                                        //    //csvContent = csvContent + "," + dataText;
                                        //    csvContent.Append("," + dataText);
                                        //}
                                    }
                                    dt.Rows.Add(datarow);
                                }
                            }

                            var workbook = new DataExport().CreateODSv1_3();
                            var worksheet = workbook.AddWorksheet("工作表1");
                            DataTable dataTable= ds.Tables[0];
                            for (int i = 0; i < dataTable.Rows.Count; i++)
                            {
                                worksheet.AddRow();
                                for (int j = 0; j < dataTable.Columns.Count; j++)
                                    worksheet.AddCell(dataTable.Rows[i].ItemArray[j], DataType.String);
                            }
                            workbook.Save(dirFileName);

                            //OdsReaderWriter odsFile = new OdsReaderWriter();
                            ////odsFile.WriteOdsFile(ds, @"C:\TEMP\1.ods");
                            //odsFile.WriteOdsFile(ds, dirFileName);

                            //Label_MSG1.ForeColor = System.Drawing.Color.Green;
                            //string msg = DateTime.Now.ToString() + "匯出成功。";
                            //Label_MSG1.Text = msg;
                            //Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('" + msg + "');</script>");
                        }
                        catch (Exception)
                        {
                            throw;
                        }
                    }
                    System.Web.HttpContext.Current.Response.TransmitFile(dirFileName);
                    System.Web.HttpContext.Current.Response.End();
                }
                #endregion Export ODS
            }
            catch (Exception)
            {
                throw;
            }
            //Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('匯出成功。');</script>");
        }
        #endregion

        //建立參數
        #region === public static SqlParameter[] ConvertParameters(ParameterCollection parameters, Page page) ===
        public static SqlParameter[] ConvertParameters(ParameterCollection parameters, Page page)
        {
            SqlParameter[] sqlParameters = new SqlParameter[parameters.Count];
            for (int i = 0; i < parameters.Count; i++)
            {
                var parameter = parameters[i];
                if (parameter is ControlParameter)
                {
                    ControlParameter controlParameter = (ControlParameter)parameter;
                    var control = page.FindControl(controlParameter.ControlID);
                    // 確保找到控制元件
                    if (control != null)
                    {
                        string value = (control as ITextControl)?.Text ?? string.Empty;
                        sqlParameters[i] = new SqlParameter(parameter.Name, value);
                    }
                    else
                    {
                        // 找不到控制元件時,應該提供預設值,而不是引發 NullReferenceException
                        sqlParameters[i] = new SqlParameter(parameter.Name, DBNull.Value);
                    }
                }
                else
                {
                    // 如果參數不是控制參數,則使用 DBNull.Value
                    sqlParameters[i] = new SqlParameter(parameter.Name, DBNull.Value);
                }
            }
            return sqlParameters;
        }
        #endregion === public static SqlParameter[] ConvertParameters(ParameterCollection parameters, Page page) ===
    }
}

實際測試可以成功。(按鈕3)

下圖,

下圖,

********************************************************************************

(完)

相關

[研究]ASP.NET,WebForm,用 FreeDataExports 1.1.11 匯出 SqlDataSource1 資料成 .ods (MIT)
https://shaurong.blogspot.com/2024/11/aspnetwebform-freedataexports-1111.html

[研究]ASP.NET,WebForm,用 FreeDataExports 1.1.11 匯出 .ods
https://shaurong.blogspot.com/2024/10/aspnetwebform-freedataexports-1111-ods.html

[研究]ASP.NET,WebForm,要傳遞 SqlDataSource1.SelectParameters 當時的值https://shaurong.blogspot.com/2024/03/aspnetwebform-sqldatasource1selectparam.html

[研究]ASP.NET,WebForm,用 FreeDataExports 1.1.9 匯出資料庫某資料表成 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-freedataexports-119-ods_29.html

[研究]ASP.NET,WebForm,用 FreeDataExports 1.1.9 匯出 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-freedataexports-119-ods.html

[研究]ASP.NET,WebForm, 把 OdsReadWrite.cs 從 Ionic.Zip 或 DotNetZip 改成用 System.IO.Compression
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreadwritecs-ioniczip.html

[研究]ASP.NET,WebForm,用 OdsReaderWriter + DotNetZip (Ionic.Zip) 1.16.0 共用匯出 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreaderwriter-dotnetzip_79.html

[研究]ASP.NET,WebForm,用 OdsReaderWriter + DotNetZip (Ionic.Zip) 1.16.0 匯出 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreaderwriter-dotnetzip_23.html

[研究]ASP.NET,WebForm,用 OdsReaderWriter + DotNetZip (Ionic.Zip) 1.16.0 匯入 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreaderwriter-dotnetzip_93.html

How to Read and Write ODF/ODS Files (OpenDocument Spreadsheets) - CodeProject
https://www.codeproject.com/Articles/38425/How-to-Read-and-Write-ODF-ODS-Files-OpenDocument-2

[研究][ASP.NET]讀取、匯出、寫入、匯入 Excel .xlsx .xls ODF .ods
https://shaurong.blogspot.com/2020/04/caspnetwebform-excel-xlsx-xls-odf-ods.html

[研究][ASP.NET]使用 OdsReaderWriter + DotNetZip 1.15.0 (Ionic.Zip) 匯出寫入 .ods
https://shaurong.blogspot.com/2021/02/aspnet-odsreaderwriter-dotnetzip-1150_9.html

[研究][ASP.NET]使用 OdsReaderWriter + DotNetZip 1.15.0 讀取匯入 .ods 到資料庫
https://shaurong.blogspot.com/2021/02/aspnet-odsreaderwriter-dotnetzip-1150.html

[研究][C#]用OdsReaderWrite匯出(寫入)、匯入(讀取) ODF/.ods 檔案 (使用 Ionic.Zip、DotNetZip)
https://shaurong.blogspot.com/2020/09/caspnetwebform-ioniczip-odfods.html

[研究] [C#] 用OdsReadWrite讀取 LibreOffice、OpenOffice 的試算表(Calc) 檔案 (.ods)(使用 .NET 4.5 的 ZipFile)
https://shaurong.blogspot.com/2016/12/c-libreoffice-516-calc-ods-net-45.html

[研究] [C#] 用OdsReaderWrite讀取 LibreOffice 5.1.6 的試算表(Calc) 檔案 (.ods)(使用 DotNetZip)
https://shaurong.blogspot.com/2016/12/c-libreoffice-516-calc-ods.html

NuGet Gallery | OdsReaderWriter 1.0.10
https://www.nuget.org/packages/OdsReaderWriter

sortings/OdsReadWrite at master · Luviz/sortings · GitHub
https://github.com/Luviz/sortings/tree/master/OdsReadWrite




2024年11月7日 星期四

[研究]NuGet 的 OdsReaderWriter 1.0.10 改用 OdsReadWrite.zip

[研究]NuGet 的 OdsReaderWriter 1.0.10 改用 OdsReadWrite.zip

2024-11-07

環境:Visual Studio 2022 + ASP.NET + WebForm + Web Application + C# + SQL Server 2019 + SQL Server Management Studio (SSMS) 19

********************************************************************************

NuGet 的 OdsReaderWriter 1.0.10 的  License 是Copyleft,移除改用 odsreadwrite.zip

********************************************************************************

先用 NuGet 把 OdsReaderWriter 1.0.10 移除,然後把這篇的 OdsReadWrite.cs 拷貝放到方案中

[研究]ASP.NET,WebForm, 把 OdsReadWrite.cs 從 Ionic.Zip 或 DotNetZip 改成用 System.IO.Compression
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreadwritecs-ioniczip.html

(這篇的程式,以前是正常可用,但目前測試不能用,不知是否 System.IO.Compression 改版還是其他因素,待解決)

using 要變更

//using Zaretto.ODS;	// NuGet ODSReaderWriter 1.0.10 使用;
using OdsReadWrite;	// 若用 odsreadwrite.zip 中的 OdsReaderWriter.cs 檔案  

.cs 中

//ODSReaderWriter odsFile = new ODSReaderWriter();  // NuGet OdsReaderWriter 使用,注意大小寫不同
OdsReaderWriter odsFile = new OdsReaderWriter();  // OdsReaderWriter.cs 使用


因為 NuGet 安裝 OdsReaderWriter 1.0.10 會安裝 DotNetZip.Reduced 1.9.1.8,可移除。



編譯,看看有無問題,再進行處理。

(完)

相關

[研究]ASP.NET,WebForm,用 NuGet OdsReaderWriter 1.0.10 匯出 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-nuget-odsreaderwriter.html

[研究]ASP.NET,WebForm, 把 OdsReadWrite.cs 從 Ionic.Zip 或 DotNetZip 改成用 System.IO.Compression
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreadwritecs-ioniczip.html

[研究]ASP.NET,WebForm,用 OdsReaderWriter + DotNetZip (Ionic.Zip) 1.16.0 共用匯出 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreaderwriter-dotnetzip_79.html

[研究]ASP.NET,WebForm,用 OdsReaderWriter + DotNetZip (Ionic.Zip) 1.16.0 匯出 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreaderwriter-dotnetzip_23.html

[研究]ASP.NET,WebForm,用 OdsReaderWriter + DotNetZip (Ionic.Zip) 1.16.0 匯入 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreaderwriter-dotnetzip_93.html

How to Read and Write ODF/ODS Files (OpenDocument Spreadsheets) - CodeProject
https://www.codeproject.com/Articles/38425/How-to-Read-and-Write-ODF-ODS-Files-OpenDocument-2

[研究][ASP.NET]讀取、匯出、寫入、匯入 Excel .xlsx .xls ODF .ods
https://shaurong.blogspot.com/2020/04/caspnetwebform-excel-xlsx-xls-odf-ods.html

[研究][ASP.NET]使用 OdsReaderWriter + DotNetZip 1.15.0 (Ionic.Zip) 匯出寫入 .ods
https://shaurong.blogspot.com/2021/02/aspnet-odsreaderwriter-dotnetzip-1150_9.html

[研究][ASP.NET]使用 OdsReaderWriter + DotNetZip 1.15.0 讀取匯入 .ods 到資料庫
https://shaurong.blogspot.com/2021/02/aspnet-odsreaderwriter-dotnetzip-1150.html

[研究][C#]用OdsReaderWrite匯出(寫入)、匯入(讀取) ODF/.ods 檔案 (使用 Ionic.Zip、DotNetZip)
https://shaurong.blogspot.com/2020/09/caspnetwebform-ioniczip-odfods.html

[研究] [C#] 用OdsReadWrite讀取 LibreOffice、OpenOffice 的試算表(Calc) 檔案 (.ods)(使用 .NET 4.5 的 ZipFile)
https://shaurong.blogspot.com/2016/12/c-libreoffice-516-calc-ods-net-45.html

[研究] [C#] 用OdsReaderWrite讀取 LibreOffice 5.1.6 的試算表(Calc) 檔案 (.ods)(使用 DotNetZip)
https://shaurong.blogspot.com/2016/12/c-libreoffice-516-calc-ods.html

NuGet Gallery | OdsReaderWriter 1.0.10
https://www.nuget.org/packages/OdsReaderWriter

sortings/OdsReadWrite at master · Luviz/sortings · GitHub
https://github.com/Luviz/sortings/tree/master/OdsReadWrite






[研究]Windows Server 2019 不能安裝 Microsoft .NET Framework 4.8.1

[研究]Windows Server 2019 不能安裝 Microsoft .NET Framework 4.8.1

2024-11-07

下載 .NET Framework
https://dotnet.microsoft.com/zh-tw/download/dotnet-framework

Windows Server 2019 安裝 Microsoft .NET Framework 4.8.1 出現錯誤:

這個作業系統不支援 .NET Framework 4.8.1。

********************************************************************************

查了一下

.NET Framework 系統需求
https://learn.microsoft.com/zh-tw/dotnet/framework/get-started/system-requirements

.NET Framework system requirements
https://learn.microsoft.com/en-us/dotnet/framework/get-started/system-requirements



(完)

2024年11月6日 星期三

[研究] Fedora 41 Workstation Linux 繁體中文版安裝

[研究] Fedora 41 Workstation Linux 繁體中文版安裝

2024-11-05

Fedora 40 於美國時間 2024-04-23釋出; EOL 於2025-05-13,壽命約1年。

官方網站、下載
https://getfedora.org/

Fedora version history - Wikipedia
https://en.wikipedia.org/wiki/Fedora_version_history

Fedora Linux Schedule
https://fedorapeople.org/groups/schedule/

下載
https://dl.fedoraproject.org/pub/fedora/linux/releases/41/Workstation/x86_64/iso/

Fedora (作業系統) - 維基百科,自由的百科全書

https://zh.wikipedia.org/wiki/Fedora_(%E4%BD%9C%E6%A5%AD%E7%B3%BB%E7%B5%B1)

Fedora-Workstation-Live-x86_64-41-1.4.iso

2.28 GB (2,458,187,776 位元組)

Click圖片可看100%尺寸原圖,不難安裝,只是做個紀錄。

一開始安裝,畫面會自動跳到 1280x768 解析度,但安裝過程隨時可以調整解析度 ( 敝人在 VMware Workstaiton Pro的 VM 上安裝)






















VMware Tools 顯示 ReInstall,疑似已經安裝了。

(完)

相關

[研究] Fedora 41 Workstation Linux 繁體中文版安裝
https://shaurong.blogspot.com/2024/11/fedora-41-workstation-linux.html

[研究] Fedora 40 Workstation Linux 繁體中文版安裝
https://shaurong.blogspot.com/2024/04/fedora-40-workstation-linux.html

[研究] Fedora 39 Workstation Linux 繁體中文版安裝
https://shaurong.blogspot.com/2023/11/fedora-39-workstation-linux.html

[研究] Fedora 38 Workstation Linux 繁體中文版安裝
https://shaurong.blogspot.com/2023/04/fedora-38-workstation-linux.html

[研究] Fedora Server 37 Linux 繁體中文版安裝
https://shaurong.blogspot.com/2022/11/fedora-server-37-linux.html

[研究] Fedora 37 Workstation Linux 繁體中文版安裝
http://shaurong.blogspot.com/2022/11/fedora-37-workstation-linux.html

[研究] Fedora 34 Workstation Linux 安裝
http://shaurong.blogspot.com/2021/07/fedora-34-workstation-linux.html