PDA

View Full Version : چه طوری باید درب صندوق فروشگاهی رو باز کرد



NasimBamdad
جمعه 15 آذر 1398, 22:03 عصر
سلام و وقت بخیر

در سامانه فروشگاهی که درست کردم نیاز دارم درب صندوق یا همون کشر ( Cashier ) رو از طریق کد نویسی C# باز کنم ، چه طور میشه کلا این درب صندوق رو مدیریت کنم ، مدت زمانی که درب باز هست و تشخیص بدم ، زمان بسته شدن و این موارد

یه عکس پیوست کردم گفتن یه چیز مثل اینه

NasimBamdad
دوشنبه 18 آذر 1398, 08:14 صبح
50 view و هیچ !

drawback
دوشنبه 18 آذر 1398, 16:45 عصر
این کد خوندن پورت Com هستش .
باید با پورت سریال کار کنید

the king
دوشنبه 18 آذر 1398, 22:24 عصر
سلام و وقت بخیر

در سامانه فروشگاهی که درست کردم نیاز دارم درب صندوق یا همون کشر ( Cashier ) رو از طریق کد نویسی C#‎ باز کنم ، چه طور میشه کلا این درب صندوق رو مدیریت کنم ، مدت زمانی که درب باز هست و تشخیص بدم ، زمان بسته شدن و این موارد

یه عکس پیوست کردم گفتن یه چیز مثل اینه
فرض رو بر این میگیرم که REM ها حذف بشن.
سطر 1 و 4، غیر فعال کردن اکو
سطر 2 و 3، شرحی که میده کمکی نمی کنه.
سطر 5، کپی کردن فایل های ftp که می توانید با کد #C هم انجامش بدید.
سطر 7 الی 11 تنظیم کردن پورت سریال ئه که استفاده اش برای یک برنامه دیگه است و داخل #C هم باید از همین فرمان MODE استفاده بشه.
اینکه در #C پورت سریال رو باز کنیم و چبری بهش بفرستیم یا داده بگیریم با این توضیحات این فایل معنی نداره. این فایل شما پورت سریال رو برای استفاده یک برنامه دیگه تنظیم میکنه، خودش کاری با پورت نداره.
سطر های 12 و 13 ایجاد کردن پوشه است که در #C هم میشه انجامش داد.
سطر 14 اختصاص دادن یک درایو مجازی :K به یک مسیر فایل ئه که در #C هم با همین SUBST قابل انجام ئه.
سطر های 15 و 16 تنظیم مجدد پورت LPT3 روی یک سخت افزار (معمولا پرینتر) تحت شبکه است که در #C هم با همین فرمان انجام شدنی است.
سطر 17 تغییر نام فایل های JPG به BMP است که اونم در #C قابل انجام ئه.
سطر 18 انتظار ئه که برای #C اجراش منطقی نداره.

چند تا مساله هست، اول اینکه در این فایل Batch شما اشاره نشده که در ادامه کدوم برنامه باز بشه. در واقع صندوقی که میخواد باز بشه در این فایل باز نشده.
شما می توانید تخصیص پورت LPT3 رو ملاک لحظه باز شدن بگیرید ولی ظاهرا این مورد دیگری است.
به هر حال شما می توانید در یک فایل متنی یا یک کلید Registry تاریخ و ساعت فعلی رو ثبت کنید که مشخص بشه کی این کد #C رو اجرا می کنید.
بعد هر زمان که لازم شد به اون فایل یا کلید Registry ویندوز مراجعه میکنید تا ببینید از کی بازش کردید. هر وقتم بستیدش اون فایل یا کلید Registry رو حذف می کنید.

یک متد میسازیم که بوسیله اون یک فرمان Command Prompt رو اجرا کنیم :


private static void ExecuteCommand(string command, out string output)
{
try
{
var startInfo = new System.Diagnostics.ProcessStartInfo("cmd.exe", "/C " + command)
{
UseShellExecute = false,
CreateNoWindow = true,
WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden,
RedirectStandardOutput = true
};
var process = System.Diagnostics.Process.Start(startInfo);
process.WaitForExit();
output = process.StandardOutput.ReadToEnd();
}
catch (Exception ex)
{
output = ex.Message;
}
}


