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

У меня есть Arduino, отправляющая символ 'c' через COM-порт 3.
У меня есть консольное приложение VS2013 C#, прослушивающее COM3 для символа 'c'. Оператор if при чтении 'c' запускает файл .ahk.

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

Я заметил это после нескольких попыток. Так сказать, когда данные получены, консоль печатает новую строку "data received" и вторую строку с данными.

Ex:

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

Теперь это не запустит приложение, которое должно. Но это будет:

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

Обратите внимание, что в обоих примерах я получил данные три раза, но только во втором примере строки анализируются неправильно, и он не печатает символ или имеет разрывы строк. В один из трех раз он получил данные. Как ни странно именно тогда, когда запускает приложение.

Я беру 2 доллара США за печать фотографий. Каждые 2 доллара США запускают скрипт ahk, который берет и печатает изображение. Таким образом, каждый раз, когда вводятся 2 доллара США, я получаю «c». Затем, после того, как изображение напечатано, скрипт ahk завершает работу, и я хотел бы, чтобы он снова открывался после того, как были вставлены еще 2 доллара США.

Я прочитал о 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 : вы можете получить более одного символа при запуске события, даже если вы удалите инструкции Sleep, которые кажутся бесполезными.   -  person Graffito    schedule 08.07.2015
comment
Что вы хотите, чтобы ваша программа делала, если она получает более одного символа 'c'? Если вам нужно, чтобы ваша программа запускала процесс один раз для каждого символа, то вам нужно просканировать строку, которая была прочитана из последовательного порта, и запустить процесс для каждого из них. Если вам просто нужно запустить процесс один раз, независимо от того, сколько отправлено, то сработает использование Contains() в качестве заданных состояний ответа. К сожалению, ваш вопрос слишком расплывчатый, чтобы понять, каков правильный ответ.   -  person Peter Duniho    schedule 08.07.2015
comment
@peter Я беру 2 доллара за печать фотографий. Каждые 2 доллара США запускают скрипт ahk, который берет и печатает изображение. Таким образом, каждый раз, когда вводятся 2 доллара США, я получаю «c». Затем, после того, как изображение напечатано, скрипт ahk завершает работу, и я хотел бы, чтобы он снова открывался после того, как были вставлены еще 2 доллара США.   -  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
Я действительно доволен неправильным ответом. Сэр, вы дважды правы: во-первых, предположив, что я согласен с неправильным ответом, а во-вторых, указав основную проблему блокировки обработчика событий во время выполнения процесса. Я ценю усилия, чтобы указать на это мне и другим пользователям. Я хотел бы похвалить вас за это. Без дальнейших замечаний. -J   -  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