2012年5月18日 星期五

USB NetPower 8800 SDK 從 C++ 轉成 C# - Part 3

因為改 C++ 成 C#,最後再加把勁把程式改完整一點, 改完後的程式會在 Windows 登出或關機時自動將 USB NetPower的插座斷電,如果在把程式加入啟動中,Windows 開機時會自動將 USB NetPower 供電,關機或登出時,自動斷電。

完整 Source Code:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Configuration;
using System.IO.Ports;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public const int FILE_ATTRIBUTE_NORMAL = 0x00000080;
        public const uint GENERIC_READ = 0x80000000;
        public const uint GENERIC_WRITE = 0x40000000;
        public const int OPEN_EXISTING = 3;
        // public const UInt32 INVALID_HANDLE_VALUE = 0xffffffff;

        private const uint FILE_FLAG_OVERLAPPED = 0x40000000;
        private const uint FILE_DEVICE_UNKNOWN = 0x00000022;
        private const uint FILE_ATTRIBUTE_SYSTEM = 0x00000004;
        private const uint USB2SER_IOCTL_INDEX = 0x0800;
        private const uint METHOD_BUFFERED = 0;
        private const uint FILE_ANY_ACCESS = 0;
        public System.Configuration.Configuration config;
        public IntPtr pl2303 = (IntPtr)(-1);



        public Form1()
        {
            InitializeComponent();
        }



        static uint CTL_CODE(uint DeviceType, uint Function, uint Method, uint Access)
        {
            return ((DeviceType << 16) | (Access << 14) | (Function << 2) | Method);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (pl2303 == (IntPtr)(-1))
            {
                pl2303 = CreateFile(textBox1.Text,
                                    GENERIC_READ | GENERIC_WRITE,
                                    0,
                                    IntPtr.Zero,
                                    OPEN_EXISTING,
                                    FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
                                    IntPtr.Zero);
                button1.Text = "關閉通訊埠";
            }
            else
            {
                CloseHandle(pl2303);
                button1.Text = "開啟通訊埠";
                pl2303 = (IntPtr)(-1);
            }

        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (pl2303 != (IntPtr)(-1))
            { // pl2303 open success
                byte val = 0;
                if (PL2303_GP1_GetValue(pl2303, ref  val))
                {
                    // button2.Text = val.ToString();
                    if (val == 0)
                    {
                        if (PL2303_GP1_Enable(pl2303))
                        {
                            if (PL2303_GP1_SetValue(pl2303, 1))
                            {
                                button2.Text = "插座断電";
                            }
                        }
                        else
                        {
                            MessageBox.Show("enable fail");
                        }
                    }
                    else
                    {
                        if (PL2303_GP1_Enable(pl2303))
                        {
                            if (PL2303_GP1_SetValue(pl2303, 0))
                            {
                                button2.Text = "插座通電";
                            }
                        }
                        else
                        {
                            MessageBox.Show("enable fail");
                        }
                    }

                }
            }
            else
            {
                MessageBox.Show("通訊埠尚未開啟");
            }

        }
        private bool PL2303_GP1_SetValue(IntPtr hDrv, byte val)
        {
            uint nBytes = 0;
            byte dummybyte = 0;
            uint GP1_SET_VALUE = CTL_CODE(FILE_DEVICE_UNKNOWN, USB2SER_IOCTL_INDEX + 23, METHOD_BUFFERED, FILE_ANY_ACCESS);
            bool bSuccess = DeviceIoControl(hDrv, GP1_SET_VALUE, ref val, sizeof(byte), ref dummybyte,
                            0,
                            ref nBytes,
                            IntPtr.Zero);

            return bSuccess;
        }

        private bool PL2303_GP1_GetValue(IntPtr hDrv, ref byte val)
        {
            uint nBytes = 0;
            byte dummybyte = 0;
            uint GP1_GET_VALUE = CTL_CODE(FILE_DEVICE_UNKNOWN, USB2SER_IOCTL_INDEX + 25, METHOD_BUFFERED, FILE_ANY_ACCESS);


            bool bSuccess = DeviceIoControl(hDrv, GP1_GET_VALUE, ref dummybyte, 0, ref val,
                            sizeof(byte),
                            ref nBytes,
                            IntPtr.Zero);

            return bSuccess;
        }

        private bool PL2303_GP1_Enable(IntPtr hDrv)
        {
            uint nBytes = 0;
            byte enable = 1;
            byte dummybyte = 0;
            uint GP1_OUTPUT_ENABLE = CTL_CODE(FILE_DEVICE_UNKNOWN, USB2SER_IOCTL_INDEX + 21, METHOD_BUFFERED, FILE_ANY_ACCESS);

            bool bSuccess = DeviceIoControl(hDrv, GP1_OUTPUT_ENABLE, ref enable, sizeof(byte), ref dummybyte,
                            0,
                            ref nBytes,
                            IntPtr.Zero);


            return bSuccess;
        }

        [DllImport("kernel32.dll")]
        private static extern IntPtr CreateFile(
        string lpFileName,
        uint dwDesiredAccess,
        int dwShareMode,
        IntPtr lpSecurityAttributes,
        int dwCreationDisposition,
        uint dwFlagsAndAttributes,
        IntPtr hTemplateFile
         );

        [DllImport("kernel32.dll", EntryPoint = "DeviceIoControl", SetLastError = true)]
        internal static extern bool DeviceIoControl(
            IntPtr hDevice,
            uint dwIoControlCode,
            ref byte lpInBuffer,
            uint nInBufferSize,
            ref byte lpOutBuffer,
            int nOutBufferSize,
            ref uint lpBytesReturned,
            IntPtr lpOverlapped);

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool CloseHandle(IntPtr hObject);

        private void Form1_Shown(object sender, EventArgs e)
        {
            string[] ports = SerialPort.GetPortNames();
            comboBox1.Items.AddRange(ports);
            config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            textBox1.Text = config.AppSettings.Settings["port"].Value;
            if (comboBox1.FindStringExact(textBox1.Text) > -1)
            {
                comboBox1.Text = textBox1.Text;
            }

            if (pl2303 == (IntPtr)(-1))
            {
                pl2303 = CreateFile(textBox1.Text,
                                    GENERIC_READ | GENERIC_WRITE,
                                    0,
                                    IntPtr.Zero,
                                    OPEN_EXISTING,
                                    FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
                                    IntPtr.Zero);
                button1.Text = "關閉通訊埠";
            }
            else
            {
                CloseHandle(pl2303);
                button1.Text = "開啟通訊埠";
                pl2303 = (IntPtr)(-1);
            }

            byte val = 0;
            if (PL2303_GP1_GetValue(pl2303, ref  val))
            {
                // button2.Text = val.ToString();
                if (val == 0)
                {
                    if (PL2303_GP1_Enable(pl2303))
                    {
                        if (PL2303_GP1_SetValue(pl2303, 1))
                        {
                            button2.Text = "插座断電";
                        }
                    }
                    else
                    {
                        MessageBox.Show("enable fail");
                    }
                }
                else
                {
                    button2.Text = "插座断電";
                }

            }


        }

        private void label2_Click(object sender, EventArgs e)
        {

        }

        private void button3_Click(object sender, EventArgs e)
        {
            config.AppSettings.Settings["port"].Value = comboBox1.Text;
            config.Save();
            ConfigurationManager.RefreshSection("appSettings");
            textBox1.Text = comboBox1.Text;

        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.WindowsShutDown)
            {
                if (pl2303 == (IntPtr)(-1))
                {
                    pl2303 = CreateFile(textBox1.Text,
                                        GENERIC_READ | GENERIC_WRITE,
                                        0,
                                        IntPtr.Zero,
                                        OPEN_EXISTING,
                                        FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
                                        IntPtr.Zero);
                   
                }
               
                if (PL2303_GP1_Enable(pl2303))
                {
                    if (PL2303_GP1_SetValue(pl2303, 0))
                    {
                     
                    }
                }





            }
        }



    }
}