發表文章

目前顯示的是有「dotnet」標籤的文章

C# 免裝Excel 就可以讀取 EXCEL 檔案 - ExcelDataReader (C# Read xls/xlsx/csv without excel using ExcelDataReader)

圖片
在幫公司開發程式的過程中,常常免不了要接收使用者或是客戶上傳的資料檔案, 通常我們程式設計師在解析檔案使用XML、CSV、TXT之類的檔案很好用,但對於使用者來說卻不是很友善的介面,通常會用統計資料的,也決不會是WORD,很多時候都是使用EXCEL或是CALC做出來的檔案。 在台灣大部分都是使用EXCEL做出來的統計檔案占絕大多數,因此處理這些EXCEL檔案便是家常便飯之事了。 而EXCEL產出的檔案,以附檔名類型上來說大致分為 .XLS 或是 .XLSX 這兩類。XLS檔案屬於BIFF格式檔案,它是一種二進位格式(Binary)檔案;XLSX則是比較新的檔案,屬於XML架構的檔案,一般又稱為 OpenXML,因此在處理與解讀上有所不同。 通常要處理 BIFF 檔案或是 OpenXML 檔案都需要有相當的格式研究能力,對於一般設計師來說都不是簡單的事,更不像TXT、CSV、XML這麼容易。 dotNet Framework 處理 EXCEL 當然自有一套方式,不管是LINQ、或是使用 Microsoft.Office.Interop.Excel 或是以 Microsoft.Jet.OLEDB.4.0 資料庫方式操作都避免不了一件事,就是 執行讀取檔案的電腦必須安裝 EXCEL ,但大家都知道 EXCEL本身不是免費的軟體,收費也很高,如果要在使用者端能夠執行,勢必在使用者端要裝上不少授權,光是費用都很驚人,也不是一般的小公司能夠負擔的。 ExcelDataReader - 這是一套在GitHub 上的 OpenSource 套件,它提供了強大的 Reader 功能,重點是免費,與強大的可攜性,它號稱是 Lightweight and fast library written in C# for reading Microsoft Excel files。 基本的讀取不是問題,處理檔案有它就很夠用了。 首先你可以到專案下的 NuGet 去取得套件: 總共有兩個套件要安裝:ExcelDataReader 和 ExcelDataReader.DataSet 要注意的是3.0.0以前的版本只有 ExcelDataReader,沒有 ExcelDataReader.DataSet,這個 DataSet 套件是從 3.0.0後分開的,

ASP.NET Core 2 外掛設定檔

