การใช้ Parameters ในการสร้าง query string สำหรับใช้กับ MySql Connector Net C# เบื้องต้น

สวัสดีครับ วันนี้จะมาแนะนำการใช้ parameter เพื่อสร้าง query string สำหรับใช้ในโปรแกรมที่เขียนด้วย C#  และใช้ MySql Connector Net เบื้องต้นนะครับ

ความสำคัญของการใช้ parameter คือเพื่อป้องกันการโจมตีแบบ  SQL Injection ซึ่งเป็นการใส่ command เข้ามาพร้อมกัน query ที่ถูกสร้างขึ้น สังเกตุการส้าง query string ด้านล่างนี้นะครับ

[code language=”csharp”] string query = "SELECT * FROM recipe WHERE name = " + name;
[/code]

จะเห็นได้ว่าเราได้สร้าง query string ขึ้นมาจากการรวมข้อความกับตัวแปรที่ค่าในตัวแปรนั้นอาจจะเป็นอะไรก็ตามแต่ที่ผู้ใช้งานป้อนเข้ามาซึ่งอาจจะเป็น query ที่ใช้โจมตีเราด้วยก็เป็นไปได้ ดังนั้นถ้าเราใช้ parameter

[code language=”csharp”] string query = "SELECT * FROM recipe WHERE name = @name";
[/code]

ในส่วนของ parameter จะถูกมองว่าเป็นเพียงแค่ฟิลด์ข้อมูลเท่านั้น(หมายความว่าส่วนของ parameter จะไม่ถูก execute) ดังนั้นการใช้ parameter จึงป้องกัน SQL injection ได้

สำหรับการใช้ parameter กับ MySql Connector Net นั้นก็ไม่ได้ยากอะไร ก่อนอื่นขอแนะนำส่วนที่เกี่ยวข้องก่อน

  • MySqlCommand.Parameters เป็น collection ที่เก็บ instance ของ Parameter class
  • Parameter class เก็บข้อมูล parameter เพื่อให้ MySqlCommand ใช้
  • MySqlCommand.Parameters.AddWithValue(string parameterName, object value) สร้าง Parameter class พร้อมกับระบุชื่อและค่าของ parameter และเก็บเข้าสู่ Parameters collection

ทั้งหมดที่จำเป็นก็มีเพียงเท่านี้ จริงๆ แล้วเราสามารถกำหนดได้ถึง ชนิดข้อมูลและขนาดของ parameter ผ่านการสร้าง Parameter class จากนั้นก็ Add parameter class เข้าสู่ Parameters collection อีกที แต่จากการทดสอบพบว่าไม่ผลอะไรกับการที่ไม่ได้กำหนดชนิดและขนาดของข้อมูล(ตัวอักษรเก็บได้กว้างสูงสุดเท่าที่เรากำหนดไว้อยู่แล้ว ตัวเลขส่วนตัวทดสอบแล้วเจอ exception ตั้งแต่ข้อมูลเกินตัวแปร int) ดังนั้นใช้ AddWithValue จะสะดวกกว่า

อย่างแรกคือการสร้าง query string ที่ระบุข้อมูลเป็นชื่อ parameter ก่อน โดยชื่อ parameter นั้นให้เติม prefix “@” ไว้

[code language=”csharp”] string query = "SELECT * FROM recipe WHERE name = @name";
[/code]

ต่อไปก็ทำการเพิ่ม parameter ให้กับ Parameters collection โดยต้องระบุชื่อ parameter ให้ตรงกับค่าที่ต้องการ

ข้อสังเกตเล็กน้อยคือเราจะไม่สามารถเพิ่ม Parameter ที่มีชื่อเหมือนกับ Parameter ที่มีอยู่ก่อนใน Parameters collection ได้ หรือก็คือไม่สามารถตั้งชื่อ parameter ซ้ำกันได้นั่นเอง ต่อไปจะเป็นตัวอย่างต่างๆ ในการใช้ parameter นะครับ

ใช้แบบปกติ

ผมใช้ query เดียวภายใน method ไม่ได้เปลี่ยน query เพื่อรันภายใน method ต่อโดยใช้ MySqlCommand เดิมแต่อย่างใด

[code language=”csharp”] public bool Update(int ID, int quantity)
{
try
{
string query = "UPDATE recipe SET quantity = @quantity WHERE recipe_id = @id";

if (OpenConnection())
{
MySqlCommand cmd = new MySqlCommand(query, connection);
cmd.Parameters.AddWithValue("@quantity", quantity);
cmd.Parameters.AddWithValue("@id", ID);
cmd.ExecuteNonQuery();
CloseConnection();

return true;
}
}
catch (MySqlException ex)
{
MessageBox.Show(ex.Message + Environment.NewLine + ex.StackTrace, "Error number : " + ex.Number,
MessageBoxButtons.OK, MessageBoxIcon.Information);

return false;
}

return false;
}
[/code]

ใช้ใน Loop

เนื่องจากเราไม่สามารถเพิ่ม parameter ที่มีชื่อซ้ำกันเข้าไปภายใน MySqlCommand.Parameters.Clear() ในการลบ parameter เดิมภายใน collection ออกและทำการเพิ่มเข้าไปใหม่ หรือเราสามารถเปลี่ยนค่า parameter ผ่าน index ตรงๆ เลยก็ได้เช่น MySqlCommand.Parameters[i].Value = value; หรือ MySqlCommand.Parameters[“@parameterName”].Value = value; แต่ผมขอเลือกใช้วิธีการลบ parameter เดิมออก (ด้านล่างนี้เป็นตัวอย่างจริงๆ)

