‏הצגת רשומות עם תוויות Tools. הצג את כל הרשומות
‏הצגת רשומות עם תוויות Tools. הצג את כל הרשומות

יום שני, 27 בינואר 2014

C# Reflection Guide



אחד התחומים המעניינים בפיתוח, האפשרות לתוכנית ללמוד על עצמה תוך כדי ריצה מאפשרת לפתח תוכניות מיוחדות במיוחד, האמת שנושא ה Reflection ישן והוא קיים עוד מתחילת ה Framework הראשון אבל אף פעם לא התייחסתי אליו כי בדרך כלל אין בו צורך, לרוב אנחנו יודעים מה אנחנו הולכים לפתח אבל קיימים מקרים מסויימים בהם יש חור שחור ואין לנו מספיק מידע ולכן עלינו לשמור על קוד גנרי ככל האפשר.

Reflection

יכולת של תוכנית לזהות במהלך הריצה את האובייקטים שרצים בה, לנתח אותם ולהפעיל בהם פונקציות באופן דינמי לפי סוג האובייקט או על פי קונבנציה קבועה, במאמר זה אני יעבור על נושא ה Reflection בסביבת .Net אבל היכולת הזאת נתמכת גם בסביבות נוספות כמו JavaScript, C++,Phyton וכו', הרעיון המרכזי הוא להפוך את התוכנית ל"שקופה" ושתוכל להתמודד עם אובייקטים שונים מבלי לעבור Compile כל פעם מחדש.

לצורך הדוגמה בניתי תוכנית והיא מאפשרת למשתמשים ליצור עבורה Plugins מיוחדים, מהרגע שהכנסתי את התכונה הזאת אני לא יודע מה המשתמש יעשה (האמת שזה לא כלכך צריך לעניין אותי), ואני לא יכול לעשות Compile לתוכנית המקורית כל פעם מחדש כי זה יהיה מגוחך, כאן נכנס ה Reflection לתמונה שבעזרתו אני יכול להגדיר קונבנציה עבור טעינת Plugin כחלק מה SDK של התוכנית, משתמש הקצה מייצר אובייקט שמכיל בתוכו קריאות לפונקציות שנקבעו מראש שמטרתם לחבר בין התוכנית לקוד שהמשתמש יצר, ברגע שמופעלת הפונקציה הקוד של המשתמש רץ מבלי שהיה חלק מהתוכנית עצמה כפי שניתן לראות בקוד הבא:

public class example
    {
        //private string
        private string msg0 = "this is exmaple of private string!";

        //public string
        public string msg1 = "this is exmaple of public string!";

        //constructor
        public example()
        {

        }

        //public function for invoke return string
        public string returnPrivateMessage()
        {
            return msg0;
        }

        //public function for invoke getting external 
        //parameter and return string
        public string returnEditMessage(string msg)
        {
            return "you write: " + msg;
        }
    }


המשתמש עוטף את המחלקה כ DLL ומעתיק אותה לתיקיית Plugin בתוכנית,התוכנית טוענת אותו לזיכרון ומחפשת את הפונקציה שנקבעה מראש על מנת להפעיל אותה ובעצם מעבירה את הריצה ל DLL מבלי לדעת מה בדיוק עומד לקרות שם.


class Program
    {
        static void Main(string[] args)
        {
            //load assmbly dynamically
            Assembly assemblyInstance = Assembly.LoadFrom(@"C:\\RefDLL.dll");

            Type[] types = assemblyInstance.GetTypes();

            for (int i = 0; i < types.Length; i++)
            {
                //search for specific type
                if (types[i].Name.ToLower() == "example")
                {
                    MethodInfo[] methods = types[i].GetMethods();
                    if (methods != null)
                    {
                        for (int z = 0; z < methods.Length; z++)
                        {
                            //search for specific method
                            if (methods[z].Name == "returnPrivateMessage")
                            {
                                //create instance for dynamic object
                                object classInstance = Activator.CreateInstance(types[i], null);

                                //execute method and gettig string
                                object res = methods[z].Invoke(classInstance, new object[0]);

                            }

                            if (methods[z].Name == "returnEditMessage")
                            {
                                //create parameters array for function,
                                //you can get the types of the arguments using
                                //ParameterInfo[] parameters = methods[z].GetParameters();
                                object[] parametersArray = new object[] { "my information!" };
                                object classInstance = Activator.CreateInstance(types[i], null);

                                object res = methods[z].Invoke(classInstance, parametersArray);
                            }
                        }
                    }
                }
            }

        }
    }



