powered by simpleCommunicator - 2.0.55     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
49 сообщений из 49, показаны все 2 страниц
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38875759
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я для передачи команд (строк) между приложениями использую два IPC-метода:
1) Mailslot
2) SendMessage(WM_COPYDATA) -сейчас почти нигде не оставил в пользу первого

В переписываемом .Net приложении я делаю упор на Юникод, т.е. все API декларируются
Код: vbnet
1.
Declare Unicode Function ...Alias "...W"


все структуры с намеком на строки
Код: vbnet
1.
  <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>



Чтение /запись в MailSlot базируется на ф-циях ReadFile/WriteFile. В случае WM_COPYDATA передается структура COPYDATASTRUCT.
И в том и другом случае речь идет о передаче НАБОРА БАЙТОВ а не строк, поэтому в оригинале нет отдельных определений "A" и "W"

Вот собственно не знаю как поступить.

Могу оставаться в ANSI (для этих методов):

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
'MailSlot
  Public Declare Function ReadFile Lib "kernel32" ( _
   ByVal hFile As IntPtr, _
   ByVal lpBuffer As String, _
   ByVal nNumberOfBytesToRead As Integer, _
   ByRef lpNumberOfBytesRead As Integer, _
   ByVal lpOverlapped As IntPtr) As Boolean 'два крайних параметра -Optional
  Public Declare Function WriteFile Lib "kernel32" ( _
   ByVal hFile As IntPtr, _
   ByVal lpBuffer As String, _
   ByVal nNumberOfBytesToWrite As Integer, _
   ByRef lpNumberOfBytesWritten As Integer, _
   ByVal lpOverlapped As IntPtr) As Boolean

'SendMessage(WM_COPYDATA)
  <StructLayout(LayoutKind.Sequential)>
  Public Structure COPYDATASTRUCT
    Dim dwData As IntPtr ' additional 32 bit data to pass
    Dim cbData As Integer ' length in bytes of data pointed by lpData
    Dim lpData As String ' pointer to data to be passed to the receiving app. '<MarshalAs(UnmanagedType.LPStr)>
  End Structure



Могу "мигрировать на Юникод"
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
'MailSlot
  Public Declare Unicode Function ReadFile Lib "kernel32" ( _
   ByVal hFile As IntPtr, _
   ByVal lpBuffer As String, _
   ByVal nNumberOfBytesToRead As Integer, _
   ByRef lpNumberOfBytesRead As Integer, _
   ByVal lpOverlapped As IntPtr) As Boolean 'два крайних параметра -Optional
  Public Declare Unicode Function WriteFile Lib "kernel32" ( _
   ByVal hFile As IntPtr, _
   ByVal lpBuffer As String, _
   ByVal nNumberOfBytesToWrite As Integer, _
   ByRef lpNumberOfBytesWritten As Integer, _
   ByVal lpOverlapped As IntPtr) As Boolean

'SendMessage(WM_COPYDATA)
   <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
  Public Structure COPYDATASTRUCT
    Dim dwData As IntPtr ' additional 32 bit data to pass
    Dim cbData As Integer ' length in bytes of data pointed by lpData
    Dim lpData As String ' pointer to data to be passed to the receiving app. '<MarshalAs(UnmanagedType.LPStr)>
  End Structure



Сложность выбора еще в том, что у меня есть C++(ANSI) -модуль, в котором также присутствует MailSlot , он обменивается c VB.Net -приложением (только EN-строки), но это же VB.Net обменивается с другим VB.Net.
Если посылать раздельно ANSI/Unicode (в разные приложения) можно без проблем, то приемник один (т.е. в него нельзя слать ANSI/Unicode кашу).

VB.Net компоненты могут передавать меж собой "русские" (не-EN) тексты.
От требования к системе: русский язык для не-юникод программ для "русской версии" я хочу отказаться.

Если я оставлю ANSI в этом вопросе, не получу ли я проблем с передачей русского текста (при отключенной поддержке для не-Юникод программ)? Комп то вроде по любому один и тот же. Как закодирует, так и раскодирует.
Как тут посоветуете поступить?


И еще.
Конечно не стоит мешать API с .Net,
хотя бы в случае с mailslot,
нельзя как-то заменить ReadFile/WriteFile на StreamWriter/Reader?
Т.е. явно задавать/определять кодировку при чтении записи в файл (т.е в Mailslot) UTF8 с флагом или как там его(недавно обсуждали)/Default ANSI, handle mailslot-а известен.???
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38875779
Фотография Konst_One
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
base64 кодируй при отправке, при приёме декодируй
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38875852
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
маршаллинг прарметров явно задай (как массив байтов с указаием параметра-длины) ,
буферу будет насрать на вызов A или U

Дмитрий77От требования к системе: русский язык для не-юникод программ для "русской версии" я хочу отказаться.
это правильно

Дмитрий77нельзя как-то заменить ReadFile/WriteFile на StreamWriter/Reader?
Т.е. явно задавать/определять кодировку при чтении записи в файл (т.е в Mailslot) UTF8 с флагом или как там его(недавно обсуждали)/Default ANSI, handle mailslot-а известен.???
никакого смысла. получил пакет в виде набора байтов - интерпретируй как хочешь, поток не поможет

можно рассмотреть вариант - во всех приложениях использовать UTF-8
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38875899
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77, при работе с набором байтов разницы между ANSI и Unicode не будет. Однако по моему ты неправильно объявил ReadFile/WriteFile/COPYDATASTRUCT. Ты говоришь об обмена байтами, а используешь тип String для lpBuffer/lpData. По моему там должен быть IntPtr т.к. в С/С++ они объявлены как LPVOID.
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38875921
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Давайте про mailslot только рассуждать чтоб не путаться.

Ну, насколько я понимаю,
что если
1) строка "русская"
2) язык системы для не-юникода - "китайский"
3) WriteFile и ReadFile декларированы как ANSI т.е. (...ByVal lpBuffer As String)
то на выходе все таки получим фигню а не "русский".
Т.е. не сумеет он в общем случае кодировать в ANSI и декодировать из ANSI.
Так? Т.е. все-таки передавать надо Unicode?


>маршаллинг прарметров явно задай
Какая разница в данном случае написать слово Unicode перед ф-цией или лепить <Marshall.> перед as String?.
Задекларировав функции как Declare Unicode Function , ну или прописав маршалинг параметров как Юникод я эту задачу решаю (передается Юникод хз там в какой кодировке согласно API понятиям но без искажений). Естественно хочется As String для простоты использования.
===
Но остается тогда нерешенной следующая задача:
Предположим есть exe, есть mailslot.
Одно приложение шлет в него ANSI (C++, только EN, переписывать/перекомпилировать на Unicode не буду).
Другое приложение шлет в него Unicode.
Как извернуться (с единственным mailslot)?

Объясню почему я вспомнил про StreamWriter/Reader.
Потому что mailslot -по сути файл с операциями записи чтения в него.
В StreamWriter/Reader есть параметр Encoder, применяя который можно задать BOM (явное указание UTF8 например).
Т.е. нельзя ли эту автоматику как то присобачить?
Приходит строка с BOM -конвертируется из UTF8, без BOM -значит ANSI.
Хотя опять же, не уверен. BOM же в начало файла ставится а как это на MailSlot переложить...