[code language=”csharp”] public void testmethod(string name, List<string>[] data)
{
if (OpenConnection())
{
string query = "INSERT INTO some_table (name, id, value)" +
"VALUES(@name, @id, @value)";
MySqlCommand cmd = new MySqlCommand(query, connection);

for (int i = 0; i < data[0].Count; i++)
{
cmd.Parameters.AddWithValue("@name", name);
cmd.Parameters.AddWithValue("@id", data[0][i]);
cmd.Parameters.AddWithValue("@value", data[1][i]);
cmd.CommandText = query;
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
}
}
}
[/code]

จากตัวอย่างล่าสุดนี้สามารถปรับไปใช้แบบกำปรับค่า parameter ผ่าน index ก็ได้ ลักษณะจะเป็นประมาณนี้

[code language=”csharp”] public void testmethod(string name, List<string>[] data)
{
if (OpenConnection())
{
string query = "INSERT INTO some_table (name, id, value)" +
"VALUES(@name, @id, @value)";
MySqlCommand cmd = new MySqlCommand(query, connection);
cmd.Parameters.AddWithValue("@name", name);
cmd.Parameters.AddWithValue("@id", data[0][0]);
cmd.Parameters.AddWithValue("@value", data[1][0]);

for (int i = 0; i < data[0].Count; i++)
{
cmd.Parameters["@id"].Value = data[0][i];
cmd.Parameters["@value"].Value = data[1][i];
cmd.CommandText = query;
cmd.ExecuteNonQuery();
}
}
}
[/code]

2 ตัวอย่างล่าสุดสามารถเขียนในแบบอื่นๆ ได้อีกหลายแบบ สามารถดูรายละเอียดได้จาก MySqlCommand Members ทั้งหมดนี้ก็เป็นพื้นฐานการใช้ parameter กับ MySqlConnector net ครับ ถ้ามีคำถามหรือผมอธิบายอะไรผิดไป คอมเม้นบอกกันได้เลยนะครับ

การเพิ่ม Name-based Virtual Host ให้กับ Apache สำหรับใช้งานบน localhost

สวัสดีครับ หลังจากไม่ได้เขียนมานานเนื่องจากหลายๆ เหตุผลวันนี้ได้ฤกษ์เขียนอะไรที่พอมีประโยชน์ต่อซะที

จากชื่อบทความอาจจะฟังดูไร้สาระไปซักหน่อย เนื่องจากการทำให้เครื่องเราเป็น webserver เพื่อใช้ในการพัฒนาเว็บไซต์นั้น ถ้าทำแบบง่ายๆ ไม่ได้คิดอะไรมากก็แค่ลง WAMP ซักตัวหนึ่ง จากนั้นก็สร้าง subdirectory ขึ้นมาแล้วสร้างเว็บไซต์ไว้ใน subdirectory นั้น เมื่อเราจะเข้าดูผ่านเว็บไซต์ก็จะเข้าโดยการพิมพ์ลิ้ง localhost/subdirectory ที่เราต้องการเข้าแค่นั้น

แต่บทความนี้จะแนะนำวิธีการใช้ name-based virtual host เบื้องต้น ซึ่งจะส่งผลทำให้เราสามารถใช้ domain อะไรก็ได้ตามที่เรากำหนดไว้ ในการเข้าสู่เว็บไซต์บน localhost ของเรานั่นเอง(แต่ถ้า domain เหมือนกันกับที่มีอยู่แล้วบน internet เราก็จะไม่สามารถเข้าเว็บนั้นได้)

ในบทความนี้นั้นผมใช้ WampServer 2.5 ซึ่งเป็นแพ็กของซอฟต์แวร์ที่ใช้ในการทำ webserver สำหรับคำว่า WAMP นั้นไม่ได้หมายถึงตัวซอฟแวร์ตัวใดตัวหนึ่ง แต่หมายถึงซอฟแวร์ 3 ตัวที่นิยมใช้ในการทำ webserver : Windows, Apache, MySql, PHP จะมีอีกคำหนึ่งที่เห็นได้เหมือนกันคือ LAMP ซึ่งตัว L มาจาก Linux ซึ่งผู้ให้บริการ web hosting ส่วนใหญ่นิยมใช้ Linux ซึ่งฟรีมากกว่าใช้ Windows Server ซึ่งไม่ฟรีมาใช้งานอยู่แล้ว แต่ในกรณีทั่วไปที่คนส่วนใหญ่ไม่ได้ใช้ Linux ดังนั้น WAMP จึงเป็นตัวเลือกสำหรับคนใช้ windows นั่นเอง

สำหรับ WampServer 2.5 นั้นใช้ Apache 2.4.9 ซึ่งเวอร์ชั่นตรงนี้จะมีผลกับการเซตของเราด้วย ดังนั้นบทความนี้จะอาจจะใช้กับ Apache ที่เวอร์ชั่นต่ำกว่านี้ไม่ได้ ดังนั้นผมจะลงรายละเอียดที่เกี่ยวข้องไว้เท่าที่จะหาได้ไว้ในส่วนที่เกี่ยวข้องนะครับ

เพิ่ม domain name ให้กับไฟล์ hosts ของเรา