ראינו כיצד ניתן להפוך את התוכנית למשהו גנרי אבל מצד שני הקוד שלנו חשוף וכל אחד יכול להפעיל אותו, הצגתי בעבר כיצד ניתן לעשות Disassembly לקבצי DLL שנוצרו ב .Net וה Reflection לוקח חלק חשוב בתהליך, לסיום החלטתי שזו הזדמנות טובה להראות את היכולות של ה Reflection בעזרת כלי קטן שמאפשר לנתח קבצי DLL בצורה נוחה ומהירה, בדומה לדוגמה הקודמת התוכנית מקבלת נתיב ל DLL ופורסת אותו, היא מראה את הפונקציות, המשתנים והאירועים של האובייקטים בקובץ.

DLLReflector


סיכום:

אז כמו שכבר אמרתי בהתחלה בדרך כלל לא נמצא ל Reflection שימוש אלא במקרים מאוד מסויימים, ההתעסקות בניתוח האובייקט עלולה להפוך את התוכנית למסורבלת ואיטית ולכן כדאי לחשוב פעמיים לפני שבוחרים בדרך הזאת, אבל אין ספק שזה לוקח את האינטליגנציה של התוכנה צעד אחד קדימה.

קוד להורדה:


סקיינט?



יום שבת, 1 בדצמבר 2012

Process Network Analyzer .Net


דמיינו מצב שאתם מנהלים שרת אינטרנט וההייתם רוצים לדעת כמה משתמשים יש על השרת באותו רגע, וכמובן באיזה שירותים הם משתמשים, אחת הדרכים הנפוצות לעשות זו היא בעזרת שימוש בכלים קיימים ב Windows כמו ה Task Manager ו NetStat אבל זה תהליך מסורבל ומבלבל (נעבור עליו מיד) , חשבתי לעצמי איך ניתן לכתוב כלי כזה בעצמי ממקום להתחיל להתערבב עם הכלים ולזכור כל מיני מספרים...

השיטה הקלאסית:

נפעיל את חברנו הטוב - Task Manager.


חשוב לזכור שבהגדרות ה Default של טבלת ה Task Manager לא מופיעה העמודה של ה PID - Process Identifier שהיא חשובה לנו בהמשך, על מנת להפעיל את העמודה יש ללחוץ על View -> Select Columns ולסמן את ה CheckBox.


לאחר מכן נפתח Cmd ונרשום netstat -n -a -o ונקבל את רשימת החיבורים הפעילים שבמחשב ובנוסף ה PID של ה Process שאליו קשור החיבור.


עכשיו נקשר בין ה PID שמופיע ב NetStat לבין ה PID שמופיע ב Task Manager  ונדע כמה חיבורים יש לכל Process וכבר אפשר לראות שזה ממש לא נוח וצריכים כלי שיעשה זאת בשבילנו.

Process Analyzer

בסה"כ מדובר על כלי מאוד פשוט, קיימות מחלקות מוכנות ב .Net לניהול Processes שבעזרתם נקבל את רשימת ה Processes שרצים על המערכת, החלק היותר בעייתי איך מוצאים את כל החיבורים עבור כל Process, בעזרת Invoke (קריאה) ל פונקציות ומבנים ב Api נמצא את מה שאנחנו צריכים, אבל זה קצת טריקי, קיימת בעייה לגשת מתוכנית .Net שמוגדרת Managed Code לפונקציות API של Windows שמוגדרים כ UnManaged Code, אתר Pinvoke מכיל חתימות ידועות של פונקציות ב API של Windows שמאפשר לקרוא לפונקציה ישירות מ Net.