یک متد میسازیم که بوسیله اون یک برنامه سیستمی رو اجرا کنیم :


private static void ExecuteApplication(string fileName, string arguments, out string output)
{
try
{
var startInfo = new System.Diagnostics.ProcessStartInfo(fileName, arguments)
{
UseShellExecute = false,
CreateNoWindow = true,
WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden,
RedirectStandardOutput = true
};
var process = System.Diagnostics.Process.Start(startInfo);
process.WaitForExit();
output = process.StandardOutput.ReadToEnd();
}
catch (Exception ex)
{
output = ex.Message;
}
}


و یک متد میسازیم که بوسیله اون زمان باز شدن صندوق رو ثبت کنیم :


private void CashierOpened()
{
System.IO.File.WriteAllText(@"C:\Start.txt", DateTime.Now.ToBinary().ToString());
}


و یک متد میسازیم که موقع بسته شدن صندوق اجراش کنیم :


private void CashierClosed()
{
if (System.IO.File.Exists(@"C:\Start.txt"))
{
System.IO.File.Delete(@"C:\Start.txt");
}
}


و یک متد میسازیم که هر وقت خواستیم مدت زمان باز بودن صندوق رو دریافت کنیم :


private TimeSpan GetElapsedTime()
{
if (System.IO.File.Exists(@"C:\Start.txt") == false)
{
return TimeSpan.Zero;
}
var startTime = DateTime.FromBinary(long.Parse(System.IO.File.Read AllText(@"C:\Start.txt")));
return DateTime.Now.Subtract(startTime);
}


حالا فرمان های داخل فایل Batch رو میتونیم اجرا کنیم :


string output;
//ExecuteCommand(@"COPY C:\temp\sh*.fpt DEMOCOMP\shdata", out output);
//ExecuteApplication("MODE.COM", @"COM1: 96,N,8,1", out output);
//ExecuteApplication("MODE.COM", @"COM2: 96,N,8,1", out output);
//ExecuteApplication("MODE.COM", @"COM3: 96,N,8,1", out output);
//ExecuteApplication("MODE.COM", @"COM4: 96,N,8,1", out output);
//ExecuteApplication("MODE.COM", @"COM5: 96,N,8,1", out output);
//ExecuteCommand(@"MD C:\TT", out output);
//ExecuteCommand(@"MD C:\TT\TEMP", out output);
//ExecuteApplication("SUBST.EXE", @"K: C:\TT", out output);
ExecuteApplication("NET.EXE", @"USE LPT3: /DELETE", out output);
ExecuteApplication("NET.EXE", @"USE LPT3: \\BO1\ZEBRA /PERSISTENT:YES", out output);
//ExecuteCommand(@"REN DEMOCOMP\IMDATA\IMAGES\*.JPG *.BMP", out output);

CashierOpened();


و هر زمان لازمه صندوق بسته بشه اینکار رو در فایل منعکس می کنیم :


private void button1_Click(object sender, EventArgs e)
{
CashierClosed();
}


و هر زمان لازمه مدت زمان باز بودن صندوق رو داریم :


MessageBox.Show(GetElapsedTime().ToString());


ولی اینجا هر چیزی مشخص هست جز اصل کاری، صندوق رو نه باز میکنیم و نه میدونیم چطور باز میشه. در فایل Batch تون همچین چیزی مشخص نیست.