Windows ทุกเครื่องนั้นมีไฟล์ hosts อยู่ที่ C:\Windows\System32\drivers\etc ซึ่งไฟล์นี้นั้นถูกใช้โดย  TCP/IP ของ windows เองเปรียบเสมือน DNS server ตัวแรกหลักจากที่ web browser ของเราส่ง request ออกไปที่ DNS server ของ ISP(หรือตามแต่ที่เรากำหนด) ดังนั้งถ้าเราอยากจะเปลี่ยน IP ที่ domain name นั้นควรจะส่ง IP ที่ถูกต้องสำหรับ domain name นั้นคืนมา ไปเป็น IP อื่น ที่มันไม่ควรจะเป็น ก็จะสามารถทำได้ที่ไฟล์นี้เป็นด่านแรกนั่นเอง

ขั้นตอนแรกให้เปิดไฟล์ hosts ที่ C:\Windows\System32\drivers\etc ขึ้นมาก่อน ด้วย text editor ตัวใดก็ได้  ถ้ายังไม่ได้เพิ่มเติมอะไรเลย ไฟล์ที่ได้จะเป็นแบบนี้

hosts before
C:\Windows\System32\drivers\etc\hosts

สังเกตที่บรรทัดสุดท้ายซึ่งเป็นบรรทัดที่คำสั่งถูกใช้งานจริงๆ  และฝั่งซ้ายมือจะเป็น IP ของเครื่องเราเอง ฝั่งขวาจะเป็น Domain name ซึ่งต่อไปนี้ผมจะขอเรียกว่า hostname แทน ให้เราทำการเพิ่ม host name ที่เราต้องการตามรูปแบบที่มีอยู่คือ IP ที่แสดงถึงเครื่องของเราเอง(127.0.0.1)อยู่ทางด้านซ้าย เว้นวรรคด้วย tab จากนั้น ก็ใส่ชื่อ hostname ที่เราต้องการลงทางด้านขวา จะได้เป็นแบบนี้

C:\Windows\System32\drivers\etc\hosts

จากนั้นก็ให้ทำการเซฟ สำหรับคนที่เซฟไม่ได้(ปกติก็ไม่น่าจะะมีใครเซฟได้) เช่น ถ้าใช้ notepad จะบอกว่าไม่มี permission หรือถ้าใช้ notepad++ จะบอกว่า มีโปรแกรมอื่นใช้อยู่ ให้เราทำการเพิ่ม permission ให้กับ user ของเรากับไฟล์นี้ก่อน โดยให้คลิกขวาที่ไฟล์ > Properties > Security tab > Edit จากนั้นให้คลิกที่ user เราและที่ช่องด้านล่างให้ติกที่ Write เสร็จแล้วให้กด OK หากมีหน้าขึ้นมาให้ยืนยัน เท่านี้เราก็จะสามารถเซฟไฟล์ hosts ได้แล้วและอย่าลืมแก้ permission คืนด้วยหลังจากเซฟเสร็จ

หลังจากขั้นตอนนี้สิ่งที่ได้มาคือ ผมได้เพิ่ม host name ชื่อ sakura.moe เข้าไป(domain name อันนี้ในอินเตอร์เน็ตมีคนจดไว้แล้ว) การทำงานหลังจากนี้คร่าวๆ(รู้แค่นี้ TwT) เมื่อเราพิมพ์ลิ้งไปที่ sakura.moe web browser จะได้รับ IP ของเครื่องเรากลับคืนมาเองและ web browser ก็จะใช้ IP นี้ access เข้าไปที่ web server(apache) ซึ่ง ก็หมายถึงเครื่องเรานั่นเอง

เพิ่ม Virtual Host ให้กับ Apache

Virtual host นั้นมีด้วยการ 2 แบบ name-based กับ IP-based ความต่างของทั้งสองอย่างนี้แบบเข้าใจง่ายๆ คือ name-based จะยึดตาม request ที่เข้ามาว่าต้องการ hostname อันไหนก่อนส่งข้อมูลนั้นกลับไปที่ client ส่วน IP-based จะยึดตามว่าต้องการ connection ของ IP ไหน ทำให้จำเป็นต้องใช้ IP แยกตาม host(website) ส่งผลให้สิ้นเปลือง IP ดังนั้นปกติจะไม่ได้ใช้แบบ IP-based กัน แต่จะใช้แบบ Name-based ที่จะทำให้หลาย host สามารถแชร์ IP เดียวกันได้

ขั้นแรกให้ไปเปิด modules ที่ใช้กับการทำงานของ name-based virtual host ก่อน โดยการเข้าไปที่ \apache2.4.9\conf  จากนั้นเปิดไฟล์ httpd ด้วย text editor จากนั้นค้นหาบรรทัด LoadModule vhost_alias_module modules/mod_vhost_alias.so และให้ลบเครื่องหมาย # ด้านหน้าออก(ถ้ามี) อีกบรรทัดหนึ่งคือ Include conf/extra/httpd-vhosts.conf ถ้ามีเครื่องหมาย # ก็ให้ลบออกเช่นกัน เป็นอันเสร็จสิ้นขั้นตอนการเปิด modules ที่จำเป็นต้องใช้(ถ้าไม่ได้เปิดไว้ก่อน)