圖片
上圖是一般開發 WinForm/APP 時會使用一些設定檔,提供程式一定的彈性,其用法是會把設定檔資訊設定 Properties 屬性裡面的『設定』,而實際會存在 app.config 或是 user.config 裡面,而且是使用XML格式儲存的(如上圖)。 但在ASP.NET Core 2 下如果要使用自己的設定檔,它的使用方式和一般 WinForm/APP 不一樣,因為它沒有預設的介面可以設定,而且它不能儲存 user.config,它反而比較建議使用 JSON 格式來處理設定檔。 畢竟JSON格式是網路上比較通用的格式,處理與閱讀起來也比XML輕鬆。 如果在系統上要一開始就載入設定檔,必需要先建立一個 json 檔案, 例如在程式 root 下新增一個 json 檔,並設定內容: 然後新增 json 檔案內容並儲存 它的結構基本上會像下面: {   "Section" : { "Name" : Value } } 一個 json 裡面可以有許多 section ,每個 section 裡面可以包含多組 name : value 然後在 Program.cs 裡面使用 ConfigureAppConfiguration 增加組態設定, (這個 ConfigureAppConfiguration 本身就是一種 DI) Program.cs namespace MyWeb1 {     public class Program     {         public static void Main(string[] args)         {             CreateWebHostBuilder(args).Build().Run();         }         public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>             WebHost.CreateDefaultBuilder(args)             .ConfigureAppConfiguration((webHostBuil

在 IIS 上執行 ASP.NET Core

圖片
雖然,ASP.NET Core 的程式可以單獨執行(使用內建 kestrel 伺服器),但是 kestrel 畢竟是輕量化服務器,操作與設定不熟悉的人使用起來就會頗困難。 而且,在有規模公司裡面伺服器 IIS 管理人可能又跟寫這程式碼的人不是同一個人,因此大原則上,程式設計就歸程式設計,伺服器管理就歸伺服器管理是比較標準的做法。 那麼 IIS 上如何掛上 ASP.NET Core 的應用呢? 建議使用 IIS 8.0 以上的版本(官方建議啦),原則上就是 Server 2008 以上作業系統。 一、 下載執行環境套件 Runtime : Microsoft Visual C++ 2015 Redistributable (非必要,除非該機器沒有裝過,下載要注意X86或X64版本) .NET Core Runtime (注意你的SDK版本) 在下載 .NET Core Runtime 時,一般都是下載最新版即可,如下圖: 但是如果你的SDK(開發)版本差異太大,例如你使用 SDK 2.0,而 Runtime 使用 2.1 ,則可能發生程式無法執行的錯誤,建議更新 SDK 後再重新編譯程式放到伺服器上,不然就是安裝降版的 Runtime ,若要安裝其它版本 Runtime,請點選下面聯結,尋找適當版本的 Runtime: 選擇其他版本,例如 2.0 版 下載該版本的 Runtime 二、 在伺服器上,將 Microsoft Visual C++ 2015 Redistributable 與 .NET Core Runtime 安裝好。 三、 建立程式放置資料夾與設定權限,如果直接使用 IIS 的內定資料夾 C:\inetpub 者,則省略此步驟。我再這個案例是建立在 D:\inetpub\api ,所以必須增加資料夾使用權限給 IIS 使用。 四、 在IIS管理員裡面新增應用程式集區         名稱雖然可以自己訂,但要易於識別所以取名為 .NET Core,然後 .NET CLR 版本要選『沒有Managed程式碼』(Unmanaged Code)。 五之一、 新增站台方式(如果要繼續使用80port做為http的服務,請確認原本IIS的站台 Default W

ASP.NET Core 2 關於 MVC Route Attribute

圖片
關於 ASP.Net Core 2 裡面使用的路由方式有很多種,MVC 的 Route Attribute 算是我常用的方法,因為它的維護上可以和主程式分離所以比較容易。 但是,一開始的時候常常搞不懂它的運作方式,跌跌撞撞失敗了不少次才搞懂,因此特別記錄下來以便給其他需要的人看。 先講 MVC 裡面對於 URL 的拆解方式,假如看到下面的 URL: http://localhost:5000/hr/Employee_GetByID?=k004521 它的組成就是像下面階層一樣: 用企業的描述法來說就是到 localhost:500 的服務器上, (Controller)取得人資系統(HR/Human Resources)資訊裡, (Action)以ID方式取得員工資料(Employee_GetByID), (Arguments)員工編號為 k004521 這樣好處是容易理解這個 Request 的目的。 當然回傳的內容依照自己系統需求而訂,可以是純字串、XML字串或是JSON字串都可以。 那麼,在ASP.NET Core 2 如何實現呢? 首先,準備一個類別檔案 ApiControllers.cs,這檔案我習慣放在 Controllers 資料夾下面(分類整理比較方便),當然懶得這樣分類也是可以放在與 Startup.cs 同一層下 using Microsoft.AspNetCore.Mvc ; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace SimplyApi.Controllers {    [ Route ( "about" )]     public class ApiAboutController {       [ Route ( "" )]       public string home() {           return "Resource Support API" ;       }       [ Route ( "co

電子發票期別顯示

電子發票期別顯示方式如下 yyy年m1-m2月 例如: 107年05-06月 一般資料來源會是當月的月份, 例如2018年6月15日開立發票會由系統產出 yyyymm 當作期別: 10706 產生顯示期別方式(標準): string period = "10706" ; string monthText; int month = int.Parse(period .Substring(3, 2)); if (mnth%2 == 0) {      //is even     monthText = (mnth - 1).ToString( "00" ) + "-" + mnth.ToString( "00" ); } else {      //is odd     monthText = mnth.ToString( "00" ) + "-" + (mnth + 1).ToString( "00" ); } //產生顯示表達 string InvoicePeriod = period.Substring(0, 3) + "年" + monthText + "月" ; 精簡化(不易閱讀): string period = "10706" ; int month = int.Parse(period .Substring(3, 2)); string InvoicePeriod = period.Substring(0, 3) + "年" + ((mnth % 2 == 0) ? (mnth - 1).ToString( "00" ) + "-" + mnth.ToString( "00" ) : mnth.ToString( "00" ) + "-" + (mnth + 1).ToString( "00" )) + "月&q

C# 取得 Windows 內所有程序視窗名稱、類別、指標

圖片
Get windows process handle / title name / class name 這篇其實是用來輔助 powerbuilder 寫的,因為大多數的第三方軟體都習慣會透過 FindWindow 這個API來確認己方程式是否已經啟動。 但是通常會不清楚自己開發工具開發的視窗會是哪種 Class Name ,所以利用下面簡單方式把電腦內所有程序的 handle / title name / class name 全部列出來查個清楚。 由於呼叫了 C 元件(COM API)所以需要多使用下面幾種 引用 using System.Runtime.InteropServices; using System.Text; using System.Collections; 程式的部分我將使用一個多行的 TextBox 把資訊列出來: namespace EnumWindows20 {     public partial class Form1 : Form     {         //Define Unmanaged API         public delegate bool EnumedWindow ( IntPtr handleWindow, ArrayList handles);         [ DllImport ( "user32.dll" , CharSet = CharSet.Auto, SetLastError = true)]         [return: MarshalAs(UnmanagedType.Bool)]         public static extern bool EnumWindows ( EnumedWindow lpEnumFunc, ArrayList lParam);         [ DllImport ( "user32.dll" , SetLastError = true, CharSet = CharSet.Auto)]         public static extern int GetClassName ( IntPtr hWnd, StringBuilder lpCl

C# HEX 字串 產生方式 (HEX KEY Gen)

很多時候,需要產生 HEX KEY 來做為唯一值,或是種子密碼來用,一般的情況我們會檢單的使用亂數(Random)來產生 Random rnd = new Random(); int num = rnd.Next(); string hexData = num.ToString("X"); 但是,許多人都知道,如果要產生很長的HEX字串,這個 Ramdom 是不夠力的。 而且也有『不夠亂』的問題存在(受限於Random演算法) 當然如果需要32字元的 HEX 字串,也可以直接使用 GUID 產生方式來獲得: string guidString = Guid.NewGuid().ToString().Replace("-", "").ToUpper(); string hexData = guidString; 但是如果要再更長,夠亂的HEX字串呢? 則可以使用 RNGCryptoServiceProvider 來處理 使用前記得引用 System.Security.Cryptography byte[] bytes = new byte[16]; using (var rng = new RNGCryptoServiceProvider()) {         rng.GetBytes(bytes); } string sBytes = BitConverter.ToString(bytes).Replace("-", ""); string hexData = sBytes; 長度的決定就由 byte 陣列大小來決定,因為一個byte可以生成2個字元的HEX碼, 所以byte[16]可以生成32字元HEX碼,byte[32]可以生成64字元的HEX碼,依此類推。

Microsoft Server 2008 / 2012 工作排程器 無法正常執行 C# [.NET] 程式

圖片
這個問題是我常常遇到的,很多時候寫Server端的程式通常是需要配合排程(工作排程器)執行的。 而這個工作排程器好似從2008以後的版本就跟2003有不少差異。 但就寫程式的工程師而言,有一個非常要注意的地方,那就是『程式執行位置』,底下演示一段程式碼來顯示 正常情況下 ,你的程式取得的程式所在位置資訊 我的程式位置在 D:\TEST 11\CnetAppPath string dir = System.Environment.CurrentDirectory; 位置: D:\TEST 11\CnetAppPath string dir = System.Windows.Forms.Application.StartupPath; 位置: D:\TEST 11\CnetAppPath string dir = System.IO.Directory.GetCurrentDirectory(); 位置: D:\TEST 11\CnetAppPath string dir = System.AppDomain.CurrentDomain.BaseDirectory; 位置: D:\TEST 11\CnetAppPath\ string dir = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase; 位置: D:\TEST 11\CnetAppPath\ string dir = System.Windows.Forms.Application.ExecutablePath; 位置: D:\TEST 11\CnetAppPath\AppPath.exe string dir = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName; 位置: D:\TEST 11\CnetAppPath\AppPath.exe string dir = this.GetType().Assembly.Location; 位置: D:\TEST 11\CnetAppPath\AppPath.exe 假設,我建立一個 捷徑 ,一般情況下捷徑裡面會有一個設定值『開始位置』