Функции для MailSlot у меня со времен VB6 такие, декларации для ANSI и Unicode я привел выше.

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
  Public Function MailSlotReadFirst(ByRef m_Message As String, ByRef m_MsgCount As Integer) As Boolean
    'ПРИЕМНИК(сервер) ф-ция читает первое сообщение если есть
    'возвращает True, если есть хотя бы одно и оно было прочитано
    'm_Message (Out)-текст сообщения, если прочли
    'm_MsgCount -к-во сообщений оставшихся после чтения (без учета прочитанного)

    MailSlotReadFirst = False

    Dim lBufferSize As Integer
    m_Message = ""
    m_MsgCount = 0
    GetMailslotInfo(hMailSlotHandle, 0, lBufferSize, m_MsgCount, 0)
    If m_MsgCount > 0 Then
      Dim sBuffer As String
      ' Create a buffer
      sBuffer = StrDup(lBufferSize, Chr(0))

      ' Read data: optional параметры ф-ции не используем
      If ReadFile(hMailSlotHandle, sBuffer, lBufferSize, 0, IntPtr.Zero) Then
        m_Message = sBuffer
        m_MsgCount = m_MsgCount - 1
        MailSlotReadFirst = True
      End If
    End If
  End Function

  Public Function SendMessageToMailSlot(ByVal sMessage As String, ByVal sMailSlot As String, _
   Optional ByVal CPP As Boolean = False) As Boolean
    'ПЕРЕДАТЧИК(клиент)ф-ция отправляет сообщение sMessage серверу с именем sMailSlot
    'если сервер не запущен, то сообщение не отправляется
    Dim hFile As IntPtr
    Dim m_tSA As SECURITY_ATTRIBUTES

    hFile = CreateFile(sMailSlot, _
                       GENERIC_WRITE, _
                       FILE_SHARE_READ, _
                       m_tSA, _
                       OPEN_EXISTING, _
                       FILE_ATTRIBUTE_NORMAL, _
                       IntPtr.Zero)
    If hFile = INVALID_HANDLE_VALUE Then Return False

    If CPP Then
      SendMessageToMailSlot = WriteFile(hFile, sMessage, Strings.Len(sMessage) + 1, 0, IntPtr.Zero) 'добавляем '\0'
    Else
      SendMessageToMailSlot = WriteFile(hFile, sMessage, Strings.Len(sMessage), 0, IntPtr.Zero) 'при отправке в VB не добавляем '\0'
    End If
    CloseHandle(hFile)
  End Function



Видимо надо тест-проект создавать и играться.
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38875933
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bazileДмитрий77, при работе с набором байтов разницы между ANSI и Unicode не будет. Однако по моему ты неправильно объявил ReadFile/WriteFile/COPYDATASTRUCT. Ты говоришь об обмена байтами, а используешь тип String для lpBuffer/lpData. По моему там должен быть IntPtr т.к. в С/С++ они объявлены как LPVOID.
Ты абсолютно прав. В оригинале там конечно байты, а не строки. По этой причине в ReadFile/WriteFile/COPYDATASTRUCT и нет деления на "A" и "W".
Но я то знаю что я работаю ТОЛЬКО со строками. Поэтому могу довериться автоматике/маршалингу.
Если объявлю ReadFile/WriteFile как Unicode -буду передавать Unicode-строки, если ANSI -то ANSI. главное чтоб одинаково для Read и Write.
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38875942
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий773) WriteFile и ReadFile декларированы как ANSI т.е. (...ByVal lpBuffer As String)
ну не надо буфер как строку передавать- передавай байты.
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38875974
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Но остается тогда нерешенной следующая задача:
Предположим есть exe, есть mailslot.
Одно приложение шлет в него ANSI (C++, только EN, переписывать/перекомпилировать на Unicode не буду).
Другое приложение шлет в него Unicode.
Как извернуться (с единственным mailslot)?

Объясню почему я вспомнил про StreamWriter/Reader.
Потому что mailslot -по сути файл с операциями записи чтения в него.
В StreamWriter/Reader есть параметр Encoder, применяя который можно задать BOM (явное указание UTF8 например).
Т.е. нельзя ли эту автоматику как то присобачить?
Раз ты контролиуешь обе стороны обмена, то можно. При наличии ВОМ класс StreamReader игнорирует переданную ему кодировку и использует кодировку указанную через BOM. Сам массив данных можно трактовать как поток с помощью MemoryStream. Передавать при этом мы будем всегда массив байтов. Код фукнций подготовки данных и их чтения на стороне .NEТ можно организовать примерно так:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
Function StringToBytes(ByVal text As String) As Byte()
	Dim utf8 As New UTF8Encoding(True) ' Указываем всегда использовать BOM
	Return utf8.GetBytes(text)
End Function

Function BytesToString(ByVal data() As Byte) As String
	Using mstream As New MemoryStream(data)
		Using reader As New StreamReader(mstream, Encoding.Default)
			return reader.ReadToEnd()
		End Using
	End Using
End Function
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38876015
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропилну не надо буфер как строку передавать- передавай байты.
А что это даст кроме гимора с конвертацией в байты и обратно?
Я ж все равно не угадаю юникодные это байты или ANSI (если мне приходят "наборы двух типов", а чтобы понять от кого пришло надо прочесть чего там написано, а не зная ANSI или Unicode и не прочтешь, если только собственные "байт-метки" ставить, но это уже маразм).

По хорошему декларировать все как Юникод (As String) и все типа в шоколаде.
Это если не выходя за пределы .Net. Это я сделаю, это работает.

Но что тогда делать с C++ которое отправляет и принимает ANSI.
Причем сам C++ проект -чистое ANSI и Юникод там нафиг не нужен (для всего проекта).