ก่อนไปถึงขั้นตอนต่อไปขออธิบายซักเล็กน้อย หลักจากที่เราทำการเปิดใช้ virtual host แล้ว และ IP ที่เรากำหนดให้ virtual host นั้นตรงกับ global host ที่มีอยู่ ตัว global host ที่เป็นตัวหลักซึ่งถูกเซตไว้ภายในไฟล์ httpd จะไม่สามารถใช้งานได้อีก ซึ่งตัว global host ตัวนี้นั้นจะถูกส่งให้ client เสมอในกรณีที่ไม่ตรงกับ virtual host ที่เรากำหนดไว้เลย ดังนั้นเราจะจำเป็นต้องเพิ่ม default virtual host ด้วย เพราะถ้าหากไม่มี virtual host ตัวไหนที่ตรงกับ request ที่เข้ามา virtual host ตัวแรกที่เรากำหนดไว้ จะถูกใช้ส่งให้นั้นเอง ดังนั้น default virtual host คือ virtual host ที่ถูกเพิ่มไว้ในอันดับแรก

ต่อไปให้เข้าไปที่ \apache2.4.9\conf\extra จากนั้นเปิดไฟล์ httpd-vhosts โดยใช้ text editor เพื่อเพิ่ม virtual host ด้วยการสร้าง  <VirtualHost> บล็อค โดยแต่ละบล็อคก็จะหมายถึงแต่ละ virtual host นั่นเอง เมื่อเปิดขึ้นมาจะมีตัวอย่างให้ดูตามนี้

httpd-vhost sample
\apache2.4.9\conf\extra\httpd-vhosts.conf

จากที่เห็น argument ของ <VirtualHost> เป็น “*:80” ใส่แบบนี้จะทำให้หลังจาก request เข้ามาแล้ว จะมองแต่ละบล็อคว่าสามารถเเป็น IP อะไรก็ได้ที่เรียกไปที่ port 80 ดังนั้น apache จะไปดูที่ ServerName แทนและดูที่ IP เพราะทุกบล็อคตอนนี้เป็น IP อะไรก็ได้แล้วนั่นเอง

ภายในบล็อค  <VirtualHost> คำสั่งที่จำเป็นจะต้องใส่มีเพียงแค่ 2 คำสั่งคือ ServerName ที่เอาไว้สำหรับบอก servername ของ virtual host กับ DocumentRoot เอาไว้ระบุ directory ของ virtual host นั้นเท่านั้น

จากด้านบนที่ผมอธิบายไปเรื่องที่ virtual host จะใช้งานไม่ได้ ดังนั้นเราจะต้องเพิ่ม default virtual host ก่อนเป็นอันดับแรก โดยผมจะตั้งเป็น localhost เหมือนเดิมก็จะได้ตามนี้

default virtual host
\apache2.4.9\conf\extra\httpd-vhosts.conf

อธิบายเพิ่มเติม ที่ผมเขียนเพียงแค่นี้ได้เพราะว่าที่ไฟล์ httpd ได้มี config ของ localhost อยู่แล้ว เช่น DocumentRoot, <Directory> ซึ่ง ServerName ที่ผมเขียนทับไปตรงนี้นั้นได้ override และใช้ค่าของ localhost เดิมที่ยังไม่มี config ใหม่มา override นั้นเอง

ตัวอย่างต่อไปเป็นการเพิ่ม virtual host ใหม่อีกอันหนึ่งโดยกำหนด ServerName เป็นตัวเดียวกันกับผมที่เขียนไว้ใน hosts ในขั้นตอนก่อนหน้า

sakura moe virtual host

เมื่อเพิ่มเสร็จแล้วให้ restart apache สำหรับผมจะลองเข้าไปที่ http://sakura.moe ดู ถ้าทำมาแค่นี้ก็จะเจอ

sakura 403 forbiden

อย่างที่เห็น apache แจ้งว่าเราไม่มีสิทธิ์ในการเข้าถึงไฟล์ การเพิ่ม permission ให้แต่ละ directory สามารถทำได้ผ่าน <Directory> บล็อคโดยสามารถใส่ไว้ได้ภายใน <VirtualHost> บล็อค โดยที่ config ต่างๆ ที่อยู่ภายใน <VirtualHost> จะจำกัดอยู่แค่บล็อคนั้นๆ ถึงแม้เราจะกำหนด argument ของ <Directory> ซึ่งเป็น directory path ที่ <VirtualHost> บล็อคอื่นใช้ด้วยก็ตาม แต่เราก็สามารถวาง <Directory> บล็อคไว้ภายในไฟล์ httpd และ config ต่างๆ จะถูกใช้งานกับทุก <VirtualHost> ที่ใช้ directory path เดียวกันเหมือนกัน สำหรับผมจะขอเลือกอย่างหลังคือใส่ไว้ภายในไฟล์ httpd โดยข้างล่างนี้เป็นตัวอย่าง เดี๋ยวผมจะอธิบายคำสั่งต่างๆ ภายในทีละอันครับ

directory vhost
\apache2.4.9\conf\httpd.conf

อย่างแรกคือ argument ของ <Directory> จะเป็น directory path จริงๆ แล้ว directory path สามารถใช้ได้ทั้ง back slash ซึ่งใช้บน windows หรือ forward slash เหมือนกับ Unix-like OS ก็ได้ แต่ถ้าเราจะใช้ back slash นั้นจำเป็นจะต้องใส่ double quote ครอบไว้ด้วย

Options ใช้กำหนดว่าจะมี features อะไรที่สามารถใช้ได้ใน directory นั้นได้บ้าง FollowSymLinks หมายถึง ถ้าลิ้งที่ถูกป้อนเข้ามาเป็น symbolic links ก็จะใช้ symbolic links นั้น ส่วน Indexes หมายถึง ถ้าภายใน DocumentRoot ไม่มีไฟล์ index อยู่เลย ก็จะแสดงภายใน directory นั้นเป็นหน้า index ออกมาแบบด้านล่างนี้

