C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

仮想プリンタポートのシリアル通信

[トピック内 4 記事 (1 - 4 表示)]  << 0 >>

■96082 / inTopicNo.1)  仮想プリンタポートのシリアル通信
  
□投稿者/ アローアロー (1回)-(2020/10/20(Tue) 13:45:47)

分類:[C#] 

C#のフォームアプリケーションでプリンタを制御したいのですが
USB001(USBの仮想プリンターポート)をGetPortNames()で取得できませんでした。
serialportクラスでは通信出来ないのでしょうか?
引用返信 編集キー/
■96084 / inTopicNo.2)  Re[1]: 仮想プリンタポートのシリアル通信
□投稿者/ furu (80回)-(2020/10/20(Tue) 15:43:39)
No96082 (アローアロー さん) に返信
> C#のフォームアプリケーションでプリンタを制御したいのですが
> USB001(USBの仮想プリンターポート)をGetPortNames()で取得できませんでした。
> serialportクラスでは通信出来ないのでしょうか?
プリンターポートってパラレルだから
serialportクラスじゃないんっじゃないの?
引用返信 編集キー/
■96089 / inTopicNo.3)  Re[1]: 仮想プリンタポートのシリアル通信
□投稿者/ 魔界の仮面弁士 (2881回)-(2020/10/20(Tue) 19:11:32)
No96082 (アローアロー さん) に返信
> C#のフォームアプリケーションでプリンタを制御したいのですが

手元に環境が無いので試せませんが、こういうイメージ…?

[DllImport("kernel32.dll", SetLastError = true)]
static extern SafeFileHandle CreateFile(string lpFileName, FileAccess dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, FileMode dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);

SafeFileHandle hPrinter = CreateFile("ポート名", FileAccess.ReadWrite, 0, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero);
if (hPrinter.IsInvalid) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); }
using (var p = new FileStream(hPrinter, FileAccess.ReadWrite))
{
  p.Write(printerCommand, 0, printerCommand.Length);
}


> USB001(USBの仮想プリンターポート)をGetPortNames()で取得できませんでした。

手元の仮想プリンターポートは 標準 TCP/IP のものしかなく、USB 環境下では未検証なのですが、
プリンターポートの列挙は、PowerShell の Get-PrinterPort コマンドレットで行える気がします。
API 利用なら、EnumPortsW API で PORT_INFO_2 構造体を得られないか試してみてください。



[Flags]
public enum PortType : int
{
  Write = 0x1,
  Read = 0x2,
  Redirected = 0x4,
  NetAttached = 0x8,
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
[DebuggerDisplay("{fPortType}, {pPortName}, {pMonitorName}, {pDescription}")]
public struct PORT_INFO_2
{
  public string pPortName;
  public string pMonitorName;
  public string pDescription;
  public PortType fPortType;
  internal int Reserved;
}

[DllImport("winspool.drv", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int EnumPorts(string pName, int Level, IntPtr lpbPorts, int cbBuf, ref int pcbNeeded, ref int pcReturned);

public static PORT_INFO_2[] GetPorts()
{
  PORT_INFO_2[] portInfo = null;
  int needed = 0;
  int returned = 0;
  EnumPorts(null, 2, IntPtr.Zero, 0, ref needed, ref returned);
  int offset = Marshal.SizeOf(typeof(PORT_INFO_2));
  IntPtr buffer = Marshal.AllocHGlobal(Convert.ToInt32(needed + 1));
  int result = EnumPorts(null, 2, buffer, needed, ref needed, ref returned);
  if (result != 0)
  {
    var port = buffer;
    portInfo = new PORT_INFO_2[returned];
    for (int i = 0; i < returned; i++)
    {
      portInfo[i] = Marshal.PtrToStructure<PORT_INFO_2>(port);
      port = IntPtr.Add(port, offset);
    }
    Marshal.FreeHGlobal(buffer);
  }
  return portInfo ?? new PORT_INFO_2[] { };
}
引用返信 編集キー/
■96091 / inTopicNo.4)  Re[2]: 仮想プリンタポートのシリアル通信
□投稿者/ アローアロー (2回)-(2020/10/21(Wed) 10:58:19)
No96089 (魔界の仮面弁士 さん) に返信
教えてもらった方法でいけそうです。
今すぐ確認出来ないので後日確認してみます。
ありがとうございました。
解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