יש 2 פונקציות מרכזיות שאותן צריך להפעיל ב API של Windows הראשונה GetExtendedTcpTable והשנייה GetExtendedUdpTable, כל אחת מהפונקציות עובדת עם מבנים קבועים לצורך הדוגמה הפונקציה GetExtendedTcpTable צריכה לקבל מבנים מסוג MIB  שמיוחסים לפרוטוקול TCP כמו MIB_TCPROW_OWNER_PID MIB_TCPROW, MIB_TCPTABLE_OWNER_PID וכו',  בסיום הפונקציה מתמלא Buffer של טבלת החיבורים הפעילים וחוזר Pointer לאותו Buffer, מסביב כל פונקציה יש מעטפת שמכילה בתוכה את כל המבנים הדרושים.

tcpTavble.cs - מבוסס על הפונקציה שרשומה ב Pinvoke.

 public class tcpTable
    {
        //sort values by declaration order in memory
        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_TCPROW_OWNER_PID
        {
            public uint state;
            public uint localAddr;
            public byte localPort1;
            public byte localPort2;
            public byte localPort3;
            public byte localPort4;
            public uint remoteAddr;
            public byte remotePort1;
            public byte remotePort2;
            public byte remotePort3;
            public byte remotePort4;
            public int owningPid;
        }

        //sort values by declaration order in memory
        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_TCPROW
        {
            public uint dwState;
            public uint dwLocalAddr;
            public uint dwLocalPort;
            public uint dwRemoteAddr;
            public uint dwRemotePort;

        }

        //sort values by declartion order in memory
        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_TCPTABLE_OWNER_PID
        {
            public uint dwNumEntries;
            MIB_TCPROW_OWNER_PID table;
        }

        //sort values by declaration order in memory
        //enum of type for tcptable
        enum TCP_TABLE_CLASS
        {
            TCP_TABLE_BASIC_LISTENER,
            TCP_TABLE_BASIC_CONNECTIONS,
            TCP_TABLE_BASIC_ALL,
            TCP_TABLE_OWNER_PID_LISTENER,
            TCP_TABLE_OWNER_PID_CONNECTIONS,
            TCP_TABLE_OWNER_PID_ALL,
            TCP_TABLE_OWNER_MODULE_LISTENER,
            TCP_TABLE_OWNER_MODULE_CONNECTIONS,
            TCP_TABLE_OWNER_MODULE_ALL
        }

        //enum of the state of single row in the table
        public enum TCP_ROW_STATE
        {
            CLOSED,
            LISTEN,
            SENT,
            RCVD,
            ESTAB,
            FIN_WAIT1,
            FIN_WAIT2,
            CLOSE_WAIT,
            CLOSING,
            LAST_ACK,
            TIME_WAIT,
            DELETE_TCB
        }


        //expose signature, importing ip helper api
        [DllImport("iphlpapi.dll", SetLastError = true)]
        static extern uint GetExtendedTcpTable(IntPtr pTcpTable, ref int dwOutBufLen, bool sort, int ipVersion, TCP_TABLE_CLASS tblClass, int reserved);

        //return the MIB_TCPROW_OWNER_PID array as connection 
        public MIB_TCPROW_OWNER_PID[] GetAllTcpConnections()
        {
            MIB_TCPROW_OWNER_PID[] tTable;
            int AF_INET = 2;    // IP_v4
            int buffSize = 0;

            // what the size of the memory we need to allocate for the table
            uint ret = GetExtendedTcpTable(IntPtr.Zero, ref buffSize, true, AF_INET, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL, 0);
            //set pointer to buffer
            IntPtr buffTable = Marshal.AllocHGlobal(buffSize);

            try
            {
                //getting the buffer
                ret = GetExtendedTcpTable(buffTable, ref buffSize, true, AF_INET, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL, 0);
                if (ret != 0)
                {
                    return null;
                }

                //convert pointer to MIB_TCPTABLE_OWNER_PID pointer
                MIB_TCPTABLE_OWNER_PID tab = (MIB_TCPTABLE_OWNER_PID)Marshal.PtrToStructure(buffTable, typeof(MIB_TCPTABLE_OWNER_PID));
                IntPtr rowPtr = (IntPtr)((long)buffTable + Marshal.SizeOf(tab.dwNumEntries));

                tTable = new MIB_TCPROW_OWNER_PID[tab.dwNumEntries];
 
                //reading the row from buffer using next position pointer
                //size of MIB_TCPROW_OWNER_PID
                for (int i = 0; i < tab.dwNumEntries; i++)
                {
                    //convert pointer to MIB_TCPROW_OWNER_PID pointer
                    MIB_TCPROW_OWNER_PID tcpRow = (MIB_TCPROW_OWNER_PID)Marshal.PtrToStructure(rowPtr, typeof(MIB_TCPROW_OWNER_PID));
                    //save row in table
                    tTable[i] = tcpRow;
                    //go to the next entry.
                    rowPtr = (IntPtr)((long)rowPtr + Marshal.SizeOf(tcpRow));
                }

            }
            finally
            {
                // clear buffer
                Marshal.FreeHGlobal(buffTable);
            }

            return tTable;
        }
    }