Код там такой:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
'прием
  char buffer[1000];
  DWORD NumberOfBytesRead;
  for (;;)
  {
    if (ReadFile(hMailSlotHandle, buffer, 1000, &NumberOfBytesRead, NULL)!=0) {
      buffer[NumberOfBytesRead]='\0'; //отсекаем мусор -не надо, надо '\0' добавлять к сообщению
      PString str_message =  PString((LPCTSTR)buffer);
...


'отправка
BOOL SendMessageToMailSlot(LPCTSTR lpszMessage, LPCTSTR SlotName)
{
  HANDLE hFile;

  hFile = CreateFile(SlotName,
   GENERIC_WRITE,
   FILE_SHARE_READ,
   (LPSECURITY_ATTRIBUTES) NULL,
   OPEN_EXISTING,
   FILE_ATTRIBUTE_NORMAL,
   (HANDLE) NULL);
  if (hFile == INVALID_HANDLE_VALUE)
    return FALSE;

  BOOL fResult;
  DWORD cbWritten; 
  fResult = WriteFile(hFile, 
   lpszMessage,
   (DWORD) lstrlen(lpszMessage)*sizeof(TCHAR),
   &cbWritten,
   (LPOVERLAPPED) NULL);
  CloseHandle(hFile);
  return fResult;
}

'Ну например...
      std::string buffer;
...
      SendMessageToMailSlot(TEXT(buffer.c_str()),
       TEXT("\\\\.\\mailslot\\MailSlotMyName"));



Вот как эти две "функции" переписать на прием/отправку именно Юникода? При том что весь проект в ANSI.
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38876042
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bazile,

т.е. я правильно понимаю, что при отправке юникод сообщения(UTF-8) я BOM добавляю в начало КАЖДОГО сообщения (массива байтов) - т.е на этапе формирования именно массива байтов?
Соответственно если надо отправить в ANSI, то делаю массив с кодировкой .Default?
А на обратном пути автоматика на основании наличия/отсутствия BOM?
При этом конечно ReadFile/WriteFile декларирую однозначно с массивом байтов (IntPtr, надо смотреть) - инвариантно для обоих случаев - как в оригинале.

Ну по крайне мере чутье не обмануло. Хотя я имел ввиду запись BOM в MailSlot (интерпретируя его как файл).
Идея дошла. Спасибо. Пошел делать тест-проект, играться и переписывать свои ф-ции.
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38876072
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77т.е. я правильно понимаю, что при отправке юникод сообщения(UTF-8) я BOM добавляю в начало КАЖДОГО сообщения (массива байтов) - т.е на этапе формирования именно массива байтов?
Соответственно если надо отправить в ANSI, то делаю массив с кодировкой .Default?
А на обратном пути автоматика на основании наличия/отсутствия BOM?
Да.

Дмитрий77Хотя я имел ввиду запись BOM в MailSlot (интерпретируя его как файл).
Никто не мешает тебе написать класс MailSlotStream инкапсулирующий всю эту логику.
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38876119
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bazileДмитрий77Хотя я имел ввиду запись BOM в MailSlot (интерпретируя его как файл).
Никто не мешает тебе написать класс MailSlotStream инкапсулирующий всю эту логику.
Не-не, здесь нет никакой здравой логики. Я то хотел по hMailSlotHandle открыть его как файл и использовать StreamWriter/Reader, ВМЕСТО ReadFile/WriteFile , возможно частично сделать что-то здесь можно, например указав "\\.\mailslot\MailSlotMyName" в качестве пути к файлу (на запись возможно да, если атрибуты - аналог CreateFile подберу), но я сомневаюсь что что-то путное выйдет. Короче счас попробую твою идею с подготовкой/чтением массива байтов + родные ReadFile/WriteFile.
А уж потом посмотрю можно ли ему сообщение послать чисто через StreamWriter.
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38876168
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77его как файл и использовать StreamWriter/Reader, ВМЕСТО ReadFile/WriteFile ,


это НИКАК не влияет на решение задачи ( кодировку текста)
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38876211
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Не-не, здесь нет никакой здравой логики.
"Спасибо" за высокую оценку. В моем понимании это наоборот прекрасно укладывается в .NET логику. Ты хочешь работать с mailslot через StreamWriter который умеет оборачиваться вокруг другого потока. Т.к. в нет класса наследника Stream который умеет работать с MailSlot, то значит можно написать свой класс для этой задачи.

Дмитрий77Я то хотел по hMailSlotHandle открыть его как файл и использовать StreamWriter/Reader, ВМЕСТО ReadFile/WriteFile
Конструктор FileStream позволяет передать дескриптор уже открытого потока. Затем FileStream можно передать StreamWriter/Reader. Попробуй так.
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38876277
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bazile
Код: vbnet
1.
2.
3.
4.
Function StringToBytes(ByVal text As String) As Byte()
	Dim utf8 As New UTF8Encoding(True) ' Указываем всегда использовать BOM
	Return utf8.GetBytes(text)
End Function

Так не хочет BOM к массиву пре-приписывать.

Вроде вот так получается (до конца еще не доделал):
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
   Dim buffer As Byte()
    If bUTF8 Then 'отправлять Юникод
      Dim utf8 As New System.Text.UTF8Encoding(True) ' Указываем всегда использовать BOM
      Dim pre As Byte() = utf8.GetPreamble 'если только ручками BOM дописывать
      Dim body As Byte() = utf8.GetBytes(sMessage)
      ReDim buffer(0 To pre.Length + body.Length - 1)
      Array.Copy(pre, buffer, pre.Length)
      Array.Copy(body, 0, buffer, pre.Length, body.Length)


Проще нельзя этот BOM приписать?
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38876298
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Проще нельзя этот BOM приписать?
можно
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38876325
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилДмитрий77Проще нельзя этот BOM приписать?
можно
Ты вот это имел ввиду?
Код: vbnet
1.
2.
      buffer = _
       System.Text.Encoding.UTF8.GetPreamble().Concat(System.Text.Encoding.UTF8.GetBytes(sMessage)).ToArray


Это на .Net2 не фурычит, а я как ты возможно помнишь не рискну отказываться хотя бы от совместимости кода.

Или что-то другое имелось в виду?
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38876386
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну вот вроде допилил, все типа работает:

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
Public Class Form1

  Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
    MakeMailSlot("\\.\mailslot\MailSlotMyName")
  End Sub

  Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed
    CloseMailSlot() 'необх. нет, т.к. он уничтожится по любому вместе с закрытием приложения
  End Sub

'я беру интервал 1 секунда  
Private Sub TimerMailSlot_Tick(sender As Object, e As EventArgs) Handles TimerMailSlot.Tick
    ReadApplyMessages_MailSlot()
  End Sub

  Public Sub ReadApplyMessages_MailSlot()
    Dim the_str As String = vbNullString
    Dim the_msgCount As Integer
    Do
      If MailSlotReadFirst(the_str, the_msgCount) Then
        '---обработка сообщения---
        MsgBox(the_str)
        '---обработка сообщения---
        If the_msgCount = 0 Then Exit Do
      Else
        Exit Do
      End If
    Loop
  End Sub

  Private Sub ButtonSendANSI_Click(sender As Object, e As EventArgs) Handles ButtonSendANSI.Click
    SendMessageToMailSlot(TextBoxToSend.Text, "\\.\mailslot\MailSlotMyName", False)
  End Sub

  Private Sub ButtonSendUTF8_Click(sender As Object, e As EventArgs) Handles ButtonSendUTF8.Click
    SendMessageToMailSlot(TextBoxToSend.Text, "\\.\mailslot\MailSlotMyName", True)
  End Sub
End Class



Module MailSlots
  Public Structure SECURITY_ATTRIBUTES
    Dim nLength As Integer
    Dim lpSecurityDescriptor As IntPtr
    Dim bInheritHandle As Boolean
  End Structure

  'File Attribute Constants
  Public Const FILE_ATTRIBUTE_NORMAL = &H80

  Public ReadOnly INVALID_HANDLE_VALUE As IntPtr = New IntPtr(-1)

  'File Management Functions

  'dwDesiredAccess - The requested access to the file or device, which can be summarized as read, write, both...
  Public Const GENERIC_WRITE = &H40000000
  'dwShareMode - The requested sharing mode of the file or device
  Public Const FILE_SHARE_READ = &H1
  'dwCreationDisposition -An action to take on a file or device that exists or does not exist.
  Public Const OPEN_EXISTING = 3

  Public Declare Unicode Function CreateFile Lib "kernel32" _
   Alias "CreateFileW" ( _
   ByVal lpFileName As String, _
   ByVal dwDesiredAccess As Integer, _
   ByVal dwShareMode As Integer, _
   ByRef lpSecurityAttributes As SECURITY_ATTRIBUTES, _
   ByVal dwCreationDisposition As Integer, _
   ByVal dwFlagsAndAttributes As Integer, _
   ByVal hTemplateFile As IntPtr) As IntPtr

  Public Declare Function ReadFile Lib "kernel32" ( _
   ByVal hFile As IntPtr, _
   ByVal lpBuffer As Byte(), _
   ByVal nNumberOfBytesToRead As Integer, _
   ByRef lpNumberOfBytesRead As Integer, _
   ByVal lpOverlapped As IntPtr) As Boolean 'два крайних параметра -Optional
  Public Declare Function WriteFile Lib "kernel32" ( _
   ByVal hFile As IntPtr, _
   ByVal lpBuffer As Byte(), _
   ByVal nNumberOfBytesToWrite As Integer, _
   ByRef lpNumberOfBytesWritten As Integer, _
   ByVal lpOverlapped As IntPtr) As Boolean

  'Mailslot Functions
  Public Declare Unicode Function CreateMailslot Lib "kernel32" _
   Alias "CreateMailslotW" ( _
   ByVal lpName As String, _
   ByVal nMaxMessageSize As Integer, _
   ByVal lReadTimeout As Integer, _
   ByRef lpSecurityAttributes As SECURITY_ATTRIBUTES) As IntPtr
  Public Declare Function GetMailslotInfo Lib "kernel32" ( _
   ByVal hMailslot As IntPtr, _
   ByRef lpMaxMessageSize As Integer, _
   ByRef lpNextSize As Integer, _
   ByRef lpMessageCount As Integer, _
   ByRef lpReadTimeout As Integer) As Boolean

  'Handle and Object Functions
  Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As IntPtr) As Boolean

  Public hMailSlotHandle As IntPtr

  Public Function MakeMailSlot(ByVal lpszSlotName As String) As Boolean
    'ПРИЕМНИК(сервер) ф-ция создает MailSlot с именем lpszSlotName
    'невозможно создать более одного MailSlot с заданным именем
    Dim m_tSA As SECURITY_ATTRIBUTES

    If Strings.Len(lpszSlotName) = 0 Then
      ' No slotname
      hMailSlotHandle = INVALID_HANDLE_VALUE
      MakeMailSlot = False
      Exit Function
    End If

    ' The handle to the slot
    hMailSlotHandle = CreateMailslot(lpszSlotName, 0, 0, m_tSA)

    MakeMailSlot = (hMailSlotHandle <> INVALID_HANDLE_VALUE)
  End Function

  Public Sub CloseMailSlot()
    'ПРИЕМНИК(сервер) ф-ция уничтожает MailSlot
    'При этом все непрочитанные сообщения также уничтожаются
    'При закрытии приложения (включая принудительное типа End Task/kill) MailSlot и сообщения также уничтожатся
    If hMailSlotHandle <> INVALID_HANDLE_VALUE Then
      CloseHandle(hMailSlotHandle)
      hMailSlotHandle = INVALID_HANDLE_VALUE
    End If
  End Sub

  Public Function MailSlotReadFirst(ByRef m_Message As String, ByRef m_MsgCount As Integer) As Boolean
    'ПРИЕМНИК(сервер) ф-ция читает первое сообщение если есть
    'возвращает True, если есть хотя бы одно и оно было прочитано
    'm_Message (Out)-текст сообщения, если прочли
    'm_MsgCount -к-во сообщений оставшихся после чтения (без учета прочитанного)

    MailSlotReadFirst = False

    Dim lBufferSize As Integer
    m_Message = ""
    m_MsgCount = 0
    GetMailslotInfo(hMailSlotHandle, 0, lBufferSize, m_MsgCount, 0)
    If m_MsgCount > 0 Then
      Dim sBuffer(lBufferSize - 1) As Byte

      ' Read data: optional параметры ф-ции не используем
      If ReadFile(hMailSlotHandle, sBuffer, lBufferSize, 0, IntPtr.Zero) Then
        Using mstream As New IO.MemoryStream(sBuffer)
          Using reader As New IO.StreamReader(mstream, System.Text.Encoding.Default, True)
            m_Message = reader.ReadToEnd()
          End Using
        End Using
        m_MsgCount = m_MsgCount - 1
        MailSlotReadFirst = True
      End If
    End If
  End Function

  Public Function SendMessageToMailSlot(ByVal sMessage As String, ByVal sMailSlot As String, _
   Optional ByVal bUTF8 As Boolean = True, Optional ByVal CPP As Boolean = False) As Boolean
    'ПЕРЕДАТЧИК(клиент)ф-ция отправляет сообщение sMessage серверу с именем sMailSlot
    'если сервер не запущен, то сообщение не отправляется
    'bUTF8 -кодировать в UTF8 CPP-если true, то добавлять '\0' в конце
    Dim hFile As IntPtr
    Dim m_tSA As SECURITY_ATTRIBUTES

    hFile = CreateFile(sMailSlot, _
                       GENERIC_WRITE, _
                       FILE_SHARE_READ, _
                       m_tSA, _
                       OPEN_EXISTING, _
                       FILE_ATTRIBUTE_NORMAL, _
                       IntPtr.Zero)
    If hFile = INVALID_HANDLE_VALUE Then Return False

    If CPP Then sMessage = sMessage & Chr(0) 'при отправке в VB не добавляем '\0'

    Dim buffer As Byte()
    If bUTF8 Then 'отправлять Юникод
      'Указываем всегда использовать BOM
      Dim pre As Byte() = System.Text.Encoding.UTF8.GetPreamble()
      Dim body As Byte() = System.Text.Encoding.UTF8.GetBytes(sMessage)
      ReDim buffer(pre.Length + body.Length - 1)
      Array.Copy(pre, buffer, pre.Length)
      Array.Copy(body, 0, buffer, pre.Length, body.Length)
      'System.Text.Encoding.UTF8.GetPreamble().Concat(System.Text.Encoding.UTF8.GetBytes(sMessage)).ToArray
    Else 'отправлять ANSI
      buffer = System.Text.Encoding.Default.GetBytes(sMessage)
    End If

    SendMessageToMailSlot = WriteFile(hFile, buffer, buffer.Length(), 0, IntPtr.Zero)
    CloseHandle(hFile)
  End Function
End Module



Bazile, спасибо.

bazileКонструктор FileStream позволяет передать дескриптор уже открытого потока. Затем FileStream можно передать StreamWriter/Reader. Попробуй так.
Там все методы с Intptr первым параметром "устаревшие" (компилятор подчеркивает).
Я попробовал интереса ради. Типа через задницу работает (отправка), но при этом вместо одного сообщения отправляется 2, первое пустое, а нужное приходит с задержкой в несколько секунд, уж не знаю чего там эта муть делает.
При попытке подсунуть имя mailslot-а в FileStream или StreamWriter всегда имеем:
Дополнительные сведения: FileStream не открывает устройства Win32, такие как логические диски и ленточные накопители. Избегайте использования "\\.\" в пути.

Через API WriteFile/ReadFile все работает как и положено четко.
Данный совет приписывать BOM к массиву байтов озвученную проблему "автоматики при приеме" решил.

====

По mailslot у меня один наверно вопрос еще.
Я использую таймер который запускает ф-цию ReadApplyMessages_MailSlot() раз в секунду (в коде формы, код под спойлером).
Т.е. время ожидания и обработки сообщения может затянуться (максимум на 1 секунду).
В принципе для моих целей это приемлимо, но все же.
В VB6 к сожалению с многопоточностью хреново.

По хорошему это надо крутить циклом в отдельном потоке.
Не подскажете как в .Net лучше сделать?
Есть еще опасения что при выполнении команд буду нарываться на ошибки типа "вы пытаетесь дорваться до чего-то что было создано в другом потоке", посему особо не горю желанием такие штуки сгоряча и без опыта имплементировать.
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38876447
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Или что-то другое имелось в виду?
да
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
            MemoryStream m = new MemoryStream();
            using (StreamWriter w = new StreamWriter(m, Encoding.UTF8))
            {
                w.Write("bla-bla");
                w.Flush();
                long sz = m.Length;
                byte[] buf = m.GetBuffer();
            }

...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38876448
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Есть еще опасения что при выполнении команд буду нарываться на ошибки типа "вы пытаетесь дорваться до чего-то что было создано в другом потоке"

настоящий программист документацию не читает
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38876535
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилДмитрий77Или что-то другое имелось в виду?да
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
            MemoryStream m = new MemoryStream();
            using (StreamWriter w = new StreamWriter(m, Encoding.UTF8))
            {
                w.Write("bla-bla");
                w.Flush();
                long sz = m.Length;
                byte[] buf = m.GetBuffer();
            }


Уже подумал о том что MemoryStream можно использовать обратно с StreamWriter (по аналогии с распаковкой в строку).
Спасибо за код.

Тогда лучше думаю так:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
    Dim buffer As Byte()
    Using mstream As New IO.MemoryStream()
      Using writer As New IO.StreamWriter(mstream, IIf(bUTF8, System.Text.Encoding.UTF8, System.Text.Encoding.Default))
        writer.Write(sMessage)
        writer.Flush()
        buffer = mstream.ToArray()
      End Using
    End Using



Иначе придется обрезать лишнее:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
    Dim buffer As Byte()
    Using mstream As New IO.MemoryStream()
      Using writer As New IO.StreamWriter(mstream, IIf(bUTF8, System.Text.Encoding.UTF8, System.Text.Encoding.Default))
        writer.Write(sMessage)
        writer.Flush()
        buffer = mstream.GetBuffer()
        ReDim Preserve buffer(mstream.Length - 1)
        buffer = mstream.ToArray()
      End Using
    End Using



ИзопропилДмитрий77Есть еще опасения что при выполнении команд буду нарываться на ошибки типа "вы пытаетесь дорваться до чего-то что было создано в другом потоке"

настоящий программист документацию не читает

По MailSlot я документацию читал и примеры смотрел. Иначе б этот вопрос не возник.
Просто это делалось под VB6 и таймер был выбран как наиболее разумный способ чтения MailSlot (VB6 при создании потока через API крашит, поэтому научился обходиться без них).

.Net документацию по потокам - нет, не читал пока. Насколько понимаю, тема не очень тривиальная и с ней надо разбираться отдельно. Так что пока оставлю ту логику что есть, вопрос снимаю.
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38876538
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вызов метода в UI потоке - control.Invoke - ничего сложного, код в форме от таймерного отличаться не будет

Массив из memoryStream - не твой - просто скопируй нужное количество байтов в свой массив
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38876561
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилМассив из memoryStream - не твой - просто скопируй нужное количество байтов в свой массив
Ну.
А разве buffer = mstream.ToArray() именно это и не делает в одну строчку?
Просто все копирования mstream.GetBuffer() с учетом mstream.Length -оно ни чуть не менее муторней чем тупое сложение массивов System.Text.Encoding.UTF8.GetPreamble() и System.Text.Encoding.UTF8.GetBytes(sMessage) - изначальный вариант

ИзопропилВызов метода в UI потоке - control.Invoke - ничего сложного, код в форме от таймерного отличаться не будет
Что значит не будет? Получил я message, мне например надо: нажать кнопку на форме, выгрузить форму, поменять надпись на форме... выполнить какую нибудь public function из модуля, которая на эту форму ссылается и т.п. Это хорошо еще если я к этой форме только в режиме чтения обращаюсь, или просто какие-то левые дела в этом ново-потоке делаю.
А в общем случае это надо переписывать код, с отработкой заново всех потенциальных глюков.
Не, давай забьем пока эту тему.
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38876645
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Что значит не будет?
Есть форме(контроле) метод.

без разницы - из таймера Invoke делать или из другого потока. Нет никаких глюков. В UI потоке будет вызываться
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38876935
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вроде вот с WM_COPYDATA сделал по аналогии:

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
Imports System.Runtime.InteropServices

Module ModuleCopyData
  Public Const WM_COPYDATA = &H4A

  <StructLayout(LayoutKind.Sequential)>
  Public Structure COPYDATASTRUCT
    Dim dwData As IntPtr ' additional 32 bit data to pass
    Dim cbData As Integer ' length in bytes of data pointed by lpData
    Dim lpData As IntPtr 'Byte() ' pointer to data to be passed to the receiving app. 
  End Structure

  Public Declare Unicode Function SendMessage_COPYDATASTRUCT Lib "user32" Alias "SendMessageW" _
   (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByRef lParam As COPYDATASTRUCT) As Integer

  Public Sub SendMessageCopyData(ByVal dwData As Integer, ByVal sMessage As String, ByVal hwndTarget As IntPtr, _
   Optional ByVal bUTF8 As Boolean = True, Optional ByVal AddZero As Boolean = False)
    'dwData -тип сообщения (например номер команды)
    'sMessage -текстовое сообщение
    'hwndTarget -окно - получатель сообщения
    'bUTF8 -кодировать в UTF8; AddZero-если true, то добавлять '\0' в конце

    If AddZero Then sMessage = sMessage & Chr(0) 'в VB6 при приеме иногда читал байты по указателю до символа '\0'

    Dim buffer As Byte()
    Using mstream As New IO.MemoryStream()
      Using writer As New IO.StreamWriter(mstream, IIf(bUTF8, System.Text.Encoding.UTF8, System.Text.Encoding.Default))
        writer.Write(sMessage)
        writer.Flush()
        buffer = mstream.ToArray()
      End Using
    End Using
    Dim cds As New COPYDATASTRUCT
    cds.dwData = CType(dwData, IntPtr) 'идентифицирует тип передаваемых данных
    cds.cbData = buffer.Length
    Dim lpData As IntPtr = Marshal.AllocHGlobal(buffer.Length)
    Marshal.Copy(buffer, 0, lpData, buffer.Length)
    cds.lpData = lpData

    Call SendMessage_COPYDATASTRUCT(hwndTarget, WM_COPYDATA, hwndTarget, cds)

    Marshal.FreeHGlobal(lpData)

  End Sub

End Module

'=====

Imports System.Runtime.InteropServices

Public Class Form1
  Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    'Debug.WriteLine(m.ToString())

    Select Case m.Msg
      Case WM_COPYDATA
        Dim the_str As String
        Dim cds As COPYDATASTRUCT = CType(Marshal.PtrToStructure(m.LParam, GetType(COPYDATASTRUCT)), COPYDATASTRUCT)
        Dim buffer(cds.cbData - 1) As Byte
        Marshal.Copy(cds.lpData, buffer, 0, cds.cbData)
        Using mstream As New IO.MemoryStream(buffer)
          Using reader As New IO.StreamReader(mstream, System.Text.Encoding.Default, True)
            the_str = reader.ReadToEnd()
          End Using
        End Using
        MsgBox(the_str & ";len=" & Strings.Len(the_str))
      Case Else
    End Select

    ' Forward message to base WndProc.
    MyBase.WndProc(m)
  End Sub

  Private Sub ButtonSendMeANSI_Click(sender As Object, e As EventArgs) Handles ButtonSendMeANSI.Click
    SendMessageCopyData(1, TextBoxSendMeANSI.Text, Me.Handle, False, False)
  End Sub

  Private Sub ButtonSendMeUNI_Click(sender As Object, e As EventArgs) Handles ButtonSendMeUNI.Click
    SendMessageCopyData(2, TextBoxSendMeUNI.Text, Me.Handle, True, False)
  End Sub
End Class



Но у меня получилось только с Dim lpData As IntPtr + Marshal.AllocHGlobal + Marshal.FreeHGlobal

А упрощенный вариант почему-то не работает.
Код: vbnet
1.
2.
3.
4.
5.
6.
  <StructLayout(LayoutKind.Sequential)>
  Public Structure COPYDATASTRUCT
    Dim dwData As IntPtr ' additional 32 bit data to pass
    Dim cbData As Integer ' length in bytes of data pointed by lpData
    Dim lpData As Byte() ' pointer to data to be passed to the receiving app.
  End Structure

Собственно код:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
  Public Structure COPYDATASTRUCT
    Dim dwData As IntPtr ' additional 32 bit data to pass
    Dim cbData As Integer ' length in bytes of data pointed by lpData
    Dim lpData As Byte() ' pointer to data to be passed to the receiving app.
  End Structure

  Public Sub SendMessageCopyData(ByVal dwData As Integer, ByVal sMessage As String, ByVal hwndTarget As IntPtr, _
   Optional ByVal bUTF8 As Boolean = True, Optional ByVal AddZero As Boolean = False)
    'dwData -тип сообщения (например номер команды)
    'sMessage -текстовое сообщение
    'hwndTarget -окно - получатель сообщения
    'bUTF8 -кодировать в UTF8; AddZero-если true, то добавлять '\0' в конце

    If AddZero Then sMessage = sMessage & Chr(0) 'в VB6 при приеме иногда читал байты по указателю до символа '\0'

    Dim cds As New COPYDATASTRUCT
    Using mstream As New IO.MemoryStream()
      Using writer As New IO.StreamWriter(mstream, IIf(bUTF8, System.Text.Encoding.UTF8, System.Text.Encoding.Default))
        writer.Write(sMessage)
        writer.Flush()
        cds.lpData = mstream.ToArray()
      End Using
    End Using
    cds.dwData = CType(dwData, IntPtr) 'идентифицирует тип передаваемых данных
    cds.cbData = cds.lpData.Length

    Call SendMessage_COPYDATASTRUCT(hwndTarget, WM_COPYDATA, hwndTarget, cds)

  End Sub

'---
  Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    'Debug.WriteLine(m.ToString())

    Select Case m.Msg
      Case WM_COPYDATA
        Dim the_str As String
        Dim cds As COPYDATASTRUCT = CType(Marshal.PtrToStructure(m.LParam, GetType(COPYDATASTRUCT)), COPYDATASTRUCT)
        Using mstream As New IO.MemoryStream(cds.lpData)
          Using reader As New IO.StreamReader(mstream, System.Text.Encoding.Default, True)
            the_str = reader.ReadToEnd()
          End Using
        End Using
        MsgBox(the_str & ";len=" & Strings.Len(the_str))
      Case Else
    End Select

    ' Forward message to base WndProc.
    MyBase.WndProc(m)
  End Sub


Т.е. он работает, но если посылать сообщение своему окну.
А если чужому, то lpData As Byte() в target не читается (ptr получает а содержимое отсутствует).

Для сравнения
Если писать Dim lpData As String, то работает (с оговоркой про ANSI/Unicode естественно)

В Mailslot+ReadFile/WriteFile,
ByVal lpBuffer As Byte() на ура прокатило без всяких IntPtr.

Где напортачил в нижнем коде? М.б.
<MarshalAs(UnmanagedType. ???> Dim lpData As Byte() какой нибудь надо подставить?
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38876945
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

в маршале полезно указывать, какой параметр содержит длину и в каком направлении передаются данные
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38876981
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропилкакой параметр содержит длину и в каком направлении передаются данные
Это как?
Ну, cbData в принципе содержит длину lpData , хотя честно говоря cbData -параметр на мой взгляд излишний (вспомогательный), т.е. если массив то его длина и так известна. В VB6, имея указатель, я тупо читал память до '\0' -символа например.
Во всяком случае не-указание cbData (или указание неверного значения) к крашу посылателя не приведут и приниматель обычно может вытащить данные и без cbData.

Пытаюсь вот читать:
Маршалинг по умолчанию для массивов
но чет не нахожу ответа.
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38877243
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Короче так и не понял как Dim lpData As Byte() лечить, оставлю Dim lpData As IntPtr,
собственно и в VB6 я всегда передавал именно указатель на первый элемент байт-массива

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
cds.lpData = VarPtr(StringToMas(str_id).ByteStr(0))

Public Type StringToChar
  ByteStr() As Byte
End Type

Public Function StringToMas(str As String) As StringToChar
  Dim data As StringToChar
  Dim temp As String
  Dim Ln As Long
  Dim i As Long
  Dim Ptr As Long
  temp = str
  Ln = Len(temp)
  ReDim data.ByteStr(0 To Ln)
  If Ln > 0 Then
    For i = 0 To Ln - 1
      data.ByteStr(i) = Asc(Mid(temp, i + 1, 1))
    Next i
  End If
  data.ByteStr(Ln) = 0
  StringToMas = data
End Function

===
Кстати интереса ради.
Апишная "W" (CharSet:=CharSet.Unicode)
это не UTF8
(собственно это очевидно).
Еще как понял В UTF8 EN-символ кодируется одним байтом, в "Unicode" все кодируется двумя байтами.
А какой ".Net " -кодировке соответствует "W"?

===ИзопропилЕсть форме(контроле) метод.
без разницы - из таймера Invoke делать или из другого потока. Нет никаких глюков. В UI потоке будет вызываться
Расшифруешь?
Слово "Invoke" мне пока мало о чем говорит.
Из таймера я могу написать:
Me.Text="My caption"
Me.Function()
А поток меня как я понимаю пошлет с такими претензиями.
Или как вызвать этот замечательный "UI поток" ну скажем из Form_Load, чтоб из него все чего хошь можно сделать было?
Простенький совсем пример можно?
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38877342
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Простенький совсем пример можно?
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
 public partial class Form1 : Form
    {
        private delegate void MyDelegate(string parameter);
        public Form1()
        {
            InitializeComponent();
        }
        public void Do(string parameter)
        {
            this.Invoke(new MyDelegate(ui), parameter);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Do("ha-ha");  
        }
        private void ui( string parameter)
        {

        } 
    }


Дмитрий77А какой ".Net " -кодировке соответствует "W"?
что есть "соответсвует" ?
как маршаллинг опишешь так и будет.
символы и строки в .NET - UTF-16,
что в байтовых массивах живёт - заботы приложения.
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38877435
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилДмитрий77А какой ".Net " -кодировке соответствует "W"?
что есть "соответсвует" ?
как маршаллинг опишешь так и будет.
символы и строки в .NET - UTF-16,
что в байтовых массивах живёт - заботы приложения.

В смысле отправляем так (у меня только два варианта:(1) CharSet.Unicode и (2) CharSet.ANSI -набор из .UTF8, UTF7 здесь отсутствует):


Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
 <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
  Public Structure COPYDATASTRUCT_UNI
    Dim dwData As IntPtr ' additional 32 bit data to pass
    Dim cbData As Integer ' length in bytes of data pointed by lpData
    Dim lpData As String ' pointer to data to be passed to the receiving app. >
  End Structure

  Public Declare Unicode Function SendMessage_COPYDATASTRUCT_UNI Lib "user32" Alias "SendMessageW" _
   (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByRef lParam As COPYDATASTRUCT_UNI) As Integer

  Private Sub ButtonSendMeUNIOrig_Click(sender As Object, e As EventArgs) Handles ButtonSendMeUNIOrig.Click
    Dim cds As New COPYDATASTRUCT_UNI
    cds.dwData = CType(3, IntPtr) 'идентифицирует тип передаваемых данных
    cds.cbData = System.Text.Encoding.Unicode.GetByteCount(TextBoxSendMeUNI.Text)
    cds.lpData = TextBoxSendMeUNI.Text

    Call SendMessage_COPYDATASTRUCT_UNI(Me.Handle, WM_COPYDATA, Me.Handle, cds)

  End Sub



Ну, вот так удалось принять без искажений:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
  <StructLayout(LayoutKind.Sequential)>
  Public Structure COPYDATASTRUCT
    Dim dwData As IntPtr ' additional 32 bit data to pass
    Dim cbData As Integer ' length in bytes of data pointed by lpData
    Dim lpData As IntPtr ' pointer to data to be passed to the receiving app.
  End Structure

      Case WM_COPYDATA
        Dim the_str As String
        Dim cds As COPYDATASTRUCT = CType(Marshal.PtrToStructure(m.LParam, GetType(COPYDATASTRUCT)), COPYDATASTRUCT)
        Dim buffer(cds.cbData - 1) As Byte
        Marshal.Copy(cds.lpData, buffer, 0, cds.cbData)
        Using mstream As New IO.MemoryStream(buffer)
          Using reader As New IO.StreamReader(mstream, System.Text.Encoding.Unicode, True)
            the_str = reader.ReadToEnd()
          End Using
        End Using
        MsgBox(the_str & ";len=" & Strings.Len(the_str))
      Case Else
    End Select



Ну да, значит "W"=.Unicode=UTF-16 (как ты и сказал) -она значит и есть "классический Юникод".
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38877470
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилДмитрий77Простенький совсем пример можно?...

Не понимаю мысли.
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
Public Class Form1

  Private Delegate Sub MyDelegate(parameter As String)

  Public Sub DoIt(parameter As String)
    Me.Invoke(New MyDelegate(AddressOf ui), parameter)
  End Sub

  Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    DoIt("ha-ha")
  End Sub

  Private Sub ui(parameter As String)
    Do
      Me.Text = Now & " " & parameter
    Loop
  End Sub

End Class



А где тут другой поток?
InvokeВыполняет указанный делегат в том потоке, которому принадлежит основной дескриптор окна элемента управления, с указанным списком аргументов.

Нажал на кнопку. Время в шапке тикает, а форма сдохла -ни подвинуть, ни закрыть.
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38877479
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77А где тут другой поток?
без разницы откуда звать DoIt - из UI потока или любого другого

бесконечный цикл в процедуре ui - так нельзя, ui вызывается из цикла обработки сообщений,
пока не выйдешь из процедуры ui - окно не получит никаких сообщений
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38877832
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропил,

кажется дошло.

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
Imports System.Threading

Public Class Form1

  Private myThread As Thread
  Private Delegate Sub MyDelegate(parameter As String)

  Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
    myThread = New Thread(New ThreadStart(AddressOf ThreadFunction)) 'здесь запускаем поток
    myThread.Start()
  End Sub

  Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed
    myThread.Abort() 'здесь останавливаем/убиваем поток, чтоб предотвратить возможные исключения
  End Sub

  Private Sub ThreadFunction() 'здесь делаем "долбежные дела", может циклиться, может спать, может ждать
    Do
      'Thread.Sleep(100)
      Me.Invoke(New MyDelegate(AddressOf ui), Now().ToString) 'стучимся в ui, передавая параметр(ы)=команда
    Loop
  End Sub

  Private Sub ui(parameter As String) 'здесь обрабатываем команду в потоке формы(полный доступ к ее интерфейсу)
    Me.Text = parameter
  End Sub

  Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    MsgBox("Not blocked")
  End Sub
End Class



Ну, т.е. для случая mailslot я кручу цикл чтения сообщения в ThreadFunction.
Наверно не тупо Do...Loop а там параметры есть в MailSlot API на бесконечное ожидание нового сообщения.
По получении message я стучу в ui-ф-цию, например передавая это самое msg в нее в качестве parameter as string
Ну а ui уже занимается обработкой, имея доступ ко всем элементам формы.
Так?

Изопропилui вызывается из цикла обработки сообщений ,
пока не выйдешь из процедуры ui - окно не получит никаких сообщений
В принципе тогда я могу получить то же самое и без .Net конструкции Delegate+Invoke
Я могу послать "самому себе" SendMessage (Me.handle, WM_COPYDATA, 0, <parameter as string>) и обработать parameter в основной WndProc. Так ведь?

Почему я стал отказываться от WM_COPYDATA (ее преимущество, что она стучится в окно "как только так сразу") в пользу mailslot:
1) Потому что обработка WM_COPYDATA "блокирует" вызывающую сторону (приложение) на время обработки сообщения на принимающей стороне.
2) Потому что нельзя слать WM_COPYDATA между разными User-аккаунтами (например сервис System не может послать сообщение в User окно и наоборот), у mailslot этого недостатка нет.

