精選文章

bcp大量匯出與匯入資料庫資料方法

--匯出-- bcp "select * from [資料庫名稱].[dbo].[資料表名稱]" queryout 匯出檔案名稱.txt -w -U "使用者帳號" -P "使用者密碼" " ...

2019年10月1日 星期二

Selenium-瀏覽器的操作

說明:
以下是一些關於瀏覽器操作的語法與案例

1.訪問指定網址
以下二種方法都可以訪問指定的網址
driver.Navigate().GoToUrl("https://www.google.com/");

driver.Url ="https://www.google.com/"

2.回上一頁
driver.Navigate().Back();

3.到下一頁
driver.Navigate().Forward();

4.重新整理
driver.Navigate().Refresh();

5.瀏覽器最大化
driver.Manage().Window.Maximize();

6.瀏覽器最小化
driver.Manage().Window.Minimize();

7.瀏覽器自訂大小
driver.Manage().Window.Size = new System.Drawing.Size(800, 600);

8.關閉瀏覽器
driver.close(); //關閉當前瀏覽器視窗
driver.quit(); //退出驅動並關閉所有關聯的視窗

2019年9月26日 星期四

Selenium-使用不同的瀏覽器

說明:
在前篇初始語法裡,使用瀏覽器是Chrome,但Selenium支援很多不同的瀏覽器, 這裡要教如何改更瀏覽器,可以實現同個案例,可以使用不同的瀏覽器進行驗證。

驅動瀏覽器
在初始語法裡,是寫在 [ClassInitialize],
就是每次執行此測試類別時,都會去執行,驅動Chrome如下
driver = new ChromeDriver();
想要使用其他瀏覽器,只要更改此段語法即可,在更改其他瀏覽器時,在using也要新增該瀏覽器的提示詞。

以第1個範例的程式碼進行修改-使用Firefox
將語法修改如下:
using OpenQA.Selenium.Chrome; => using OpenQA.Selenium.Firefox;
driver = new ChromeDriver(); => driver = new FirefoxDriver();
並執行測試,結果發生錯誤訊息,原因是,沒有安裝Firefox驅動,可以到NuGet安裝「Selenium.Firefox.WebDriver」
相關的瀏覽器驅動可以到https://www.seleniumhq.org/download/,有下載網址。
錯誤訊息:
類別初始設定方法 UnitTestProject1.UnitTest1.InitializeClass 擲回例外狀況。OpenQA.Selenium.DriverServiceNotFoundException: OpenQA.Selenium.DriverServiceNotFoundException: The geckodriver.exe file does not exist in the current directory or in a directory on the PATH environment variable. The driver can be downloaded at https://github.com/mozilla/geckodriver/releases.。
使用IE
操作與Firefox相同,也要去下載驅動,都完成後執行測試,還是發生錯誤訊息,
需要去調整IE的安全性,操作如下:
工具->網際網路選項->安全性,
將「網際網路」、「近端內部網路」、「信任的網站」、「限制的網站」
以上四個區域的「啟用受保護模式(需要重新啟動Internet Explorer)」,
都打勾或都不勾

錯誤訊息:
System.InvalidOperationException: System.InvalidOperationException: Unexpected error launching Internet Explorer. Protected Mode settings are not the same for all zones. Enable Protected Mode must be set to the same value (enabled or disabled) for all zones. (SessionNotCreated)。

2019年9月25日 星期三

C# Google Maps API取得資料

問題:C# Google Maps API取得資料
把地址轉成JSON格式
    
public GoogleGeoCodeResponse ConvertAddressToLatLng(string addr)
        {
            string result = string.Empty;
            string googlemapkey = "你的API金鑰";         
            string MapUrl = String.Format("https://maps.googleapis.com/maps/api/geocode/json?");
            
            string url = MapUrl + "address={0}&key={1}";
            url = string.Format(url, addr, googlemapkey);

            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
            using (var response = request.GetResponse())
            using (StreamReader sr = new StreamReader(response.GetResponseStream()))
            {

                result = sr.ReadToEnd();
            }

            return JsonConvert.DeserializeObject(result);
        }

取得的JSON格式(20190925)
 
