2025年5月16日 星期五

C# 動態放置log4net路徑

 參考網站logging - C# Log4Net - dynamically change log directory programmatically - Stack Overflow


config:

file type="log4net.Util.PatternString" value="%property{LogFileName}.txt"
程式碼:
log4net.GlobalContext.Properties["LogFileName"] = @"D:\abc";
log4net.Config.XmlConfigurator.Configure();

2025年3月17日 星期一

C# 背景登入功能實做

參考自Chatgpt


 public bool Checkin(string username, string password)

{

    var autoLoginService = new AutoLoginService();


    bool defaultPageContent = false;

    //defaultPageContent = autoLoginService.Login(username, password, strLoginpage, strquerypage);


    return defaultPageContent;

}


public bool Login(string username, string password, string strlogin, string strquery)

{

    bool bolr = false;


    //SSL TLS1.2

    System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate

    {

        return CheckCert();

    };


    //for SSL

    System.Net.ServicePointManager.SecurityProtocol = (System.Net.SecurityProtocolType)3072;


    using (HttpClientHandler handler = new HttpClientHandler { UseCookies = true })

    using (HttpClient client = new HttpClient(handler))

    {

        // 1️⃣ 先發送 GET 請求取得 __VIEWSTATE 和 __EVENTVALIDATION

        HttpResponseMessage getResponse = client.GetAsync(strlogin).Result;

        string loginPageHtml = getResponse.Content.ReadAsStringAsync().Result;

        //Writelog(loginPageHtml);

        // 解析 __VIEWSTATE 和 __EVENTVALIDATION

        string viewState = Regex.Match(loginPageHtml, "id=\"__VIEWSTATE\" value=\"(.*?)\"").Groups[1].Value;

        string eventValidation = Regex.Match(loginPageHtml, "id=\"__EVENTVALIDATION\" value=\"(.*?)\"").Groups[1].Value;


        Writelog($"VIEWSTATE: {viewState}");

        Writelog($"EVENTVALIDATION: {eventValidation}");


        Writelog("txtUser = " + username);

        Writelog("txtPwd = " + password);


        // 2️⃣ 準備登入請求的 Form Data

        var loginData = new FormUrlEncodedContent(new[]

        {

        new KeyValuePair<string, string>("__VIEWSTATE", viewState),

        new KeyValuePair<string, string>("__EVENTVALIDATION", eventValidation),

        new KeyValuePair<string, string>("txtOrgCode", "BOTOSB"),

        new KeyValuePair<string, string>("txtUser", username),  // 請更換成你的帳號輸入框名稱

        new KeyValuePair<string, string>("txtPwd", password),  // 請更換成你的密碼輸入框名稱

        new KeyValuePair<string, string>("cmdLogin", "Login")  // 請更換成你的登入按鈕名稱

    });


        // 3️⃣ 發送 POST 登入請求

        HttpResponseMessage postResponse = client.PostAsync(strlogin, loginData).Result;


        // 4️⃣ 檢查是否成功登入

        if (postResponse.IsSuccessStatusCode)

        {

            Writelog(postResponse.Content.ReadAsStringAsync().Result.Substring(0, 1500));


            //Console.WriteLine("登入成功!");

            bolr = true;

            // 5️⃣ 使用登入後的 Cookie 訪問 Default 頁面

            //HttpResponseMessage defaultPageResponse = client.GetAsync(strquery).Result;

            //string defaultPageHtml = defaultPageResponse.Content.ReadAsStringAsync().Result;


            //Writelog(defaultPageHtml); // 只顯示部分 HTML

        }

        else

        {

            //Console.WriteLine("❌ 登入失敗!");

            bolr = false;

        }

    }


    return bolr;

}

2024年10月22日 星期二

bat 讀檔存成另個檔案

在echo !line!時改成 echo(!line!

可以避免讀到空值時秀出echo is off的訊息

@echo off

setlocal enabledelayedexpansion
for /f "delims=:" %%a in ('findstr /n "AXX0000XXXA" "C:\Users\23456\Desktop\data.txt"') do (set /A find_line=%%a-1)
call :processFile < "C:\Users\23456\Desktop\data.txt" > target.txt
goto :EOF


:processFile

rem Duplicate the first %find_line%-1 lines
for /L %%i in (1,1,%find_line%) do (
   set /P "line="
   echo(!line!
)

rem Insert the additional line
type temp.txt

rem Copy the rest of lines
findstr ^^

exit /B

參考:windows - Why this code says echo is off? - Stack Overflow