А в комбинации
Mailslot+Thread+(Delegate+Invoke)
либо
Mailslot+Thread+(WM_COPYDATA своему окну)
вроде как при преимуществах mailslot решается вопрос с "получил как только так сразу".
Не, ну наверно раз в .Net то лучше уж первое.

Вроде все красиво.
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38877838
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

используйте Task'и, это удобнее и практичнее
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38877958
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman Mejtesиспользуйте Task'и,
Не рассматриваю, оно кажется с .Net 2 не совместимо.

Да Thread думаю нормально.
Счас попробую с MailSlot-Read процедурой потестить.

Вопрос:
myThread.Abort() в Form_Closed достаточно, чтоб поток "под занавес" не "нагадил"?
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38877962
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77В принципе тогда я могу получить то же самое и без .Net конструкции Delegate+Invoke
Я могу послать "самому себе" SendMessage (Me.handle, WM_COPYDATA, 0, <parameter as string>) и обработать parameter в основной WndProc. Так ведь?

ну не сенд, а post

Зачем тебе .net ? Бери в руки с++

иначе будешь трахать мозг себе и людям бесконечно
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38877964
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77myThread.Abort()
за такое завершение потока нужно больно бить по рукам.
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38877983
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропилну не сенд, а post
post с WM_COPYDATA не работает, обсуждалось много где неоднократно. Передаваемая структура (обсуждавшийся выше массив байтов) убьется раньше чем принимающая сторона ее прочтет. По этой же причине As Byte() наверняка и не работает.
Я думаю предложенное тобой Delegate+Invoke здесь оптимально, поэтому WM_COPYDATA можно не обсуждать.
Просто не сразу врубился в твой пример в том виде как ты его написал.