NasimBamdad
سه شنبه 19 آذر 1398, 07:41 صبح
فرض رو بر این میگیرم که REM ها حذف بشن.
سطر 1 و 4، غیر فعال کردن اکو
سطر 2 و 3، شرحی که میده کمکی نمی کنه.
سطر 5، کپی کردن فایل های ftp که می توانید با کد #C هم انجامش بدید.
سطر 7 الی 11 تنظیم کردن پورت سریال ئه که استفاده اش برای یک برنامه دیگه است و داخل #C هم باید از همین فرمان MODE استفاده بشه.
اینکه در #C پورت سریال رو باز کنیم و چبری بهش بفرستیم یا داده بگیریم با این توضیحات این فایل معنی نداره. این فایل شما پورت سریال رو برای استفاده یک برنامه دیگه تنظیم میکنه، خودش کاری با پورت نداره.
سطر های 12 و 13 ایجاد کردن پوشه است که در #C هم میشه انجامش داد.
سطر 14 اختصاص دادن یک درایو مجازی :K به یک مسیر فایل ئه که در #C هم با همین SUBST قابل انجام ئه.
سطر های 15 و 16 تنظیم مجدد پورت LPT3 روی یک سخت افزار (معمولا پرینتر) تحت شبکه است که در #C هم با همین فرمان انجام شدنی است.
سطر 17 تغییر نام فایل های JPG به BMP است که اونم در #C قابل انجام ئه.
سطر 18 انتظار ئه که برای #C اجراش منطقی نداره.

چند تا مساله هست، اول اینکه در این فایل Batch شما اشاره نشده که در ادامه کدوم برنامه باز بشه. در واقع صندوقی که میخواد باز بشه در این فایل باز نشده.
شما می توانید تخصیص پورت LPT3 رو ملاک لحظه باز شدن بگیرید ولی ظاهرا این مورد دیگری است.
به هر حال شما می توانید در یک فایل متنی یا یک کلید Registry تاریخ و ساعت فعلی رو ثبت کنید که مشخص بشه کی این کد #C رو اجرا می کنید.
بعد هر زمان که لازم شد به اون فایل یا کلید Registry ویندوز مراجعه میکنید تا ببینید از کی بازش کردید. هر وقتم بستیدش اون فایل یا کلید Registry رو حذف می کنید.

یک متد میسازیم که بوسیله اون یک فرمان Command Prompt رو اجرا کنیم :


private static void ExecuteCommand(string command, out string output)
{
try
{
var startInfo = new System.Diagnostics.ProcessStartInfo("cmd.exe", "/C " + command)
{
UseShellExecute = false,
CreateNoWindow = true,
WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden,
RedirectStandardOutput = true
};
var process = System.Diagnostics.Process.Start(startInfo);
process.WaitForExit();
output = process.StandardOutput.ReadToEnd();
}
catch (Exception ex)
{
output = ex.Message;
}
}


یک متد میسازیم که بوسیله اون یک برنامه سیستمی رو اجرا کنیم :


private static void ExecuteApplication(string fileName, string arguments, out string output)
{
try
{
var startInfo = new System.Diagnostics.ProcessStartInfo(fileName, arguments)
{
UseShellExecute = false,
CreateNoWindow = true,
WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden,
RedirectStandardOutput = true
};
var process = System.Diagnostics.Process.Start(startInfo);
process.WaitForExit();
output = process.StandardOutput.ReadToEnd();
}
catch (Exception ex)
{
output = ex.Message;
}
}


و یک متد میسازیم که بوسیله اون زمان باز شدن صندوق رو ثبت کنیم :


private void CashierOpened()
{
System.IO.File.WriteAllText(@"C:\Start.txt", DateTime.Now.ToBinary().ToString());
}


و یک متد میسازیم که موقع بسته شدن صندوق اجراش کنیم :


private void CashierClosed()
{
if (System.IO.File.Exists(@"C:\Start.txt"))
{
System.IO.File.Delete(@"C:\Start.txt");
}
}


و یک متد میسازیم که هر وقت خواستیم مدت زمان باز بودن صندوق رو دریافت کنیم :


private TimeSpan GetElapsedTime()
{
if (System.IO.File.Exists(@"C:\Start.txt") == false)
{
return TimeSpan.Zero;
}
var startTime = DateTime.FromBinary(long.Parse(System.IO.File.Read AllText(@"C:\Start.txt")));
return DateTime.Now.Subtract(startTime);
}