{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "122號",
               "short_name" : "122號",
               "types" : [ "street_number" ]
            },
            {
               "long_name" : "Section 1, Chongqing South Road",
               "short_name" : "Section 1, Chongqing South Road",
               "types" : [ "route" ]
            },
            {
               "long_name" : "Bo'ai Special Zone",
               "short_name" : "Bo'ai Special Zone",
               "types" : [ "neighborhood", "political" ]
            },
            {
               "long_name" : "Zhongzheng District",
               "short_name" : "Zhongzheng District",
               "types" : [ "administrative_area_level_3", "political" ]
            },
            {
               "long_name" : "Taipei City",
               "short_name" : "Taipei City",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "Taiwan",
               "short_name" : "TW",
               "types" : [ "country", "political" ]
            },
            {
               "long_name" : "100",
               "short_name" : "100",
               "types" : [ "postal_code" ]
            }
         ],
         "formatted_address" : "No. 122號, Section 1, Chongqing South Road, Zhongzheng District, Taipei City, Taiwan 100",
         "geometry" : {
            "location" : {
               "lat" : 25.0400826,
               "lng" : 121.5119547
            },
            "location_type" : "ROOFTOP",
            "viewport" : {
               "northeast" : {
                  "lat" : 25.0414315802915,
                  "lng" : 121.5133036802915
               },
               "southwest" : {
                  "lat" : 25.03873361970849,
                  "lng" : 121.5106057197085
               }
            }
         },
         "place_id" : "ChIJJXNJjQqpQjQR-UfWtMFthwI",
         "plus_code" : {
            "compound_code" : "2GR6+2Q Zhongzheng District, 台北市 Taiwan",
            "global_code" : "7QQ32GR6+2Q"
         },
         "types" : [ "establishment", "point_of_interest", "tourist_attraction" ]
      }
   ],
   "status" : "OK"
}

設定的結構
部份有調整過,可以自行設計
 
public class GoogleGeoCodeResponse
        {

            public string status { get; set; }
            public string error_message { get; set; }
            public results[] results { get; set; }
        }
        public class results
        {
            public string formatted_address { get; set; }
            public geometry geometry { get; set; }
            public string[] types { get; set; }
            public address_component[] address_components { get; set; }
        }
        public class geometry
        {
            public string location_type { get; set; }
            public location location { get; set; }
        }

        public class location
        {
            public string status { get; set; }
            public string error_message { get; set; }
            public string lat { get; set; }
            public string lng { get; set; }
        }
        public class address_component
        {
            public string long_name { get; set; }
            public string short_name { get; set; }
            public string[] types { get; set; }
        }

處理地址轉成json後,輸出經緯度資料
 
public location GetLatLngByAddr(string addr)
        {
            location _result = new location();
            GoogleGeoCodeResponse _mapdata = new GoogleGeoCodeResponse();
            _mapdata = ConvertAddressToLatLng(addr);
            if (_mapdata.status == "OK")
            {
                    _result.lat = _mapdata.results[0].geometry.location.lat;
                    _result.lng = _mapdata.results[0].geometry.location.lng;
            }
            else
            {
                _result.error_message = _mapdata.error_message;
            }
            _result.status = _mapdata.status;
            return _result;
        }

2019年9月20日 星期五