ИзопропилДмитрий77myThread.Abort()
за такое завершение потока нужно больно бить по рукам.
Бить не надо, лучше объясни.
Как его завершить в моем примере? Если ничего не сделать, то он продолжит Invok-ать в закрытую форму, что вызовет ошибку при закрытии формы.
А метода типа .Stop() я не вижу.
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38878002
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

создать флаг, при котором цикл завершится. Наверное так.
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38878007
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

поток должен ждать какого либо события чтобы завершиться штатно.

на худой конец может в случае отсутствия работы засыпать на какое-то время( например в ожидании завершения асинхронной операции с заданным таймаутом),
пробудившись проверять флаг запроса завершения
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38878252
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну вот, подправил логику чтения из Mailslot с учетом обсуждаемого:

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
Public Class Form1
  Dim MailSlotThread As Thread
  Private Delegate Sub MailSlotDelegate(ByVal NewMessage As String)

  Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
    If MakeMailSlot("\\.\mailslot\MailSlotMyName", True) Then
      MailSlotThread = New Thread(New ThreadStart(AddressOf MailSlotThreadFunction))
      MailSlotThread.Start()
    End If
  End Sub

  Private Sub MailSlotThreadFunction()
    Dim m_Message As String = ""
    Do
      If MailSlotReadFirstInfinite(m_Message) Then _
       Me.Invoke(New MailSlotDelegate(AddressOf MailSlotUIFunction), m_Message)
    Loop
  End Sub

  Private Sub MailSlotUIFunction(ByVal NewMessage As String)
    '---обработка сообщения---
    'MsgBox(NewMessage)
    Me.Text = NewMessage
    '---обработка сообщения---
  End Sub

  Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed
    If Not IsNothing(MailSlotThread) Then MailSlotThread.Abort()
    CloseMailSlot() 'необх. нет, т.к. он уничтожится по любому вместе с закрытием приложения
  End Sub