indexes
ตัวอย่างอันนี้ผมทำการเปลี่ยน DocumentRoot ไปที่อื่น

AllowOverride ใช้บอกว่า ถ้า server เจอไฟล์ .htaccess คำสั่งอะไรที่อยู่ภายใน .htaccess จะสามารถ override config ที่มีอยู่ก่อนได้บ้าง สุดท้ายคือ Require  ใช้สำหรับจำกัดว่าใครสามารถเข้าถึงไฟล์ได้บ้าง ซึ่งเมื่อเซตคำสั่งนี้เป็น  all granted แล้วทุกคนจะสามารถเข้าถึงไฟล์ได้  เมื่อเราเพิ่ม <Directory> เข้าไปที่ไฟล์ httpd เรียบร้อยแล้ว เราก็จะสามารถใช้งาน virtual host ที่เป็น name-based ของเราได้แล้ว

sakura moe complete

ทั้งหมดนี้ก็เป็นวิธีการเพิ่ม name-based virtual host เบื้องต้น ซึ่งจริงๆ แล้วผมศึกษามาจากที่นี่ทั้งหมดเลย ถ้าผมมีความรู้เพิ่มขึ้นจะมาอัพเดทให้อีกนะครับ สำหรับใครที่เข้ามาอ่านแล้วเห็นว่ามีตรงไหนที่ผมอธิบายไว้ผิดพลาดตรงไหน ก่อนจะเอาไปเม้าว่าผมเขียนมั่ว ช่วยเขียนแนะนำไว้ให้ผมด้วยครับ เพราะผมจะได้มีความรู้ด้วย TwT

วิธี JailBreak และเปลี่ยน ScreenSavers Kindle Paperwhite

JailBreak Kindle PaperWhite(KT, PW, PW2, KV, PW3)

สำหรับเครื่องที่ไม่เคย JailBreak มาก่อน

  • JailBreak Firmware version ได้ตั้งแต่ 5.0.x ถึง 5.4.4.2 เท่านั้น
  • เครื่องที่ FW >= 5.4.5 ไม่สามารถ JailBreak แบบปกติได้ ยกเว้น
  • เครื่องที่ FW ไม่ >= 5.7.2 สามารถลง FW 5.6.5 และ JailBreak ได้โดยใช้วิธีคนละแบบกัน
  • PW2 ที่ FW >= 5.4.5 แต่ < 5.5.0 สามารถ downgrade ไปเป็น version 5.4.3.2 ได้
  • แม้แต่ PW3 ซึ่งเป็นรุ่นใหม่ล่าสุด ก็ยังไม่ได้ขายมาพร้อมกับ FW >= 5.7.2 ดังนั้นสามารถใช้วิธีพิเศษสำหรับ 5.6.5 ได้

สำหรับเครื่องที่ต้องการอัปเดท JailBreak

  • FW 5.0.x ถึง 5.4.4.2 อัปเดทได้ด้วยวิธีถอนการติดตั้ง
  • FW >= 5.4.5 อัปเดทด้วยวิธีลง bridge
  • FW >= 5.6.x อัปเดทด้วยวิธีปกติไม่ได้ ต้องติดตั้ง update package ต้องติดตั้งด้วย MRPI (เป็น KUAL extension; ต้องติดตั้ง KUAL ก่อน)เท่านั้น

สำหรับเครื่องที่ JailBreak แล้วและต้องการอัปเดท FW Kindle

  • JailBreak จะยังคงอยู่แม้ Firmware >= 5.4.5  แต่ต้องทำการอัปเดท JailBreak เป็นเวอร์ชั่นล่าสุดก่อน
  • FW >= 5.6.x จะไม่สามารถ downgrade FW ได้โดยง่ายอีกต่อไป และจะไม่สามารถติดตั้ง update package (หมายถึงไฟล์ .bin) ได้อีกต่อไป ถ้าจะติดตั้ง update package ต้องติดตั้งด้วย MRPI (เป็น KUAL extension; ต้องติดตั้ง KUAL ก่อน)เท่านั้น
JailBreak เวอร์ชั่นปัจจุบัน (วันที่ 18/2/2016) คือ v1.14.N ดาวน์โหลดไฟล์ kindle-jailbreak-1.14.N ได้จากด้านล่างของโพส 1 ที่นี่ หลังจาก unzip ออกมาแล้ว ไฟล์ภายในที่สำคัญในที่นี้

kindle-5.4-jailbreak.zip

Update_jailbreak_1.14.N_uninstall.bin

Update_jailbreak_bridge_1.14.N_install.bin

วิธีติดตั้ง JailBreak แบบปกติ(สำหรับ FW 5.0.x ถึง 5.4.4.2 เท่านั้น)

  1. upzip ไฟล์ kindle-5.4-jailbreak.zip และนำไฟล์ที่ได้มาทั้งหมดไปวางไว้ใน kindle (root directory – ด้านนอกสุด)
  2. ไปที่เมนู [HOME] -> [MENU] > Settings -> [MENU] > Update Your Kindle หลังจากนี้จะไม่มีการอัปเดทใดๆ ทั้งสิ้น และไม่กี่วินาทีจากนี้จะมีคำว่า “**** JAILBREAK ****” ขึ้นที่ด้านของจอ เป็นอันเสร็จสิ้น

