質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
NFC

無線通信

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

メール

メールは、コンピュータネットワークを利用し、 情報等を交換する手段のことです。

Q&A

1回答

2620閲覧

C#でnfcタグを読み取ってメール送信したい

singlestroke

総合スコア68

NFC

無線通信

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

メール

メールは、コンピュータネットワークを利用し、 情報等を交換する手段のことです。

0グッド

0クリップ

投稿2021/05/19 13:29

###やりたいこと概要
C# を使用して Windows でnfc タグを読み取り、カード番号を php ファイルに post したい。
nfc を使用していわゆる入退室システムのようなものを作りたい。

###詳細
ポイントは以下の3点かと思います。

  • 「入室」「退室」ボタンをトグルで切り替える
  • NFCリーダ(Sony PaSoRi RC-S380/S)でカードを読み取る
  • カード番号を php ファイルに post する

###現状
それぞれ単独では実現できたが、すべてを合体させるとうまくいかない。

###やってみたコード

C#

1using PCSC; 2using System; 3using System.Collections.Generic; 4using System.ComponentModel; 5using System.Data; 6using System.Drawing; 7using System.Linq; 8using System.Net.Http; 9using System.Text; 10using System.Threading.Tasks; 11using System.Windows.Forms; 12 13 14namespace WinFormsApp 15{ 16 public partial class Form1 : Form 17 { 18 private Timer timer1; 19 private IContainer components; 20 private CheckBox checkBox1; 21 private Label label1; 22 23 public Form1() 24 { 25 InitializeComponent(); 26 } 27 28 private void InitializeComponent() 29 { 30 this.components = new System.ComponentModel.Container(); 31 this.label1 = new System.Windows.Forms.Label(); 32 this.timer1 = new System.Windows.Forms.Timer(this.components); 33 this.checkBox1 = new System.Windows.Forms.CheckBox(); 34 this.SuspendLayout(); 35 // 36 // label1 37 // 38 this.label1.AutoSize = true; 39 this.label1.Font = new System.Drawing.Font("Yu Gothic UI", 72F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); 40 this.label1.Location = new System.Drawing.Point(150, 9); 41 this.label1.Name = "label1"; 42 this.label1.Size = new System.Drawing.Size(307, 128); 43 this.label1.TabIndex = 0; 44 this.label1.Text = "label1"; 45 // 46 // timer1 47 // 48 this.timer1.Tick += new System.EventHandler(this.timer1_Tick_1); 49 // 50 // checkBox1 51 // 52 this.checkBox1.Appearance = System.Windows.Forms.Appearance.Button; 53 this.checkBox1.AutoSize = true; 54 this.checkBox1.Location = new System.Drawing.Point(249, 187); 55 this.checkBox1.Name = "checkBox1"; 56 this.checkBox1.Size = new System.Drawing.Size(74, 25); 57 this.checkBox1.TabIndex = 1; 58 this.checkBox1.Text = "入室"; 59 this.checkBox1.UseVisualStyleBackColor = true; 60 this.checkBox1.CheckedChanged += new System.EventHandler(this.checkBox1_CheckedChanged); 61 // 62 // Form1 63 // 64 this.ClientSize = new System.Drawing.Size(618, 261); 65 this.Controls.Add(this.checkBox1); 66 this.Controls.Add(this.label1); 67 this.Name = "Form1"; 68 this.Load += new System.EventHandler(this.Form1_Load_1); 69 this.ResumeLayout(false); 70 this.PerformLayout(); 71 72 } 73 74 private void Form1_Load_1(object sender, EventArgs e) 75 { 76 this.Text = Application.ProductName; 77 timer1.Interval = 500; 78 timer1.Enabled = true; 79 } 80 81 private void timer1_Tick_1(object sender, EventArgs e) 82 { 83 DateTime d = DateTime.Now; 84 label1.Text = string.Format("{0:00}:{1:00}", d.Hour, d.Minute); 85 } 86 87 private void checkBox1_CheckedChanged(object sender, EventArgs e) 88 { 89 CheckBox chkBox = (CheckBox)sender; 90 91 if (chkBox.Checked) 92 { 93 chkBox.Text = "入室"; 94 } 95 else 96 { 97 chkBox.Text = "退室"; 98 } 99 } 100 101 private static async Task GetTask(string[] args) 102 { 103 IntPtr hContext = IntPtr.Zero; 104 105 // ################################################## 106 // 1. SCardEstablishContext 107 // ################################################## 108 uint ret = Api.SCardEstablishContext(Constant.SCARD_SCOPE_USER, IntPtr.Zero, IntPtr.Zero, out hContext); 109 if (ret != Constant.SCARD_S_SUCCESS) 110 { 111 string message; 112 switch (ret) 113 { 114 case Constant.SCARD_E_NO_SERVICE: 115 message = "サービスが起動されていません。"; 116 break; 117 default: 118 message = "サービスに接続できません。code = " + ret; 119 break; 120 } 121 throw new ApplicationException(message); 122 } 123 124 if (hContext == IntPtr.Zero) 125 { 126 throw new ApplicationException("コンテキストの取得に失敗しました。"); 127 } 128 129 // ################################################## 130 // 2. SCardListReaders 131 // ################################################## 132 uint pcchReaders = 0; 133 134 // NFCリーダの文字列バッファのサイズを取得 135 ret = Api.SCardListReaders(hContext, null, null, ref pcchReaders); 136 if (ret != Constant.SCARD_S_SUCCESS) 137 { 138 // 検出失敗 139 throw new ApplicationException("NFCリーダを確認できません。"); 140 } 141 142 // NFCリーダの文字列を取得 143 byte[] mszReaders = new byte[pcchReaders * 2]; // 1文字2byte 144 ret = Api.SCardListReaders(hContext, null, mszReaders, ref pcchReaders); 145 if (ret != Constant.SCARD_S_SUCCESS) 146 { 147 // 検出失敗 148 throw new ApplicationException("NFCリーダの取得に失敗しました。"); 149 } 150 151 UnicodeEncoding unicodeEncoding = new UnicodeEncoding(); 152 string readerNameMultiString = unicodeEncoding.GetString(mszReaders); 153 154 // 認識したNDCリーダの最初の1台を使用 155 int nullindex = readerNameMultiString.IndexOf((char)0); 156 var readerName = readerNameMultiString.Substring(0, nullindex); 157 158 // ################################################## 159 // 3. SCardConnect 160 // ################################################## 161 IntPtr hCard = IntPtr.Zero; 162 IntPtr activeProtocol = IntPtr.Zero; 163 ret = Api.SCardConnect(hContext, readerName, Constant.SCARD_SHARE_SHARED, Constant.SCARD_PROTOCOL_T1, ref hCard, ref activeProtocol); 164 while (ret != Constant.SCARD_S_SUCCESS) 165 { 166 if (ret == Constant.SCARD_S_SUCCESS) 167 { 168 continue; 169 } 170 ret = Api.SCardConnect(hContext, readerName, Constant.SCARD_SHARE_SHARED, Constant.SCARD_PROTOCOL_T1, ref hCard, ref activeProtocol); 171 } 172 173 // ################################################## 174 // 4. SCardTransmit 175 // ################################################## 176 uint maxRecvDataLen = 256; 177 var recvBuffer = new byte[maxRecvDataLen + 2]; 178 var sendBuffer = new byte[] { 0xff, 0xca, 0x00, 0x00, 0x00 }; // ← IDmを取得するコマンド 179 180 Api.SCARD_IO_REQUEST ioRecv = new Api.SCARD_IO_REQUEST(); 181 ioRecv.cbPciLength = 255; 182 183 int pcbRecvLength = recvBuffer.Length; 184 int cbSendLength = sendBuffer.Length; 185 186 IntPtr handle = Api.LoadLibrary("Winscard.dll"); 187 IntPtr pci = Api.GetProcAddress(handle, "g_rgSCardT1Pci"); 188 Api.FreeLibrary(handle); 189 190 ret = Api.SCardTransmit(hCard, pci, sendBuffer, cbSendLength, ioRecv, recvBuffer, ref pcbRecvLength); 191 if (ret != Constant.SCARD_S_SUCCESS) 192 { 193 throw new ApplicationException("NFCカードへの送信に失敗しました。code = " + ret); 194 } 195 string cardId = BitConverter.ToString(recvBuffer, 0, pcbRecvLength - 2); 196 197 var hc = new HttpClient(); 198 var dic = new Dictionary<string, string>(); 199 dic["name"] = "id"; 200 dic["card"] = cardId; 201 var cont = new FormUrlEncodedContent(dic); 202 var url = "https://example/example.php"; 203 var req = await hc.PostAsync(url, cont); 204 } 205 206 } 207} 208

以下サイトを参考に作ってみましたが、素人なのでうまくできません。
カード番号を読み取って post したいだけなのですが、どのようにしたら良いか教えていただけますでしょうか。

###参照サイト
WindowsでNFCタグを読み取る
C#からPHPにPOSTする

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2021/05/19 13:32

そのカード番号というのはコードのどこにありますか
YAmaGNZ

2021/05/19 13:52

「うまくいかない」とはどうなるのですか?
退会済みユーザー

退会済みユーザー

2021/05/19 13:53

> それぞれ単独では実現できたが、すべてを合体させるとうまくいかない。 うまくいかないというだけでは話が伝わりません。
singlestroke

2021/05/19 20:29

> そのカード番号というのはコードのどこにありますか cardId という変数に代入されます。 >「うまくいかない」とはどうなるのですか? カードをリーダーに置いても何も起きないということです。 カードを予めリーダーかざしてからビルドしても、ビルドしてからカードをかざしても何も起きません。
退会済みユーザー

退会済みユーザー

2021/05/19 22:29

> カードをリーダーに置いても何も起きないということです。 「何も起きない」と言うのはどう判断しているのですか? 送信先のサーバーに結果を取得できない? であれば、Fiddler を使ってクライアントからサーバーへ期待どおりの要求が出ていってるか調べて見ては?
退会済みユーザー

退会済みユーザー

2021/05/19 23:11 編集

正しく動かないのであれば、まずどこまで正しく動いているか、どこで想定外の動きをしているか絞り込む所から始めてください。例外が発生しているなら、その詳細(メッセージ・スタックトレース)を記述してください。デバッグログ等を出力してみればすぐ判るでしょう。 [質問をする前に自分で何がわからないのかを把握しましょう] https://teratail.com/help/question-tips#questionTips2
guest

回答1

0

デバッガを使ってどのようにプログラムが実行されているか確認しましょう。
各処理単体であれば出来ているのであれば、なおのことステップ実行なりで止めながら実行して各変数がどうなっているのか確認しましょう。

またGetTaskはどこで動かしているのでしょうか?

投稿2021/05/19 22:07

編集2021/05/19 22:11
YAmaGNZ

総合スコア10242

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

singlestroke

2021/05/20 01:12

書いたコードは以上ですべてです。 これで GetTask は実行されていると思っていたのですが、どこかから呼び出す記述が必要ということでしょうか。
YAmaGNZ

2021/05/20 01:15

実行されていると思うなら、ブレークポイントで止めてみるなりログを出力したりして確認しましょう。
YAmaGNZ

2021/05/20 01:27

参考にされているページがコンソールアプリでMain関数が開始時に自動で呼ばれるから勘違いされているようですね。 GetTaskが勝手に呼ばれることはありません。 また、システム設計の問題として、PHPへPostするデータがカードIDのみで「入室」「退室」を示すものがないのはいいのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問