...===========
  Public Function MakeMailSlot(ByVal lpszSlotName As String, _
   Optional ByVal WaitForever As Boolean = False) As Boolean
...
    hMailSlotHandle = CreateMailslot(lpszSlotName, 0, IIf(WaitForever, MAILSLOT_WAIT_FOREVER, 0), m_tSA)

  Public Function MailSlotReadFirstInfinite(ByRef m_Message As String) As Boolean
    'возвращает True,если сообщение прочитано
    'm_Message -возвращает текст первого сообщения при успехе
    'пока не получено, ReadFile ждет за счет MAILSLOT_WAIT_FOREVER при создании MailSlot

    Dim lBufferSize As Integer = 260 ' arbitrary - can be set higher/lower if desired
    Dim sBuffer(lBufferSize - 1) As Byte
    Dim lBytesRead As Integer 'сколько байт прочитали -чтоб обрезать буфер

    ' Read data: optional параметры ф-ции не используем
    If ReadFile(hMailSlotHandle, sBuffer, lBufferSize, lBytesRead, IntPtr.Zero) = False Then
      If Err.LastDllError = ERROR_INSUFFICIENT_BUFFER Then
        GetMailslotInfo(hMailSlotHandle, 0, lBufferSize, 0, 0) 'получаем точный размер буфера, если не хватило
        ReDim sBuffer(lBufferSize - 1)
        'читаем повторно с точным размером буфера
        If ReadFile(hMailSlotHandle, sBuffer, lBufferSize, lBytesRead, IntPtr.Zero) = False Then
          Return False 'хз-не должно такого быть
        End If
      Else
        Return False 'любая другая ошибка, например при обращении к несуществующему MailSlot
      End If
    Else 'в случае успеха с первого раза буфер надо обрезать
      ReDim Preserve sBuffer(lBytesRead - 1)
    End If

    Using mstream As New IO.MemoryStream(sBuffer)
      Using reader As New IO.StreamReader(mstream, System.Text.Encoding.Default, True)
        m_Message = reader.ReadToEnd()
      End Using
    End Using
    Return True
  End Function