הפונקציה GetExtendedUdpTable אומנם לא חשופה ב Pinvoke אבל היא מאוד דומה ל GetExtendedTcpTable.

udpTable.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace processNetwork
{
    public class udpTable
    {
        //sort values by declartion order in memory
        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_UDPROW_OWNER_PID
        {
            public uint LocalAddr;
            public byte localPort1;
            public byte localPort2;
            public byte localPort3;
            public byte localPort4;
            public int owningPid;
        }


        //sort values by declartion order in memory
        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_UDPTABLE_OWNER_PID
        {
            public uint dwNumEntries;
            MIB_UDPROW_OWNER_PID table;
        }



        enum UDP_TABLE_CLASS
        {
            UDP_TABLE_BASIC,
            UDP_TABLE_OWNER_PID,
            UDP_TABLE_OWNER_MODULE
        }

        //expose signature, importing ip helper api
        [DllImport("iphlpapi.dll", SetLastError = true)]
        static extern uint GetExtendedUdpTable(IntPtr pUddpTable, ref int dwOutBufLen, bool sort, int ipVersion, UDP_TABLE_CLASS tblClass, int reserved);

        //return the MIB_UDPROW_OWNER_PID array
        public MIB_UDPROW_OWNER_PID[] GetAllUdpConnections()
        {


            MIB_UDPROW_OWNER_PID[] tTable;
         
            int AF_INET = 2;    // IP_v4
            int buffSize = 0;


            // what the size of the memory we need to allocate for the table?
            uint ret = GetExtendedUdpTable(IntPtr.Zero, ref buffSize, true, AF_INET, UDP_TABLE_CLASS.UDP_TABLE_OWNER_PID, 0);
            //set pointer to buffer
            IntPtr buffTable = Marshal.AllocHGlobal(buffSize);

            try
            {
                //getting the buffer
                ret = GetExtendedUdpTable(buffTable, ref buffSize, true, AF_INET, UDP_TABLE_CLASS.UDP_TABLE_OWNER_PID, 0);
                if (ret != 0)
                {
                    return null;
                }


                //convert pointer to MIB_UDPTABLE_OWNER_PID pointer
                MIB_UDPTABLE_OWNER_PID tab = (MIB_UDPTABLE_OWNER_PID)Marshal.PtrToStructure(buffTable, typeof(MIB_UDPTABLE_OWNER_PID));
             
                IntPtr rowPtr = (IntPtr)((long)buffTable + Marshal.SizeOf(tab.dwNumEntries));
         
                tTable = new MIB_UDPROW_OWNER_PID[tab.dwNumEntries];

                //reading the row from buffer using next position pointer
                //size of MIB_UDPROW_OWNER_PID     
                for (int i = 0; i < tab.dwNumEntries; i++)
                {
                    //convert pointer to MIB_UDPROW_OWNER_PID pointer
                    MIB_UDPROW_OWNER_PID udpRow = (MIB_UDPROW_OWNER_PID)Marshal.PtrToStructure(rowPtr, typeof(MIB_UDPROW_OWNER_PID));
                    //save row in table
                    tTable[i] = udpRow;
                    //go to the next entry.
                    rowPtr = (IntPtr)((long)rowPtr + Marshal.SizeOf(udpRow));
                }

            }
            finally
            {
                // clear buffer
                Marshal.FreeHGlobal(buffTable);
            }

            return tTable;
        }
    }

}