Selenium-開始第1個範例 (for C# MSTest)

說明:
使用初始語法去修改,在T1內容裡輸入以下內容後執行測試, 執行成功的話,會直接關掉瀏覽器,建議可以把
CleanupClass()中的
driver.Close()
driver.Dispose()
註解掉

範例
會導向google首頁網址
    
 public void T1名稱()
        {
            try
            {
                driver.Navigate().GoToUrl("https://www.google.com");
            }
            catch (Exception ex)
            {
                verificationErrors.Append(ex);
            }
               
        }

結果影片

2019年9月19日 星期四

Selenium-初始語法 (for C# MSTest)

說明:
使用C# MSTest 進行Selenium時,會這樣設計初始語法再去新增或修改

 
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
using System.Diagnostics;

namespace UnitTestProject1
{
    [TestClass]
    public class UnitTest1
    {
        //初始設定
        private static IWebDriver driver;
        private StringBuilder verificationErrors;

        // ClassInitialize運行類別的第一個測試前運行代碼(在這個測試類別都會去執行)
        [ClassInitialize]
        public static void InitializeClass(TestContext testContext)
        {
            //自行設定路徑或直接從Nuget安裝
            driver = new ChromeDriver();
            //瀏覽器最大化
            driver.Manage().Window.Maximize();
        }
        // ClassCleanup運行完類別中的所有測試后再運行代碼
        // (就是這個測試類別裡的測試代碼都執行完畢後才執行)
        [ClassCleanup]
        public static void CleanupClass()
        {
            try
            {
                //driver.Quit();// quit does not close the window
                driver.Close();
                driver.Dispose();
            }
            catch (Exception)
            {
                // Ignore errors if unable to close the browser
            }
        }
        // TestInitialize在運行每個測試前先運行代碼(就是在TestMethod()前會執行的程式碼)
        [TestInitialize]
        public void InitializeTest()
        {
            verificationErrors = new StringBuilder();
        }
        // TestCleanup在運行完每個測試後運行代碼(就是在TestMethod()後會執行的程式碼)    
        [TestCleanup]
        public void CleanupTest()
        {
            //Trace.WriteLine(verificationErrors.ToString());
            Assert.AreEqual("", verificationErrors.ToString());
        }
        // TestMethod撰寫測試案例主要內容,[T1]是為了執行順序方便排序使用,[名稱]可以編輯
        [TestMethod]
        public void T1名稱()
        {

        }
        [TestMethod]
        public void T2名稱()
        {
            
        }

    }
}



2019年8月20日 星期二

VMware Player 與 Device/Credential Guard 不兼容

問題:VMware Player 與 Device/Credential Guard 不兼容
內容:



說明:
在Win10執行VMware虛擬機時,發生不兼容問題,無法開啟
解決方法:
方法1
使用管理者身份開啟cmd,並執行以下指令
bcdedit /set hypervisorlaunchtype off

2019年7月2日 星期二

發行到IIS下的網站,無法讀取LocalDB

問題:發行到IIS下的網站,無法讀取LocalDB
建立連接至 SQL Server 時,發生網路相關或執行個體特定的錯誤。找不到或無法存取伺服器。確認執行個名稱是否正確,以及 SQL Server 是否設定為允許遠端連線。 (provider: SQL Network Interfaces, error: 50 - Local Database Runtime 發生錯誤。 無法建立自動執行個體。如需錯誤詳細資料,請參閱 Windows 應用程式事件記錄檔。 )
說明:
當寫好的網站發行到IIS時,出現以上錯誤訊息

解決方法:
只要修改 C:\Windows\System32\inetsrv\config\applicationHost.config
把 setProfileEnvironment="false"
改成 setProfileEnvironment="true"

參考網站:
https://blog.darkthread.net/blog/localdb-under-iis/
https://dotblogs.com.tw/wookpecker/2016/04/16/231552

2019年6月17日 星期一

查所有資料表名稱與結構名稱、建立時間、修改時間

說明:
1.查所有資料表名稱,當有上百個以上的資料表時,不用一個一個打,可以使用該方法一次找到所有資料表名稱, 
  再配EXCEL就可以組合成select語法一次查詢。 
2.結構名稱有些table建立時會設定不同的結構名稱,預設通常是dbo 
3.建立時間,資料表建立時間 
4.修改時間,適用於當該資料表有修改過時,可以透過該欄位來知道

PS:在此使用Server SQL 2016操作
語法:
    
SELECT name AS object_name   
  ,SCHEMA_NAME(schema_id) AS schema_name  
  ,type_desc  
  ,create_date  
  ,modify_date  
FROM sys.objects  
where type='U'
order by schema_name,object_name

2019年6月12日 星期三

當使用JQuery append 動態方式產生元件使用時,無法觸法Click事件時

    
$(document).on('click', '#delete', function(){
            var td = this.parentNode; //a元素的父節點 = td
            var tr = td.parentNode; // td元素的父節點 = tr
            tr.parentNode.removeChild(tr); //利用tr的父節點刪除tr
        });

方法
綁定的物件改為#delete的父層元素,若沒有父層可直接綁定$(document), 在此使用$(document)
參考網址
參考網址

2019年6月5日 星期三

修改檔案建立、修改及存取日期工具

軟體名稱:NewFileTime
現在版本:v3.51
軟體下載:官方下載

簡介:
NewFileTime 是一款可批次修改檔案和資料夾建立、(最後) 修改及 (最後) 存取日期和時間的免費軟體。 這款免安裝的實用工具簡單易用,首先以匯入 (import) 方式或拖放方式將要修改日期和時間的檔案和資料夾新增至的視窗中, 接著修改檔案和資料夾的日期和時間,您可將它們調整為同一日期和時間,亦可分別設定日期和時間, 最後按下「套用時間」按鈕即大功告成。 

測試用途:
1.當某些程序是判斷修改日期或建立日期時,可以使用該工具來修改日期達成測試,減少測試的等待時間。

2019年2月12日 星期二

使用TransactionScope物件達成批次更新資料的效果

說明:
更新資料時需要一次更新很多Table但是如果在更新的途中發生問題而停掉就會讓有些Table 已更新, TransactionScope可避免此問題

using (TransactionScope scope = new TransactionScope())
{
    // TODO: SQL連線
    scope.Complete();   // 交易完成
}

2019年1月31日 星期四

MS SQL 基本T-SQL語法

新增Table欄位
T-SQL
ALTER TABLE [TableName] ADD [ColumnName] [DataType] Default [Value]
T-SQL 範例1
ALTER TABLE Product ADD ProductName NVARCHAR(50) DEFAULT NULL
T-SQL 範例2
ALTER TABLE Product ADD ProductName NVARCHAR(50) NULL
更改欄位大小型態
T-SQL
ALTER TABLE [TableName] ALTER COLUMN [ColumnName] [DataType]
T-SQL 範例
ALTER TABLE Products ALTER COLUMN ProductName VARCHAR(30)

2019年1月25日 星期五

JS簡單的加密解密方法

說明:JS简单的加密解密方法

字符串加密
方法
    
/**
 * encrypto 加密程序
 * @param {Strng} str 待加密字符串
 * @param {Number} xor 异或值
 * @param {Number} hex 加密后的进制数
 * @return {Strng} 加密后的字符串
 */
function encrypto( str, xor, hex ) {
  if ( typeof str !== 'string' || typeof xor !== 'number' || typeof hex !== 'number') {
    return;
  }

let resultList = []; 
hex = hex <= 25 ? hex : hex % 25;

for ( let i=0; i < str.length; i++ ) {
    // 提取字符串每个字符的ascll码
    let charCode = str.charCodeAt(i);
    // 进行异或加密
    charCode = (charCode * 1) ^ xor;
    // 异或加密后的字符转成 hex 位数的字符串
    charCode = charCode.toString(hex);
    resultList.push(charCode);
  }
let splitStr = String.fromCharCode(hex + 97);
let resultStr = resultList.join( splitStr );
return resultStr;
}


字符串解密
方法
 
/**
 * decrypto 解密程序
 * @param {Strng} str 待加密字符串
 * @param {Number} xor 异或值
 * @param {Number} hex 加密后的进制数
 * @return {Strng} 加密后的字符串
 */
function decrypto( str, xor, hex ) { 
  if ( typeof str !== 'string' || typeof xor !== 'number' || typeof hex !== 'number') {
    return;
  }
  let strCharList = [];
  let resultList = []; 
  hex = hex <= 25 ? hex : hex % 25;
  // 解析出分割字符
  let splitStr = String.fromCharCode(hex + 97);
  // 分割出加密字符串的加密后的每个字符
  strCharList = str.split(splitStr);

  for ( let i=0; i < strCharList.length; i++ ) {
    // 将加密后的每个字符转成加密后的ascll码
    let charCode = parseInt(strCharList[i], hex);
    // 异或解密出原字符的ascll码
    charCode = (charCode * 1) ^ xor;
    let strChar = String.fromCharCode(charCode);
    resultList.push(strChar);
  }
  let resultStr = resultList.join('');
  return resultStr;
}


測試
方法
 
let s1 = 'hello world';

// 加密
s1 = encrypto(s1, 123, 25);
console.log('s1=', s1);
// s1= jz15znznzkz3gzczkz9znz16

// 解密
let s2 = decrypto(s1, 123, 25);
console.log('s2=', s2);
// s2= hello world

C#的解密方式
"ToInt32的基底,必須是 2、8、10 或 16"
方法
 
private string decrypto(string str)
        {
            string [] strCharList;
            List resultList=new List();
            
            // 解析出分割字符
            char splitStr = (char)(16 + 97);
            // 分割出加密字符串的加密後的每個字符
            strCharList = str.Split(splitStr);

            for (int i = 0; i < strCharList.Length; i++)
            {
                // 將加密後的每個字符轉成加密後的ascll碼
                int charCode = Convert.ToInt32(strCharList[i],16);
                // 異或解密出原字符的ascll碼
                charCode = (charCode * 1) ^ 123;
                char strChar = (char)(charCode);
                resultList.Add(strChar);
            }
            string resultStr = string.Join("", resultList);
            return resultStr;
        }