Вроде все отлично, стреляет "как только получено".
Но вы пишете.

Изопропилза такое завершение потока нужно больно бить по рукам
...
поток должен ждать какого либо события
Roman Mejtesсоздать флаг, при котором цикл завершится

У меня нет "бесконечно долбящего" цикла, у меня поток висит на функции ReadFile, а висит она за счет MAILSLOT_WAIT_FOREVER при создании MailSlot. И вот куда мне этот "флаг" (для корректного выхода из цикла в MailSlotThreadFunction и завершения потока) втыкать?
Ну если только закрыть MailSlot до закрытия потока и это сгенерирует какую-нибудь спецошибку в ReadFile ,которую я верну через MailSlotReadFirstInfinite и выйду из цикла. Но это надо играться.
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38878286
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Ну если только закрыть MailSlot до закрытия потока и это сгенерирует какую-нибудь спецошибку в ReadFile ,которую я верну через MailSlotReadFirstInfinite и выйду из цикла. Но это надо играться.

Ну вообще вот так наверно достаточно:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
  Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed
   CloseMailSlot() 'необх. нет, т.к. он уничтожится по любому вместе с закрытием приложения
  End Sub


  Private Sub MailSlotThreadFunction()
    Dim m_Message As String = ""
    Do
      If MailSlotReadFirstInfinite(m_Message) Then
        Me.Invoke(New MailSlotDelegate(AddressOf MailSlotUIFunction), m_Message)
      Else
        Exit Do
      End If
    Loop
  End Sub