วิธีติดตั้ง JailBreak สำหรับ FW 6.5.6 เท่านั้น

  1. ดาวน์โหลด jb.zip จากที่นี่
  2. upzip ไฟล์ jb.zip จากนั้นนำไฟล์ jb ไปไว้ใน kindle (root directory – ด้านนอกสุด)
  3. ต่อ internet ใน kindle จากนั้นเข้าเว็บเบราว์เซอร์แล้วเข้าเว็บ kindlefere.com/jb/
  4. ทำตามคำแนะนำ เมื่อได้รับแจ้งจาก notification bar ว่าให้รัน fc-cache ในช่องค้นหา ให้เปิด Kindle search แล้วพิมพ์ fc-cache ในช่องค้นหา
  5. เมื่อได้รับการแจ้งเตือนว่าเสร็จแล้ว ให้ไปโหลดไฟล์ JailBreak-1.14.N-FW-5.x-hotfix.zip จากที่นี่
  6. unzip ไฟล์ JailBreak-1.14.N-FW-5.x-hotfix.zip และนำไฟล์ Update_jailbreak_1.14.N_install.bin ที่ได้มาไปวางไว้ใน Kindle (root directory – ด้านนอกสุด)
  7. ไปที่เมนู [HOME] -> [MENU] > Settings -> [MENU] > Update Your Kindle แล้วรอจนเสร็จ

วิธีอัปเดท JailBreak สำหรับ FW 5.0.x ถึง 5.4.4.2

  1. วางไฟล์ Update_jailbreak_1.14.N_uninstall.bin ไว้ใน Kindle (root directory – ด้านนอกสุด)
  2. [HOME] -> [MENU] > Settings -> [MENU] > Update Your Kindle แล้วรอจนเสร็จ

วิธีอัปเดท JailBreak สำหรับ FW >= 5.4.5

  1. วางไฟล์ Update_jailbreak_bridge_1.14.N_install.bin ไว้ใน Kindle (root directory – ด้านนอกสุด)
  2. [HOME] -> [MENU] > Settings -> [MENU] > Update Your Kindle แล้วรอจนเสร็จ

วิธีติดตั้ง custom package ทั่วไป

วิธีการติดตั้ง custom package (หมายถึงไฟล์ .bin ทั่วไป) สำหรับ FW < 5.5.x

ถ้าได้อ่านวิธีข้างบนทั้งหมดจะเห็นว่า วิธีการติดตั้ง custom package รวมทั้ง official package ซึ่งทั้งหมดเป็นไฟล์ .bin จะเหมือนกันทั้งหมดคือ

  1. นำไฟล์ที่ต้องการติดตั้งไปไว้ใน Kindle (root directory – ด้านนอกสุด)
  2. เข้าเมนู [HOME] -> [MENU] > Settings -> [MENU] > Update Your Kindle
  3. วิธีนี้ติดตั้งได้ทีละ package

วิธีการติดตั้ง custom package (หมายถึงไฟล์ .bin ทั่วไป) สำหรับ FW >= 5.5.x ด้วย MRPI

จำเป็นต้อง JailBreak มาก่อนแล้ว ไม่ว่าจะ JailBreak มาก่อนเวอร์ชั่น 5.5.x แล้วอัปเดท FW ขึ้นมา หรือ JailBreak ที่ FW เวอร์ชั่น 6.5.6

  1. ติดตั้ง KUAL ก่อน ดาวน์โหลด KUAL-v2.6.zip ที่ท้ายโพสแรก
  2. unzip ไฟล์ KUAL-v2.6.zip แล้วนำไฟล์ KUAL-KDK-2.0.azw2 ไปไว้ใน folder documents ของ kindle เป็นอันเสร็จการติดตั้ง KUAL สามารถเข้าได้เหมือนอ่านหนังสือ สามารถดูรูปได้จากกระทู้ที่โหลด
  3. ติดตั้ง MRPI ซึ่งเป็นส่วนขยายของ KUAL ด้วยการไปดาวน์โหลด kual-mrinstaller-1.6.N.zip จากโพสแรก
  4. unzip ไฟล์ kual-mrinstaller-1.6.N.zip แล้ว นำไฟล์ทั้งหมดที่ได้ไปวางไว้ใน kindle ไฟล์ที่ได้ประกอบด้วย folder extensions (ข้างในมี folder MRInstaller) และ folder mrpackages
  5. เมื่อต้องการติดตั้ง custom package ใดๆ ให้เราเอาไปวางไว้ใน kindle จากนั้นเข้า KUAL > Helper > Install MR Packages หลังจากเลือกเมนูนี้แล้ว เราจะออกมาที่หน้า Home และจะมีข้อความเกี่ยวกับการติดตั้งแสดงที่ด้านล่างของจอ เป็นอันเสร็จสิ้น
  6. วิธีนี้สามารถลง custom package หลายอันพร้อมกันได้

ScreenSavers Hack

โหลดได้จากด้านล่างของโพสแรกที่ FW 5.x ScreenSavers Hack สิ่งที่ต้องโหลดคือ

  1. kindle-python-0.14.N-touch_pw1.zip สำหรับ KT และ PW1 หรือ kindle-python-0.14.N-pw2_kt2_kv_pw3.zip สำหรับ KT2, PW2, KV, PW3
  2. kindle-linkss-0.24.N.zip (แตกไฟล์มาแล้ว ข้างในจะมีไฟล์ สำหรับรุ่น KT, PW1 หรืออีกไฟล์ทีเหลือสำหรับ KT2, PW2, KV, PW3)

