Process.Start() работи само когато линията е неправилно разчетена

Имам Arduino, изпращащ символ 'c' през COM порт 3.
Имам конзолно приложение VS2013 C#, което слуша COM3 за символ 'c'. Операторът if, когато се чете 'c', стартира .ahk файл.

Проблемът е, че когато създам и инсталирам приложението си на друг компютър, файлът ще бъде отворен само ако редът е написан неправилно на конзолата.

Забелязах това след няколко опита. Така да кажем, когато се получат данни, конзолата отпечатва нов ред "data received" и втори ред с данните.

Ex:

Получени данни:
c
Получени данни:
c
Получени данни:
c

Сега това няма да стартира приложението, което трябва. Но това ще:

Получени данни:
cПолучени данни:
Получени данни:
c

Забележете, че и в двата примера получих данни три пъти, но само във втория пример редовете не са анализирани правилно и той не отпечатва знака или също има прекъсвания на редове. В един от трите пъти получи данни. Колкото и да е странно, това е тогава, когато стартира приложението.

Таксувам 2 USD за печат на снимки. Всеки 2 USD задейства ahk скрипт, който взема и отпечатва изображението. Така че всеки път, когато се поставят 2 USD, получавам ´c´. След това, след като изображението бъде отпечатано, ahk скриптът се затваря и бих искал да се отвори отново, след като бъдат вмъкнати още 2 USD.

Четох за Process.Start() в страниците на Microsoft. Все още уча основни неща, така че ми трябва известно време, за да мисля в правилната посока.

Прекарах часове, опитвайки се да го разбера чрез проба и грешка. Правя модификации на кода с това, което ми позволява ограничената способност. връзка към пример как да извикате процес от C#.

Както и да е, ето кода, който (между другото) копирах и поставих от търсене в Google на помощен сайт на Microsoft:

using System;
using System.IO.Ports;
using System.Diagnostics;
using System.Threading;

class PortDataReceived
{
    public static void Main()
    {
        SerialPort mySerialPort = new SerialPort("COM3");

        mySerialPort.BaudRate = 9600;
        mySerialPort.Parity = Parity.None;
        mySerialPort.StopBits = StopBits.One;
        mySerialPort.DataBits = 8;
        mySerialPort.Handshake = Handshake.None;
        mySerialPort.RtsEnable = true;

        mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);

        mySerialPort.Open();

        Console.WriteLine("Press any key to continue...");
        Console.WriteLine();
        Console.ReadKey();
        mySerialPort.Close();
    }

    private static void DataReceivedHandler(
                        object sender,
                        SerialDataReceivedEventArgs e)
    {
        SerialPort sp = (SerialPort)sender;
        string indata = sp.ReadExisting();
        Console.WriteLine("Data Received:");
        Thread.Sleep(300);
        Console.Write(indata);
        Thread.Sleep(300);
        if (indata == "c")
        {
            Thread.Sleep(1000);
            //Process.Start(@"C:\Users\laptop\Desktop\print.ahk");
            Process process = new Process();
            // Configure the process using the StartInfo properties.
            process.StartInfo.FileName = "print.ahk";
            process.StartInfo.Arguments = "-n";
           //process.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
            process.Start();
            process.WaitForExit();// Waits here for the process to exit.
        }
    }
}

Като бонус, трябва да намеря програмист, който ще ми помогне да внедря програма за разпознаване/изрязване на лица, която намерих тук в StackOverflow. Всъщност намерих един, написан с python, и друг на C#. Бях в онлайн сайтове за наемане на програмисти, но офертите изглеждаха дръзки и без никакви обещания. Както и да е, пишете ми, ако имате нужда от повече информация.


person Julio Sitges    schedule 08.07.2015    source източник
comment
в DataReceivedHandler, трябва да преминете към всички знаци, получени в indata: може да получите повече от един знак, когато събитието се задейства, дори ако премахнете инструкциите за заспиване, които не изглеждат полезни.   -  person Graffito    schedule 08.07.2015
comment
Какво искате да прави вашата програма, ако получи повече от един 'c' знак? Ако имате нужда вашата програма да стартира процеса веднъж за всеки символ, тогава трябва да сканирате низа, който е прочетен от серийния порт, и да стартирате процеса за всеки един. Ако просто трябва да стартирате процеса веднъж, без значение колко са изпратени, тогава използването на Contains() като дадено състояние на отговор ще работи. За съжаление въпросът ви е твърде неясен, за да разберете кой е правилният отговор.   -  person Peter Duniho    schedule 08.07.2015
comment
@peter Таксувам 2 USD за отпечатване на снимки. Всеки 2 USD задейства ahk скрипт, който взема и отпечатва изображението. Така че всеки път, когато се поставят 2 USD, получавам ´c´. След това, след като изображението бъде отпечатано, ahk скриптът се затваря и бих искал да се отвори отново, след като бъдат вмъкнати още 2 USD.   -  person Julio Sitges    schedule 08.07.2015
comment
Въз основа на вашата актуализирана информация ми се струва, че имате два проблема с кода. Първият е лесен за решаване: сканирайте получения низ и стартирайте процеса веднъж за всеки 'c', който намерите. Второто изисква повече усилия: вашият код няма да бъде надежден, ако данните се получават твърде бързо, защото блокирате манипулатора на събития, докато процесът работи. Това може да работи във вашия конкретен сценарий, но е вероятно да се повреди в бъдеще; трябва да използвате отделна нишка за действително стартиране и наблюдение на външния процес, като използвате манипулатора на събития единствено за сигнализиране на другата нишка.   -  person Peter Duniho    schedule 08.07.2015
comment
Ако искате помощ за действително поправяне на кода, така че да е правилен, моля, кажете го. В противен случай ще приема, че сте добре с неправилния отговор, който вече ви беше предоставен.   -  person Peter Duniho    schedule 08.07.2015
comment
Наистина съм доволен от грешния отговор. Сър, вие сте прав два пъти, първо като приемете, че съм добре с неправилния отговор и второ, че уточнявате основния проблем с блокирането на манипулатора на събития, докато процесът работи. Оценявам усилието да го посочите на мен и на други потребители. Бих искал да ви направя комплимент за това. Без повече забележки. -Дж   -  person Julio Sitges    schedule 08.07.2015


Отговори (1)


Изглежда, че вашият подател изпраща не само знака „c“, но и малко интервал. Така че по същество просто трябва да облекчите малко условието във вашия if оператор.

Така че вместо

if (indata == "c")

моля опитайте например

if (indata.Contains("c"))
person Robert Hegner    schedule 08.07.2015
comment
Той отваря файла и когато бъде изпратен друг c, той отваря файла отново. Това е, което ми трябваше. Благодаря - person Julio Sitges; 08.07.2015
comment
Както отбелязах в коментара си по-горе, това решение не е правилно. Ако кодът получи повече от един знак в една операция за получаване, той пак ще изпълни процеса само веднъж. - person Peter Duniho; 08.07.2015
comment
Не искаш ли if (indata.Trim() == "c") или if (indata.StartsWith("c"))? По принцип вие просто премахвате допълнителния CrLf и търсенето на целия низ за c прави по-трудно добавянето на други низове по-късно, защото те не могат да съдържат c. - person Trisped; 10.07.2015