Происходит следующее:
При выполнении CloseHandle(hMailSlotHandle)
ReadFile находящийся в режиме бесконечного ожидания выходит с ошибкой ERROR_HANDLE_EOF (38)
Моя MailSlotReadFirstInfinite возвращает False (номер ошибки думаю можно даже не отслеживать)
По этому False я выхожу из цикла -> поток завершается
Исключения за счет незакрытого потока не возникает.

Вариант?
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38878431
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77У меня нет "бесконечно долбящего" цикла, у меня поток висит на функции ReadFile, а висит она за счет MAILSLOT_WAIT_FOREVER при создании MailSlot.
а нужно с таймаутом висеть и по прошествии таймаута флаг проверять - далее чтение в цикле
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38878432
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Вариант?
да
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38878446
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилДмитрий77У меня нет "бесконечно долбящего" цикла, у меня поток висит на функции ReadFile, а висит она за счет MAILSLOT_WAIT_FOREVER при создании MailSlot.
а нужно с таймаутом висеть и по прошествии таймаута флаг проверять - далее чтение в цикле
Какая разница? С таймаутом или бесконечно. Хотя конечно с учетом выхода по ERROR_HANDLE_EOF разница есть: флаг сразу сработает. Только он не нужен если я отслеживаю error.
ИзопропилДмитрий77Вариант?
да
Ну вот на этом и остановимся. Имплементировал в проект, все отлично работает.
Кстати в проекте без отработки выхода по ошибке форма закрывается, а прога остается висеть (без крашей) - потому что я не в саму форму "стучу", а в public ф-цию модуля.

Так или иначе поток надо закрывать.
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38878514
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Какая разница? С таймаутом или бесконечно
завершение работы потока закрытием хэндла - частный случай.
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38878537
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропилзавершение работы потока закрытием хэндла - частный случай.
Ну, главное что для этого случая все отлично работает.
Будут другие случаи, буду смотреть.
Но во всех случаях когда в цикле разумно делать тупое засыпание через Sleep(N ms), я предпочту обычный таймер, нежели городить огород с потоком.
В данном случае я выигрываю в пользу "как только так сразу", из-за этого таймер с MailSlot-ом таки напрягал, хотя я и читал Messag-ы блоками, т.е. не по одному раз в секунду а все имеющиеся не позже чем через секунду.

Напрягают обычно 2 вещи:
1) подвисание UI потока (программа занята длительной операцией)
2) тупой должбеж чего-либо в надежде получить что-нибудь чего может долгое время не быть вообще (проверка таймером или какой нибудь цикл пусть бы и с DoEvent()). Да и в отдельном потоке такое делать - не фонтан.
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38878551
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Да и в отдельном потоке такое делать - не фонтан.
конечно не фонтан - на то и существуют события, асинхронный ввод-вывод, порты завершения, и т д
...
Рейтинг: 0 / 0
Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
    #38878552
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Напрягают обычно 2 вещи:
1) подвисание UI потока (программа занята длительной операцией)
операции запускать асинхронно, при невозможности - в отдельном потоке.
в UI потоке - только рисование


PS что характерно воевать с дотнетом нет никакого желания
...
Рейтинг: 0 / 0
49 сообщений из 49, показаны все 2 страниц
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Mailslot /SendMessage(WM_COPYDATA). Передача строк. Unicode или ANSI или все равно как?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]