สวัสดีคร๊าบบบบ ขณะนี้เป็นเวลา 5 ทุ่มกว่า ๆ ของวันสุดท้ายในปี 2561 และนี่คงเป็น Blog สุดท้ายของปีแล้ว มีเรื่องน่าสนใจมาเขียนให้ชาว Dev ได้อ่านกัน
เรื่องมันเกิดจากที่เมื่อหลายเดือนก่อน ผมได้ใช้งาน App นึงที่ติดตั้งอยู่บน macOS ที่ใช้งานอยู่ และครั้งนึง เคยกด Link จาก Web แล้วพบว่า สามารถเปิด App นั้นขึ้นมาได้ และไปยังหน้าที่ต้องการได้เลย
ด้วยความอยากรู้อยากเห็น ก็เลยแงะเว็บนั้นดู (นานเกิน จำไม่ได้ละว่าเว็บไหน) และพบว่า มันใช้ท่าของ URI Scheme นั่นเอง และภาพของ line:// เอย market:// เอย ก็ลอยขึ้นมา รวมถึง Deep Link ของฝั่ง Android ก็ใช้ท่านี้เหมือนกัน
และด้วยงานในช่วงนี้ ต้องพัฒนา Windows App ขึ้นมาตัวนึง ที่สามารถเรียกใช้งานผ่าน Web App ได้ ก็เลยนึกถึงเรื่องนี้ขึ้นมา ก็เลยลอง Research ดู พบว่า น่าสนใจดี เลยหยิบมาเขียน Blog เล่าให้ฟังกันหน่อย
ทำความรู้จักกับ URI Scheme
ก่อนอื่น มาทำความรู้จักกับ URI Scheme กันซักหน่อย
URI ย่อมาจาก Uniform Resource Identifier ซึ่งจะมี Scheme เป็นส่วนประกอบชิ้นแรก ซึ่งจะเป็นคำ และตามด้วยเครื่องหมาย :
เสมอ ยกตัวอย่างเช่น http:
, https:
, mailto:
เป็นต้น
คงไม่มีอะไรที่อธิบายคำว่า URI และ Scheme ได้ดีเท่ากับรูปนี้อีกแล้ว

จาก https://en.wikipedia.org/wiki/Uniform_Resource_Identifier
URI Scheme กับ Microsoft Windows
จากที่เกริ่นมาข้างต้น สำหรับ Blog วันนี้ ก็เลยจะพูดถึงเฉพาะฝั่ง Microsoft Windows เท่านั้น
จุดที่เป็นไคลแมคเลยอยู่ที่ Registry ครับ ก่อนอื่นเลย ลองสร้างไฟล์ NotepadRegistry.reg ดังนี้
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\Notepad] @="URL:Notepad Protocol" "URL Protocol"="" [HKEY_CLASSES_ROOT\Notepad\DefaultIcon] @="C:\\Windows\\System32\\notepad.exe,1" [HKEY_CLASSES_ROOT\Notepad\shell] [HKEY_CLASSES_ROOT\Notepad\shell\open] [HKEY_CLASSES_ROOT\Notepad\shell\open\command] @="\"C:\\Windows\\System32\\notepad.exe\"" |
เสร็จแล้ว เซฟให้เรียบร้อย แล้วดับเบิ้ลคลิกไฟล์ เพื่อนำค่า Registry ในไฟล์ ไปเพิ่มใน Registry ของ Windows เราเลย
หลังจากนั้น ลองเปิด Registry Editor ดู และเปิดเข้าไปที่ Computer\HKEY_CLASSES_ROOT
ก็จะพบ Notepad ที่เราเพิ่งเพิ่มเข้าไปจากไฟล์ข้างบน

ตอนนี้เราก็จะมี Notepad Scheme แล้วครับ ลองเรียกผ่าน Browser อะไรก็ได้ ด้วย URI ว่า notepad:blank
ดู ก็จะพบกับ Dialog ให้เรายืนยัน (แต่ละ Browser มี Dialog ไม่เหมือนกัน)

