2013年2月6日 星期三

沒有發票機,透過網路型出單機開錢櫃的解決方法


  這段實在很重要,對於VB6的程式來說,要開錢櫃,在有接發票機的情形下,直接輸出LPT即可,,沒有發票機時只能透過熱感式出單機協助。但現在有些熱感式出單機是網路型的,直接輸出LPT就沒用了。

  所以,當你的電腦接網路,網路接出單機,而出單機再接錢櫃時,下列的範例就是很好用的C#程式,以我的狀況是,用C#寫一支下列程式,呼叫下面這個Class,打開錢櫃後就自動結束程式;接著在VB6呼叫這隻程式,就可以很開心的在沒有發票機的狀況下打開錢櫃啦~

PS:很抱歉,這段資料的來源我忘了保留下來了,如果有人知道,也可以告訴我,我會立即補上出處的,感謝~
using System;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Windows.Forms;
using System.Runtime.InteropServices;
class RawPrinterHelper
    {
        // Structure and API declarions:
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public class DOCINFOA
        {
            [MarshalAs(UnmanagedType.LPStr)]
            public string pDocName;
            [MarshalAs(UnmanagedType.LPStr)]
            public string pOutputFile;
            [MarshalAs(UnmanagedType.LPStr)]
            public string pDataType;
        }
        [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);

        [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern bool ClosePrinter(IntPtr hPrinter);

        [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);

        [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern bool EndDocPrinter(IntPtr hPrinter);

        [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern bool StartPagePrinter(IntPtr hPrinter);

        [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern bool EndPagePrinter(IntPtr hPrinter);

        [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten);

        // SendBytesToPrinter()
        // When the function is given a printer name and an unmanaged array
        // of bytes, the function sends those bytes to the print queue.
        // Returns true on success, false on failure.
        public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount)
        {
            Int32 dwError = 0, dwWritten = 0;
            IntPtr hPrinter = new IntPtr(0);
            DOCINFOA di = new DOCINFOA();
            bool bSuccess = false; // Assume failure unless you specifically succeed.

            di.pDocName = "My C#.NET RAW Document";
            di.pDataType = "RAW";

            // Open the printer.
            if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero))
            {
                // Start a document.
                if (StartDocPrinter(hPrinter, 1, di))
                {
                    // Start a page.
                    if (StartPagePrinter(hPrinter))
                    {
                        // Write your bytes.
                        bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten);
                        EndPagePrinter(hPrinter);
                    }
                    EndDocPrinter(hPrinter);
                }
                ClosePrinter(hPrinter);
            }
            // If you did not succeed, GetLastError may give more information
            // about why not.
            if (bSuccess == false)
            {
                dwError = Marshal.GetLastWin32Error();
            }
            return bSuccess;
        }

    }

Then use the following method to open the cash drawer
private void openCashDrawer()
        {
            //下面這行請改成錢櫃的指令
            byte[] codeOpenCashDrawer = new byte[] { 27, 112, 48, 55, 121 };
            IntPtr pUnmanagedBytes = new IntPtr(0);
            pUnmanagedBytes = Marshal.AllocCoTaskMem(5);
            Marshal.Copy(codeOpenCashDrawer, 0, pUnmanagedBytes, 5);
            //下面這行的第一個參數"EPSON xxxx" 請改成印表機名稱,名稱哦~~很方便的
            RawPrinterHelper.SendBytesToPrinter("EPSON TM-T88V Receipt Invoice", pUnmanagedBytes, 5);
            Marshal.FreeCoTaskMem(pUnmanagedBytes);
        }

iPhone iOS 6.1 JB + AppSyn 安裝極簡心得



0.把iPhone連接好電腦
1.先備份相片、音樂、通訊錄
2.先更新到 iOS 6.1 (之前就有JB的,在這裡可能會失敗,接著就只能還原重裝)
3.到 http://evasi0n.com 下載 JB程式 evasi0n
4.執行evasi0n,按下開始
5.evasi0n執行到一半會要求你 unlock,請記得是unlock,不是unplug...
6.unlock 完會要你去按一個icon,我忘了叫什麼了...
7.請先到Cydia去更新一個項目,同樣地,我也忘了名稱..

8.到此JB就算完成。


9.但 JB的人不會就這麼滿足的,比方說:我
10.到Cydia,搜尋並下載SBSetting
11.到Cydia,搜尋並下載Activator
12.到Cydia,增加軟體源 http://Cydia.myrepospace.com/Bl00dra1n
12-1.是 Bl零零dra壹n,不是Bl歐歐dra哀n,還有,這個網站有點慢,有時會加不太進去
13.加完之後,一樣在Cydia搜尋並下載AppSync for iOS 6
13-1.裝完後,拔出連接線再接回去,讓iTune可以開始同步
14.完成,這樣之前用Installous安裝,並且存在iTune的ipa,就可以再傳回iPhone用了~
14-1.有可能會出現要你輸入帳號密碼的畫面,按取消就好了

後記:
1.Background Remover 目前好像還不正常,會閃退,滿可惜的
2.我用的是iPhone 4,升級前版本是5.1.1 JB with RedSn0w。

20130216:Background Remover已修正了,到Cydia裡搜尋Remove Background,可以找到兩個,
一個是Remove Backgrounder,另一個Remove Backgrounder SBSetting,兩個都裝就可以一鍵清除背景程式了~


MS-SQL 無法刪除使用者 - 資料庫主體在資料庫中擁有 結構描述 且無法卸除。(Microsoft SQL Server, 錯誤: 15138) 在設定MSSQL時,很常把結構描述跟成員資格搞錯 這是結構描述 這是成員資格 成員資格是設定權限用的,結構描述...我不太清楚 X...