הטבלה שחוזרת לנו מהפונקציה צריכה לעבור מספר המרות, יש להמיר Ip Number ל Ip Address, ולהוציא את ה Port מהאובייקט.

Utils.cs

 public static class utils
 {
        //convert uint to ip
        public static string convert_uint_to_ip(uint ipnum)
        {
            string ipAddress = new IPAddress(BitConverter.GetBytes(ipnum)).ToString();
            return ipAddress;
        }

        //convert bytes to ushort -> port
        public static ushort convert_bytes_to_port(byte p0, byte p1, byte p2, byte p3)
        {
            ushort port;
            byte[] arr = new byte[4];

            //check if the system is litte endian, or big endian and sort the array
            //reading the first 2 bytes
            if (BitConverter.IsLittleEndian)
            {
                arr[0] = p3;
                arr[1] = p2;
                arr[2] = p1;
                arr[3] = p0;
                port = BitConverter.ToUInt16(arr, 2);
            }
            else
            {
                arr[0] = p0;
                arr[1] = p1;
                arr[2] = p2;
                arr[3] = p3;
                port = BitConverter.ToUInt16(arr,0);
            }


            return port;


        }
    }



GUI




הפונקציה שהכי חשובה ב Gui היא init_processStack שאוספת את המידע ממחלקות ה Api שהצגתי וממחלקת ה Process הפנימית של .Net ומחברת בניהם על פי ה Process id ,שאר הפונקציות משמשות לעבודה מול הפקדים ב Gui לכן לא ארחיב עליהם. (פירוט מלא בקוד).

        /// collecting all the processes and the active connections
        private void init_processStack()
        {
            //create table of all the tcp connections
            tcpTable tcptbl = new tcpTable();
            tcpTable.MIB_TCPROW_OWNER_PID[] tcpRow = tcptbl.GetAllTcpConnections();

            //create table of all the udp connections
            udpTable udptbl = new udpTable();
            udpTable.MIB_UDPROW_OWNER_PID[] udpRow = udptbl.GetAllUdpConnections();

            //getting the processes from the machine
            Process[] pro = Process.GetProcesses();

            //add rows from tcp and udp tables inside sysProcess array
            //compate the process id inside the process array and the process id
            //inside the connections tables
            if (pro != null)
            {

                    prcs = new SysProcess[pro.Length];
          


                for (int i = 0; i < pro.Length; i++)
                {
                    prcs[i] = new SysProcess(pro[i]);

                    if (tcpRow != null)
                    {
                        for (int z = 0; z < tcpRow.Length; z++)
                        {
                            if (prcs[i].prc.Id == tcpRow[z].owningPid)
                                prcs[i].tcprows.Add(tcpRow[z]);
                        }
                    }

                    if (udpRow != null)
                    {
                        for (int z = 0; z < udpRow.Length; z++)
                        {
                            if (prcs[i].prc.Id == udpRow[z].owningPid)
                                prcs[i].udpRows.Add(udpRow[z]);
                        }
                    }

                }
            }

        }