ต่อไปแตกไฟล์ที่ดาวน์โหลดมา แล้วลงตามวิธีด้านบน (ถ้าใช้ MRPI สามารถติดตั้งพร้อมกันทั้ง 2 อันได้) หลังจากลงทั้ง 2 อันเสร็จ ถ้าเราลองกด sleep ดูจะขึ้นหน้ายืนยันว่าติดตั้งเสร็จเรียบร้อยเป็นหน้า ScreenSavers ดังภาพ

change screensaver

การทำงานของ ScreenSavers Hack มี โหมด ได้แก่

  • cover ใช้หน้าปกหนังสือเล่มล่าสุดที่อ่านมาแสดง
  • last ใช้สิ่งสุดท้ายที่อยู่บนหน้าจอแสดง (ถ้าเปิดโหมด cover กับ last พร้อมกัน kindle จะเลือก cover ก่อน)
  • autoreboot ไม่เกี่ยวกับ screensavers ทำให้ kindle restart ทุกครั้งเมื่อถอดสาย USB เวลาต่อกับคอม ต้องใช้คู่กับโหมด auto
  • random จะแสดง screensaver ที่เพิ่มเข้าไปตาม “ลำดับ” และ “ลำดับ” จะถูกสุ่มจัดใหม่ทุกครั้งที่ kindle restart
  • shuffle จะแสดง screensaver ที่เพิ่มเข้าไปตาม “ลำดับ” และ “ลำดับ” จะถูกสุ่มใหม่ทุกครั้งที่ framework restart (ผ่านการ restart, autoreboot)

วิธีเลือกโหมดคือ ให้สร้างไฟล์เปล่าขึ้นมา แล้วตั้งชื่อตามโหมดที่ต้องการ แล้ววางไว้ใน folder linkss ใน kindle (ปกติจะมีไฟล์เปล่าวางไว้อยู่ในนั้นอยู่แล้ว ให้คัดลอกแล้ววางจากนั้นเปลี่ยนชื่อ) สำหรับภาพ ให้นำไปวางไว้ใน linkss/screensavers คุณสมบัติไฟล์ดังนี้

  • KT/KT2 ขนาด 600x800px
  • PW/PW2 ขนาด 758x1024px
  • KV/PW3 ขนาด 1072×1448

และต้องเป็นไฟล์ .png และเป็นภาพขาวดำ(ภาพสีก็ได้) ถ้าไม่ได้ใช้ไฟล์ .png kindle จะมองไม่เห็น และถ้าใช้ขนาดไม่ถูกต้องอาจจะทำให้เกิดปัญหาได้

การอ่านค่า crosstab แบบง่ายๆ

บทความนี้ขอเขียนถึงการอ่านค่า crosstab ซักหน่อยกันลืม เนื่องจากว่าเพิ่งมาเข้าใจในตอนที่สอบเรื่องนี้อยู่พอดี เลยขอเขียนกันลืมไว้ซักหน่อยแล้วกัน อนึ่งความรู้เกี่ยวกับสถิติของผมนั้นมีน้อยมากใช้โปรแกรมเป็นกับสามารถทำโจทย์ที่เขาให้มาได้เท่านั้น ดังนั้นถ้าผิดพลาดอะไรก็ขออภัยนะครับ

ตาราง crosstab ในโปรแกรม spss นั้นอธิบายง่ายๆ จะเป็นตารางที่แสดงค่าตัวแปรๆ นึงโดยจัดหมวดหมู่หรือจะเรียกว่าแบ่งตามอะไรก็ได้ที่เราต้องการ

crosstab1

จากหน้าต่างข้างบนนี้ผมต้องการแสดงให้แถวแสดงค่าที่ผมต้องการเปรียบเทียบและเพศไว้ในคอลัมน์เพื่อเป็นตัวแบ่งแยก ซึ่งข้อมูลจากตารางที่ได้จะเป็นค่าต่างๆ ในตัวแปร “อ่านเฉลี่ยนกี่ชั่วโมง” โดยแยกตามเพศ

crosstab2

ต่อมาใน option cell ตรงส่วน percentages จะเป็นการกำหนดค่าว่าจะให้เราคิดเปอร์เซ็นจากอะไร ในที่นี้ขอคิดเปอร์เซ็นจาก column(ตอนนี้คือเพศ) เพราะเราจะแยกค่าต่างๆ ตามเพศ ดังนั้นเราก็ต้องคิดค่าเปอร์เซ็นต่างๆ ตามเพศเช่นกัน

crosstab3

 

ข้างบนนี้เป็นตารางที่ได้มา จากตารางนี้บอกอะไรเราได้บ้าง(ตารางนี้ดูขำๆ เพราะสำรวจเพศชายกับเพศหญิงมาไม่เท่ากัน)