حالا فرمان های داخل فایل Batch رو میتونیم اجرا کنیم :


string output;
//ExecuteCommand(@"COPY C:\temp\sh*.fpt DEMOCOMP\shdata", out output);
//ExecuteApplication("MODE.COM", @"COM1: 96,N,8,1", out output);
//ExecuteApplication("MODE.COM", @"COM2: 96,N,8,1", out output);
//ExecuteApplication("MODE.COM", @"COM3: 96,N,8,1", out output);
//ExecuteApplication("MODE.COM", @"COM4: 96,N,8,1", out output);
//ExecuteApplication("MODE.COM", @"COM5: 96,N,8,1", out output);
//ExecuteCommand(@"MD C:\TT", out output);
//ExecuteCommand(@"MD C:\TT\TEMP", out output);
//ExecuteApplication("SUBST.EXE", @"K: C:\TT", out output);
ExecuteApplication("NET.EXE", @"USE LPT3: /DELETE", out output);
ExecuteApplication("NET.EXE", @"USE LPT3: \\BO1\ZEBRA /PERSISTENT:YES", out output);
//ExecuteCommand(@"REN DEMOCOMP\IMDATA\IMAGES\*.JPG *.BMP", out output);

CashierOpened();


و هر زمان لازمه صندوق بسته بشه اینکار رو در فایل منعکس می کنیم :


private void button1_Click(object sender, EventArgs e)
{
CashierClosed();
}


و هر زمان لازمه مدت زمان باز بودن صندوق رو داریم :


MessageBox.Show(GetElapsedTime().ToString());


ولی اینجا هر چیزی مشخص هست جز اصل کاری، صندوق رو نه باز میکنیم و نه میدونیم چطور باز میشه. در فایل Batch تون همچین چیزی مشخص نیست.
ممنونم دوست عزیز که وقت گذاشتید ، برام خیلی مهم و قابل تقدیر.

موضوع اینه که یه برنامه قدیمی داریم که داره این کار انجام میده به VB ، و این رو کنارش پیدا کردم، حالا یک nuget به اسم POS پیدا کردم که دارم با اون کار می کنم اگه نتیجه گرفتم که حتما اینجا می ذارم، ولی این متد های شما هم خیلی زیبا و کد ها رو راحت تر می کنه قطعا

سپاس

NasimBamdad
جمعه 06 دی 1398, 18:20 عصر
یک کلاس اول درست می کنیم به این صورت :


using System;
using System.Runtime.InteropServices;

namespace Mall_Management
{
class CashOpen
{
// 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;
}

}
}


بعد این طوری فراخوانی میشه برای زمانی که می خوایید درب صندوق باز کنید : لازم به ذکر است این روش برای زمانی است که کابل تلفن از کشر به فیش پرینتر وصل است و پیش پرینتر به کامپیوتر ، و درب کشر از طریق فیش پرینتر باز میشه


PrintDialog pd = new PrintDialog();
pd.PrinterSettings = new PrinterSettings();
if (DialogResult.OK == pd.ShowDialog(this))
{
byte[] codeOpenCashDrawer = new byte[] { 27, 112, 48, 55, 121 };
IntPtr pUnmanagedBytes = new IntPtr(0);
pUnmanagedBytes = Marshal.AllocCoTaskMem(5);
Marshal.Copy(codeOpenCashDrawer, 0, pUnmanagedBytes, 5);
CashOpen.SendBytesToPrinter(pd.PrinterSettings.Pri nterName, pUnmanagedBytes, 5);
Marshal.FreeCoTaskMem(pUnmanagedBytes);
MessageBox.Show("Data sent to printer.");
}
else
{
MessageBox.Show("Data not sent to printer.");
}


به روش بالا بعد از ظاهر شدن فرم Print Dialog ، باید فیش پرینتر خودتون رو انتخاب کنید و Print کنید عملا ، و بعد درب صندوق باز میشه