סרט דוגמה:





קוד:
https://sourceforge.net/projects/processnetwork/

סיכום:

למדנו להכיר טוב יותר את התהליכים שרצים לנו על המחשב וכיצד ניתן לעקוב אחריהם, קיימים המון כלים בתחום , Mark Russinovich היה בין הראשונים שלקח את ניתוח המערכות של מיקרוספט לקצה וניתן למצוא המון ספרים שלו בתחום, בנוסף אני חייב להזכיר את הפרויקט Process Hacker שבקוד פתוח ב .Net שניתן ללמוד ממנו המון.

תתחילו לעקוב...


יום ראשון, 1 באפריל 2012

JavaScript Optimizer

מי שלא זוכר הבטחתי לייצר סדרת כלים חינמים, הראשון שיצא הוא Laping שמאפשר למנהלי רשתות לבדוק זמינות של פורטים ברחבי הרשת, עבר המון זמן והנה הגיעה השעה לכלי חדש, JavaScript Optimizer הוא כלי המבוסס על .Net וביטויים רגולרים (regular expression) שעוברים על הקוד של ה JavaScript ומשנים אותו, הם משנים אותו בצורה אופטימלית כלומר צמצום רווחי שורה, והורדת הערות מקומיות.

מי ולמה צריך את זה?

בעיקר מפתחי אתרים , הרעיון הוא לצמצם את גודל הקובץ שהלקוח צריך להוריד למחשב שלו בעזרת צמצום רווחים ושורות שגם הם תופסים משקל בקובץ, דבר נוסף שמרווחים בתהליך הוא הפיכת הקוד ללא קריא ומקשה מאוד על הצפייה בקוד, מי שרוצה לנתח את הקוד יצטרך לעבור מילה מילה ולעצב את הקובץ בעצמו על מנת שהיה קריא.

דוגמה ללא אופטמיזציה:


function helloWorld(id) {
    var root = document.getElementById('tmp');
    for (var i = 0; i < root.childElementCount; i++) {        
         var elm = root.childNodes[i];      
         elm.className = "test";      
         changeWorld(elm.id);  
         }
}

function changeWorld(id) {
      var f = document.getElementById(id);
      f.attributes("Style", "width:24px; height:32");
      changeSpace(f.id);
}

function changeSpace(id)
{  
      var f = document.getElementById(id);
      f.attributes("onclick", "helloWorld()");
}


דוגמה עם אופטמיזציה:

function helloWorld(id) { var root = document.getElementById('tmp'); for (var i = 0; i < root.childElementCount; i++) { var elm = root.childNodes[i]; elm.className = "test"; changeWorld(elm.id); } } function changeWorld(id) { var f = document.getElementById(id); f.attributes("Style", "width:24px; height:32"); changeSpace(f.id); } function changeSpace(id) { var f = document.getElementById(id); f.attributes("onclick", "helloWorld()"); }

אחרי שראינו את ההבדל נעבור על תוכנית, התוכנית מבוססת על ה Framework 2.0 אבל ניתן לממש אותה בכול שפה שתומכת בביטויים רגולרים, התוכנית עצמה מאוד פשוטה וכוללת בתוכה 2 פונקציות בלבד, טעינה ושמירת קובץ JS, ומורכבת מ 2 ביטויים רגולרים, הביטוי הראשון אינו מתעסק אם האופטימזציה אלא עם ההערות שהמשתמש רשם לקובץ והסיבה היא כאשר נבצע אופטמיזציה ונצמצם את השורות ההערות יפגעו לנו באופטימזיצה בכך שיהפכו את הפקודות בקובץ לההערה, הביטוי השני מצמצם לנו את הרווחים בקובץ.