เมื่อยืนยันแล้ว Browser จะทำการเปิด Notepad ขึ้นมาให้ ซึ่งก็คือการรันคำสั่ง ที่ประกาศอยู่ใน HKEY_CLASSES_ROOT\Notepad\shell\open\command
นั่นเอง
ได้เวลาเขียนโปรแกรม
เมื่อเราเข้าใจหลักการทำงานข้างต้นแล้ว หลาย ๆ คนก็น่าจะร้องอ๋อกันละ ก็ไม่มีอะไรซับซ้อนครับ เพียงแค่เราทำยังไงก็ได้ ให้มี Registry เกิดขึ้นใน Windows ตามรูปแบบด้านบน ก็สามารถเรียก App เราผ่านเว็บได้แล้ว
สำหรับ C# นั้น ก็จะเขียน Code ประมาณนี้
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
string uriSchemeName = "Demo"; using (var key = Registry.CurrentUser.CreateSubKey(string.Format(@"SOFTWARE\Classes\{0}", uriSchemeName))) { key.SetValue("", string.Format("URL:{0} Protocol", uriSchemeName)); key.SetValue("URL Protocol", ""); using (var defaultIcon = key.CreateSubKey("DefaultIcon")) { defaultIcon.SetValue("", string.Format("{0},1", Application.ExecutablePath)); } using (var commandKey = key.CreateSubKey(@"shell\open\command")) { commandKey.SetValue("", string.Format("\"{0}\" \"%1\"", Application.ExecutablePath)); } } |
เมื่อ Code ชุดนี้ถูกรัน ก็จะเป็นการเพิ่ม Registry ด้วยชื่อ Scheme ตามที่ประกาศไว้ในตัวแปร uriSchemeName
และกำหนดที่อยู่ของโปรแกรมเราให้เลย เสมือนเรา Register Scheme ของเรา กับ OS เรียบร้อย หลังจากนั้นก็สามารถเรียกผ่าน Browser ได้แล้ว

ซึ่งบางครั้ง เราอาจจะต้องการทราบว่า โปรแกรมถูกเรียกใช้งานปกติ หรือเรียกผ่าน URI Scheme มา เราสามารถแยกแยะได้ ผ่านทางสิ่งที่เรียกว่า Command Line Argument ดังนี้
1 |
string[] args = Environment.GetCommandLineArgs(); |
Code ด้านบน จะได้ค่า Command Line Argument ซึ่งจะ Return เป็น Array ที่มีขนาดอย่างน้อย 1 ช่องเสมอ โดยช่องแรก จะเป็นที่อยู่ของโปรแกรมเรา หากเรียกใช้งานปกติ ก็จะมีเพียงเท่านี้
หากเรียกผ่าน URI Scheme ก็จะได้ค่า Argument ตัวนี้ 2 มาให้เราได้ตรวจสอบกัน
รูปด้านล่าง ผมทำการอ่านค่า Command Line Argument ทั้งหมด และแสดงออกมาบน Windows Form บรรทัดละตัว

จะเห็นว่า เราสามารถส่งข้อมูลอะไรก็ได้ ผ่านทาง URI เข้ามาที่ App ได้ด้วย ต่อจากนี้ ก็เป็นหน้าที่ของ App ที่นำข้อมูลไปตัดสินใจว่าจะทำอะไรต่อ…
เขียนเว็บมาเรียกยังไง
สำหรับการเขียนเว็บมาเรียก จะใช้วิธีไหนก็ได้ ที่สามารถเปลี่ยน Address Location ของ Browser ได้ เช่นคำสั่ง JavaScript ดังนี้
1 |
location.href = 'demo:Launch app from JavaScript' |
หรือจะ HTML Hyperlink ธรรมดา ๆ ก็ยังได้
1 |
<a href="demo:Launch app from HTML">Launch app</a> |
ข้อจำกัด
เนื่องจากการสื่อสารระหว่าง Web กับ App เป็นลักษณะ One way และการเรียกใช้งานนั้น จะไม่สามารถทราบผลการรันได้เลย เพราะเป็นงานที่ Browser รับไปทำต่อ จึงไม่สามารถสื่อสารกันได้โดยตรง
หาก Web ต้องการทราบว่า App รันเรียบร้อยหรือยัง หรือว่า App ต้องการสื่อสารบางอย่างกลับมายังเว็บ คงต้องออกแบบส่วนของ Back-end ให้ทั้ง Web และ App สื่อสารกันทางอ้อม
ทิ้งท้าย
สำหรับบทความนี้ เนื้อหาก็สั้น ๆ เพียงเท่านี้ สำหรับฝั่ง macOS ถ้าใครทราบ ว่า Register Scheme ยังไง Comment บอกกันซักนิดนึงนะครับ
และ Code ในตัวอย่าง รวมถึง Registry file ผมได้นำขึ้น GitHub ไว้ให้ศึกษากัน ที่นี่นะ
ส่วนถ้าใครอยากรู้ว่า มี Scheme อะไรที่ใช้งานกันอยู่บ้าง ลองดูที่ Uniform Resource Identifier (URI) Schemes ได้เลย
และสุดท้าย ท้ายสุด ขอกล่าวคำว่า…
“สวัสดีปีใหม่” คร๊าบบบบบบบบ
Permalink
การสื่อสารระหว่าง winform กับ web
น่าจะใช้พวกฐานข้อมูล nosql ที่ต้องสอบการเปลี่ยได้มาช่วยได้นะครับ
เช่น couchbase
Permalink
ไอ้คิ้ว ไม่รู้มึงจำกูได้เปล่า ตอน ม.1/2 ห้องเล้าไก่อะ 5 5 5
คิดถึงมึงวะ
Permalink
จำได้ซิ ชื่อเมิงโคตรจะเด่น
ขอ contact ช่องทางอื่นหน่อย จะได้คุยกัน