เพศชายอ่านข่าวสารต่อวันมากกว่าผู้หญิง สังเกตุได้จากช่อง 3 ชั่วโมงขึ้นไป มีเพศชายจำนวน 8 คน คิด 13.6% จากจำนวนผู้ชายทั้งหมด ต่อไปทั้งผู้ชายและผู้หญิงอ่านข่าวไม่เกิน 1 ชั่วโมงเท่ากัน คือมีจำนวน 24 คน โดยคิดเป็น 40.7% สำหรับผู้ชาย และ 58.5% สำหรับผู้หญิงและ เพศชายอ่านข่าว 1-2 ชั่วโมงมากกว่าผู้หญิงสังเกตุจากช่อง 1-2 ชั่วโมง โดยผู้ชายอ่าน 20 คน คิดเป็น 33.9% จากเพศชายทั้งหมดและเพศหญิงอ่าน 13 คนคิดเป็น 31.7% จากเพศหญิงทั้งหมด และสุดท้ายเพศชายอ่านข่าว 2-3 ชั่วโมงมากกว่าเพศหญิง สังเกตุจากช่อง 2-3 ชั่วโมง โดยเพศชายอ่าน 7 คน คิดเป็น 11.9% จากเพศชายทั้งหมด และเพศหญิงอ่าน 4 คนคิดเป็น 9.8% ของเพศหญิงทั้งหมด

ทั้งหมดนี้ก็เป็นวิธีอ่านแบบคราวๆ ในภาษาปาก ที่เหลือต้องไปประยุกต์การอ่านเอาเองและ ขอจบแค่นี้สำหรับการอ่านค่า crosstab ครับ

แก้ปัญหาปริ้นงานไม่ได้

พอดีวันนี้ได้มีโอกาสไปแก้เครื่องปริ้นของเพื่อนที่ไม่สามารถปริ้นได้มาเลยขอมาเล่าถึงปัญหาและวิธีการแก้ซักหน่อยแล้วกัน

สำหรับอาการปริ้นเตอร์ที่ปริ้นไม่ได้ในที่นี้ ไม่ได้หมายถึงสั่งปริ้นแล้วกระดาษไม่ออกคือเครื่องปริ้นยังทำงานเป็นปกติ เช็คดูใน device manager แล้วก็ปรกติดี แต่เวลาสั่งเราจะไม่สามารถเรียนกหน้าที่ใช้ปริ้นขึ้นมาได้เลย แม้จะสั่งปริ้นจากเว็บ(ทดลองด้วย google chrome)ก็จะเป็นการเซฟเป็นไฟล์แทน โดยสรุปคือสั่งปริ้นไม่ได้จาก windows ด้วยทุกๆ โปรแกรมโดยที่เครื่องปริ้นไม่ได้เสียนั่นเอง ส่วนตอนผมทำนั้นกว่าจะรู้ว่ามันเป็นเพราะอะไรก็ไปทำอะไรยุ่งยากแทบตาย ดังนั้นผมจะขอเขียนวิธีเช็คและไล่ปัญหารวมๆ ไปเลยแล้วกันนะครับ

  1. เข้าไปเช็คที่หน้า services ของ windows ก่อนครับ win 7 ให้พิมพ์ service ที่ช่อง search ส่วน win 8 ง่ายๆ ก็เข้า task manager เสร็จแล้วไปที่แท็บ service ที่ด้านล่างๆ ให้กด open services
  2. หลังจากนั้นให้มองหา service ที่ชื่อ Print Spooler ครับ คลิกเข้าไปจากนั้นดูตรง service status ถ้ามัน stopped ให้กด start มัน แล้วอย่าลืมดูตรง startup type ด้วยว่าเป็น automatic หรือเปล่า ถ้าไม่ใช่ให้เปลี่ยนเป็น automatic ด้วย
  3. ถ้ากด start แล้วมัน ขึ้น error มา(Print Spooler Error 1068 – The Dependency Service Can’t Start)ให้ดูที่ service Remote Procedure Call (RPC) มันมันรันอยู่หรือเปล่าถ้ามันรันอยู่แล้วยังเปิด Print Spooler ไม่ได้อีกให้ไปขั้นตอนต่อไป
  4. เข้าไปหน้า registry editor สำหรับ win 7 ให้พิมพ์ regedit ที่ช่อง search ส่วน win 8 ก็ให้พิมพ์ใน start จะอยู่ใน app
  5. เข้าไปที่ HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Spooler ที่ช่องทางด้านขวา ให้คลิกเข้าไปดูค่าของ DepenOnService ซึ่งมันควรจะมีแค่ RPCSS เขียนไว้ แต่ถ้ามีอะไรอย่างอื่นก็ตามแต่ให้ลบทิ้งเหลือไว้แต่ RPCSS เป็นพอ เสร็จแล้ว restart เครื่อง ถ้าเราตั้ง startup type ไว้เป็น automatic แล้ว เมื่อรีเครื่องมาน่าจะ service น่าจะ start ให้เป็นปรกติแล้วและทำให้เราสามารถปริ้นงานได้ ถ้ายังไม่ได้อีก แนะนำให้ลงลบ driver เครื่องปริ้นทิ้งให้หมดแล้วลองดุใหม่ นอกเหนือจากนี้ ไม่รู้แล้วคร้าบบบบบ xD

อธิบายเพิ่มเต็มเล็กน้อย service ที่ชื่อ spoolsv(Print Spooler) นั้นใช้เชื่อมต่อสื่อสารระหว่างคอมและปริ้นเตอร์และสาเหตุที่ทำให้ registry ถูกแก้เพิ่มเติมอะไรเข้าไปนั้นผมขอเดาว่าเป็นเพราะไวรัสที่อาศัย service นี้ทำงาน และที่ service มันทำงานไม่ได้ก็เป็นเพราะว่ามันรันตัว service ที่แฝงมาด้วยไม่ครบ(Print Spooler Error 1068 – The Dependency Service Can’t Start) เลยทำงานไมได้ครับ เมื่อ service spoolsv ทำงานไม่ได้จึงส่งผลให้ปริ้นงานไม่ได้ครับ