// remove all to local comments in the file
 file = Regex.Replace(file, "(?<!:)//[^\r\n]*", "", RegexOptions.IgnoreCase);

//replace all extra spaces to one space.
 file = Regex.Replace(file, @"\s+", " ",RegexOptions.Multiline);



חשוב מאוד! במקרה שיש מחרוזות עם רווחים כפולים הם הצטמצמו לרווח בודד, בדקתי את הקוד על מספר קבצים והוא עבד תקין, במקרה של תקלה נא לפרסם בפוסט זה.






התוכנית:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Text.RegularExpressions;

namespace javaScriptMinimize
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        string file;

        private void btn_input_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                txb_input.Text = openFileDialog1.FileName;
                FileStream myfile = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read);
                StreamReader myreader = new StreamReader(myfile);
                file = myreader.ReadToEnd();
                file = Regex.Replace(file, "(?<!:)//[^\r\n]*", "", RegexOptions.IgnoreCase);
                file = Regex.Replace(file, @"\s+", " ",RegexOptions.Multiline);
                txb_mini.Text = file;
                myreader.Close();
                myfile.Close();
                myreader.Dispose();
                myfile.Dispose();
            }
        }

        private void btn_save_Click(object sender, EventArgs e)
        {
            try
            {
                string filename = "mini_" + Path.GetFileName(txb_input.Text);
                string path = Path.GetDirectoryName(txb_input.Text);
                if (File.Exists(path + "\\" + filename))
                    File.Delete(path + "\\" + filename);

                FileStream myfile = new FileStream(path + "\\" + filename, FileMode.Append, FileAccess.Write);
                StreamWriter mywriter = new StreamWriter(myfile);
                mywriter.Write(file);
                mywriter.Close();
                myfile.Close();
                mywriter.Dispose();
                myfile.Dispose();
            }
            catch (Exception ex)
            { }
        }
    }
}

סיכום:
אז מה ראינו פה? גם הדברים הקטנים ביותר מאפשרים לנו להעלות את האופטמיזציה לאתרים שלנו, ניתן לממש את הרעיון בכל השפות וזאת דרך מעולה להפוך את הקוד שלנו ללא קריא.

פששש....

יום שישי, 3 בדצמבר 2010

Laping Version 2

הרבה זמן חיפשתי כלי נוח עבור בדיקת תקשורת של פורטים בין מחשבים, כמובן ישנם המון כלים מהסוג הזה בעולם, החלטתי בסופו של דבר לפתח אחד כזה בעצמי בשימוש פלטפורמה ה .net של מיקרוסופט כ Console Application.



ניתן להוריד את הקוד באופן חופשי ולהשתמש בו בלי שום הגבלות, זה כלי ראשון מסדרת כלים חינמים שאני יוציא עבור הבלוג הזה.

קצת על האפשרויות:

1.בדיקה של מרחב פורטים.
2.כתיבת התוצאות לקובץ.
3.רשימה ידועה של Services.

קצת על הקוד:

שימוש באובייקטים של ה Namespace.system.net
1.TcpClient
2.UdpClient

שימוש באובייקטים של ה Namespace.system.io
1.FileStream
2.StreamWriter

סה"כ הקוד מאוד פשוט.

כיצד משתמשים:

התוכנה מקבלת קבוצת Arguments.

בדיקה של IP ופורט בודד:
laping -i 192.168.1.100 - p 80
בדיקה של מרחב של פורטים:
laping -i 192.168.1.100 -g 1-500
בדיקה של מרחב של פורטים וכתיבה לקובץ:
laping -i 192.168.1.100 -g 1-500 -l c:\portstatus
ניתן לבדוק Service ישירות:
laping -i 192.168.1.100 -s http
מסך העזרה:
laping -h
רשימת Services ידועים:
laping -sh

ניתן להוריד 2 גרסאות שונות:

ניתן להוריד את הקוד:

סרטון הדגמה:

בהצלחה...