วิธีการใช้ pipes ชื่อสำหรับการติดต่อสื่อสาร interprocess ใน Visual Basic .NET หรือ Visual Basic 2005

การแปลบทความ การแปลบทความ
หมายเลขบทความ (Article ID): 871044 - ผลิตภัณฑ์ที่เกี่ยวข้องในบทความนี้
ขยายทั้งหมด | ยุบทั้งหมด

เนื้อหาบนหน้านี้

สรุป

บทความนี้ทีละขั้นตอนเกี่ยวกับวิธีการใช้ชื่อ pipes ใน Microsoft Visual Basic .NET หรือ Microsoft Visual Basic 2005 สำหรับการสื่อสาร interprocess บทความนี้มีตัวอย่างรหัสที่แสดงการสื่อสารไคลเอ็นต์/เซิร์ฟเวอร์ โดยใช้ไปป์ที่มีชื่อ ใน Visual Basic .NET หรือ Visual Basic 2005 บทความอธิบายถึงการสื่อสาร interprocess โดยการสร้างไปป์ที่มีชื่อเซิร์ฟเวอร์และไคลเอนต์ไปป์ที่มีชื่อ การสื่อสารผ่านไปป์ทำได้ในลักษณะต่อไปนี้:
  • สร้างไปป์ที่มีชื่อ
  • บล็อกโปรแกรมประยุกต์ของเซิร์ฟเวอร์ โดยใช้ฟังก์ชัน ConnectNamedPipe จนกว่าการเชื่อมต่อไคลเอนต์
  • เชื่อมต่อกับเซิร์ฟเวอร์ โดยใช้ฟังก์ชัน CallNamedPipe
  • เรียกฟังก์ชัน ReadFile หรือฟังก์ชัน WriteFile การสื่อสารผ่านไปป์
  • เรียกฟังก์ชัน DisconnectNamedPipe เมื่อกระบวนการเสร็จสิ้นการใช้ไปป์
  • เรียกฟังก์ชัน CloseHandle ในไปป์ที่มีชื่อหลังจากที่คุณเสร็จสิ้นการสื่อสารผ่านไปป์

บทนำ

ไปป์ที่มีชื่อเป็นไปป์เดียว(one-way) หรือแบบสองทางสำหรับการสื่อสารระหว่างเซิร์ฟเวอร์ไปป์และไคลเอนต์ไปป์อย่าง น้อยหนึ่งรายการ คุณสามารถทำให้ผู้ใช้ชื่อ pipes ให้การสื่อสาร ระหว่างกระบวนการบนคอมพิวเตอร์เครื่องเดียวกัน หรือ ระหว่างกระบวนการบนคอมพิวเตอร์เครื่องอื่นผ่านเครือข่าย เงื่อนไข "เซิร์ฟเวอร์ไปป์ที่ชื่อว่า" การอ้างอิงถึงกระบวนการที่สร้างไปป์ที่มีชื่อ และเงื่อนไข "ไคลเอ็นต์ไปป์ที่ชื่อว่า" หมายถึงกระบวนการที่เชื่อมต่อกับอินสแตนซ์ของไปป์ที่มีชื่อ

คุณสามารถใช้ Microsoft Visual Basic .NET หรือ Microsoft Visual Basic 2005 เพื่อสร้างโปรแกรมประยุกต์ที่สื่อสารกับกระบวนการอื่น โดยใช้ชื่อ pipes บทความนี้ประกอบด้วยตัวอย่างรหัสที่ใช้ในไปป์ที่มีชื่อการสื่อสารระหว่างโปรแกรมประยุกต์ Visual Basic .NET หรือ Visual Basic 2005 Windows ที่สอง

ความต้องการ

บทความนี้อนุมานว่า คุณไม่คุ้นเคยกับหัวข้อต่อไปนี้:
  • โปรแกรมประยุกต์ของ windows
  • การเขียนโปรแกรม visual Basic .NET
  • การใช้ pipes
รายการต่อไปนี้แสดงฮาร์ดแวร์ที่แนะนำ ซอฟต์แวร์ โครงสร้างพื้นฐานของเครือข่าย และ service pack ที่คุณต้องการ:
  • Microsoft Visual Studio .NET หรือ Microsoft Visual Studio 2005
  • กรอบการทำงานของ microsoft .NET

สร้างไปป์ที่มีชื่อเซิร์ฟเวอร์

การสร้างไปป์ที่มีชื่อเซิร์ฟเวอร์ และสื่อสารกับไคลเอนต์แล้ว ผ่านไปป์ ดำเนินการดังต่อไปนี้:
  1. สร้างไปป์ที่มีชื่อ
  2. เรียกConnectNamedPipeฟังก์ชันการบล็อกเซิร์ฟเวอร์จนกว่าการเชื่อมต่อไคลเอนต์
  3. เรียกreadfileฟังก์ชันหรือWriteFileฟังก์ชันการสื่อสารผ่านไปป์
  4. เรียกDisconnectNamedPipeฟังก์ชันเมื่อกระบวนการเสร็จสิ้นการใช้ไปป์
  5. เรียกCloseHandleฟังก์ชันในไปป์ที่มีชื่อ

การออกแบบโปรแกรมประยุกต์ของ Windows ที่สร้างไปป์ที่มีชื่อเซิร์ฟเวอร์

เมื่อต้องการออกแบบโปรแกรมประยุกต์ของ Windows ที่สร้างไปป์ที่มีชื่อเซิร์ฟเวอร์ โดยใช้ Visual Basic .NET หรือ Visual Basic 2005 ดำเนินการดังต่อไปนี้:
  1. เริ่ม Microsoft Visual Studio .NET หรือ Microsoft Visual Studio 2005
  2. ในการแฟ้ม:เมนู ให้ชี้ไปที่ใหม่แล้ว คลิกProject.
  3. ภายใต้ชนิดโครงการคลิกโครงการ visual Basicแล้ว คลิกแอพลิเคชันของ windowsภายใต้แม่แบบ.

    หมายเหตุ:ใน Visual Studio 2005 คลิกvisual Basicภายใต้ชนิดโครงการ.
  4. ในการชื่อ:กล่อง ชนิดMyServerAppแล้ว คลิกตกลง. โดยค่าเริ่มต้น แบบฟอร์มที่มีชื่อ Form1 ถูกสร้างขึ้น
  5. เพิ่ม 3ปุ่มตัวควบคุมฟอร์ม Form1
  6. ในการมุมมองเมนู คลิกหน้าต่างคุณสมบัติ.
  7. ตั้งค่านี้ข้อความคุณสมบัตินี้ปุ่มควบคุมการค่าต่อไปนี้:
    ยุบตารางนี้ขยายตารางนี้
    ชื่อ:ข้อความ
    button1สร้างไปป์ที่มีชื่อ
    Button2รอให้การเชื่อมต่อไคลเอนต์
    Button3ตัดการเชื่อมต่อเซิร์ฟเวอร์
  8. เพิ่มคำป้ายชื่อควบคุมไปยังform1แบบฟอร์ม Label1ป้ายชื่อตัวควบคุมถูกเพิ่มให้กับฟอร์ม Form1

เพิ่ม declarations ทั้งหมดในโมดูลในแอพลิเคชันของ Windows

เมื่อต้องการเพิ่ม declarations ฟังก์ชันที่จำเป็นต้องใช้การสื่อสาร interprocess โดยใช้ไปป์ที่มีชื่อ ดำเนินการดังต่อไปนี้:
  1. คลิกขวาใน Explorer โซลูชันMyServerAppชี้ไปที่addแล้ว คลิกเพิ่มโมดูล.
  2. ในการเพิ่มรายการใหม่ - MyServerAppกล่องโต้ตอบ คลิกOPEN.
  3. เพิ่มรหัสต่อไปนี้ไปModule1.vbโมดูล:
    Public Const FILE_ATTRIBUTE_NORMAL As Short = &H80S
    Public Const FILE_FLAG_NO_BUFFERING As Integer = &H20000000
    Public Const FILE_FLAG_WRITE_THROUGH As Integer = &H80000000
    
    Public Const PIPE_ACCESS_DUPLEX As Short = &H3S
    Public Const PIPE_READMODE_MESSAGE As Short = &H2S
    Public Const PIPE_TYPE_MESSAGE As Short = &H4S
    Public Const PIPE_WAIT As Short = &H0S
    
    Public Const INVALID_HANDLE_VALUE As Short = -1
    
    Declare Function CreateNamedPipe Lib "kernel32" Alias "CreateNamedPipeA" _
    (ByVal lpName As String, ByVal dwOpenMode As Integer, _
    ByVal dwPipeMode As Integer, ByVal nMaxInstances As Integer, _
    ByVal nOutBufferSize As Integer, ByVal nInBufferSize As Integer, _
    ByVal nDefaultTimeOut As Integer, ByVal lpSecurityAttributes As IntPtr _
    ) As Integer
    
    Declare Function ConnectNamedPipe Lib "kernel32" _
        (ByVal hNamedPipe As Integer, ByVal lpOverlapped As Integer) As Integer
    
    Declare Function DisconnectNamedPipe Lib "kernel32" _
        (ByVal hNamedPipe As Integer) As Integer
    
    Declare Function WriteFile Lib "kernel32" _
    (ByVal hFile As Integer, ByRef lpBuffer() As Byte, _
    ByVal nNumberOfBytesToWrite As Integer, ByRef lpNumberOfBytesWritten As Integer, _
    ByVal lpOverlapped As Integer _
    ) As Integer
    
    Declare Function ReadFile Lib "kernel32" _
    (ByVal hFile As Integer, ByRef lpBuffer As Integer, _
    ByVal nNumberOfBytesToRead As Integer, ByRef lpNumberOfBytesRead As Integer, _
    ByVal lpOverlapped As Integer _
    ) As Integer
    
    Declare Function FlushFileBuffers Lib "kernel32" _
        (ByVal hFile As Integer) As Integer
    
    Declare Function CloseHandle Lib "kernel32" _
        (ByVal hObject As Integer) As Integer
    

เขียนโค้ดเพื่อสร้างไปป์ที่มีชื่อเซิร์ฟเวอร์

หลังจากที่คุณสร้างไปป์ที่มีชื่อ รอสำหรับการเชื่อมต่อจากไคลเอ็นต์ เมื่อไคลเอนต์เชื่อมต่อกับเซิร์ฟเวอร์ อ่าน หรือเขียนข้อมูลผ่านไปป์ โดยให้ทำตามขั้นตอนต่อไปนี้::
  1. คลิกขวาใน Explorer โซลูชันform1แล้ว คลิกOPEN.
  2. ในมุมมองออกแบบของform1แบบฟอร์ม คลิกสองครั้งสร้างไปป์ที่มีชื่อแล้ว เพิ่มโค้ดต่อไปนี้ไปButton1_Clickขั้นตอน:
    Dim openMode, pipeMode As Integer
    'Create the named pipe
    openMode = PIPE_ACCESS_DUPLEX Or FILE_FLAG_WRITE_THROUGH
    pipeMode = PIPE_WAIT Or PIPE_TYPE_MESSAGE Or PIPE_READMODE_MESSAGE
    hPipe = CreateNamedPipe(pipeName, openMode, pipeMode, 10, 10000, 2000, 10000, IntPtr.Zero)
    Label1.Text = "Created the named pipe and waiting for the clients."
    Button1.Visible = False
    Button2.Visible = True
    Button3.Visible = True
  3. เพิ่มรหัสต่อไปนี้ก่อนButton1_Clickขั้นตอน:
    Private Const pipeName As String = "\\.\pipe\MyPipe"
    Private Const BUFFSIZE As Short = 10000
    Private Buffer(BUFFSIZE) As Byte
    Private hPipe As Integer
  4. ในโซลูชัน Explorer คลิกสองครั้งForm1.vb.
  5. ในมุมมองออกแบบของฟอร์ม Form1 คลิกสองครั้งรอให้การเชื่อมต่อไคลเอนต์แล้ว เพิ่มโค้ดต่อไปนี้ไปButton2_Clickขั้นตอน:
    Dim byteCount, i, res, cbnCount As Integer
    For i = 0 To BUFFSIZE - 1 'Fill an array of numbers
       Buffer(i) = i Mod 256
    Next i
    'Wait for a connection, block until a client connects
    Label1.Text = "Waiting for client connections"
    Me.Refresh()
    Do
       res = ConnectNamedPipe(hPipe, 0)
       'Read the data sent by the client over the pipe
       cbnCount = 4
       res = ReadFile(hPipe, byteCount, Len(byteCount), cbnCount, 0)
       If byteCount > BUFFSIZE Then 'Client requested for byteCount bytes
           byteCount = BUFFSIZE 'but only send up to 20000 bytes
       End If
       'Write the number of bytes requested by the client 
       res = WriteFile(hPipe, Buffer, byteCount, cbnCount, 0)
       res = FlushFileBuffers(hPipe)
       'Disconnect the named pipe.
       res = DisconnectNamedPipe(hPipe)
       'Loop until the client makes no more requests for data. 
    Loop Until byteCount = 0
    Label1.Text = "Read or Write completed"
    Button2.Visible = False
  6. ในมุมมองออกแบบ คลิกสองครั้งform1แล้ว เพิ่มโค้ดต่อไปนี้ไปForm1_Loadขั้นตอน:
    Button2.Visible = False
    Button3.Visible = False
  7. ในโซลูชัน Explorer คลิกสองครั้งForm1.vb.
  8. ในมุมมองออกแบบของฟอร์ม Form1 คลิกสองครั้งตัดการเชื่อมต่อเซิร์ฟเวอร์แล้ว เพิ่มโค้ดต่อไปนี้ไปButton3_Clickขั้นตอน:
    Dim res As Integer
    'Close the pipe handle when the client makes no requests
    CloseHandle(hPipe)
    Label1.Text = "Disconnected the named pipe"
  9. ในการการสร้างเมนู คลิกสร้างโซลูชัน.

สร้างไปป์ที่มีชื่อไคลเอนต์

เมื่อต้องการสร้างไคลเอนต์ไปป์ที่มีชื่อที่สื่อสารกับเซิร์ฟเวอร์ ดำเนินการดังต่อไปนี้:
  1. เรียกCreateFileฟังก์ชันการสร้างหมายเลขอ้างอิงถึงไปป์ที่มีชื่อ
  2. เรียกreadfileฟังก์ชันหรือWriteFileฟังก์ชันการสื่อสารผ่านไปป์
  3. เรียกCloseHandleฟังก์ชันบนหมายเลขอ้างอิงที่สร้างในต้นแบบCreateFileฟังก์ชัน
คุณยังสามารถใช้ทรานแซคชันไปป์ที่มีชื่อสำหรับการสื่อสารไคลเอ็นต์/เซิร์ฟเวอร์ ธุรกรรมไปป์ที่มีชื่อที่รวมการดำเนินการเขียนและการดำเนินการอ่านในการดำเนินการของเครือข่ายเดียว ธุรกรรมที่สามารถใช้ได้เฉพาะในไปป์ชนิดของข้อความที่ดูเพล็กซ์ กระบวนการที่สามารถใช้ได้TransactNamedPipeฟังก์ชันหรือCallNamedPipeฟังก์ชันการทำธุรกรรมไปป์ที่มีชื่อ

ในตัวอย่างโค้ดนี้ คุณใช้การCallNamedPipeฟังก์ชันเชื่อมต่อกับเซิร์ฟเวอร์ไปป์ที่มีชื่อ เขียนข้อมูลลงในไปป์ และอ่านข้อมูลจากไปป์นั้นแล้ว

การออกแบบโปรแกรมประยุกต์ของ Windows ที่สื่อสารกับเซิร์ฟเวอร์ไปป์ที่มีชื่อ

เมื่อต้องการออกแบบแอพพลิเคชัน Visual Basic .NET หรือ Visual Basic 2005 Windows ที่ใช้ในการเชื่อมต่อกับเซิร์ฟเวอร์ไปป์ที่มีชื่อ ดำเนินการดังต่อไปนี้:
  1. เริ่ม Microsoft Visual Studio .NET หรือ Microsoft Visual Studio 2005
  2. ในการแฟ้ม:เมนู ให้ชี้ไปที่ใหม่แล้ว คลิกProject.
  3. ภายใต้ชนิดโครงการคลิกโครงการ visual Basicแล้ว คลิกแอพลิเคชันของ windowsภายใต้แม่แบบ.

    หมายเหตุ:ใน Visual Studio 2005 คลิกvisual Basicภายใต้ชนิดโครงการ.
  4. ในการชื่อ:กล่อง ชนิดMyClientAppแล้ว คลิกตกลง. โดยค่าเริ่มต้น แบบฟอร์มที่มีชื่อ Form1 ถูกสร้างขึ้น
  5. เพิ่มคำปุ่มควบคุมไปยังแบบฟอร์ม Form1
  6. คลิกขวาbutton1แล้ว คลิกคุณสมบัติ.
  7. ตั้งค่านี้ข้อความคุณสมบัติการเชื่อมต่อกับเซิร์ฟเวอร์.
  8. เพิ่มคำป้ายชื่อควบคุมไปยังแบบฟอร์ม Form1 Label1ป้ายชื่อตัวควบคุมที่ถูกเพิ่มเข้าไปform1แบบฟอร์ม
  9. ตั้งค่านี้มองเห็นได้คุณสมบัติของ Label1ป้ายชื่อควบคุมการเท็จ.
  10. เพิ่มสองกล่องข้อความตัวควบคุมฟอร์ม Form1

เขียนโค้ดการเชื่อมต่อกับเซิร์ฟเวอร์ไปป์ที่มีชื่อ

การเชื่อมต่อกับเซิร์ฟเวอร์ไปป์ที่มีชื่อ โดยใช้การCallNamedPipeฟังก์ชัน หลังจากการเชื่อมต่อกับเซิร์ฟเวอร์CallNamedPipeฟังก์ชันเขียนไปยังไปป์ อ่านจากไปป์นั้น และจากนั้น ปิดไปป์ เมื่อต้องการเชื่อมต่อกับเซิร์ฟเวอร์ และอ่าน หรือเขียนข้อมูล ดำเนินการดังต่อไปนี้:
  1. ในมุมมองออกแบบ คลิกสองครั้งเชื่อมต่อกับเซิร์ฟเวอร์แล้ว เพิ่มโค้ดต่อไปนี้ไปButton1_Clickขั้นตอน:
    Dim i, res, cbRead,numBytes As Integer
    Dim bArray() As Byte
    Dim temp As String
    
    numBytes = CInt(TextBox1.Text)
    If numBytes < 0 Then
        MessageBox.Show("Value must be at least 0.", MsgBoxStyle.OKOnly)
        Exit Sub
    End If
    If numBytes = 0 Then
        Label1.Visible = True
        Label1.Text = "The connection to the server is disconnected."
        Button1.Visible = False
        TextBox1.Visible = False
        TextBox2.Visible = False
    End If
    If numBytes > BUFFSIZE Then
        numBytes = BUFFSIZE
    End If
    
    ReDim bArray(numBytes) 'Create the return buffer
    'Call the CallNamedPipe function to do the transactions
     res = CallNamedPipe(pipeName, numBytes, Len(numBytes), bArray(0), numBytes, cbRead, 30000) 
    'Wait up to 30 seconds for a response
    'Format the data received, and then display the data in the text box
    If res > 0 Then
        temp = Format(bArray(0), " 000")
        For i = 1 To cbRead - 1
           If (i Mod 16) = 0 Then temp = temp & vbCrLf
              temp = temp & " " & Format(bArray(i), "000")
        Next i
        TextBox2.Text = temp
    Else
    MessageBox.Show("Error number " & Err.LastDllError & _
    "while trying to call the CallNamedPipe function.", MsgBoxStyle.OKOnly)
    End If
  2. เพิ่มรหัสต่อไปนี้ก่อนButton1_Clickขั้นตอน:
    Private Const pipeName As String = "\\.\pipe\MyPipe"
    Private Const BUFFSIZE As Integer = 10000
    Private hpipe As Integer
        
    Public Const INVALID_HANDLE_VALUE As Short = -1
    Public Declare Function CallNamedPipe Lib "kernel32" Alias "CallNamedPipeA" _
    (ByVal lpNamedPipeName As String, _
    ByRef lpInBuffer As Integer, _
    ByVal nInBufferSize As Integer, _
    ByRef lpOutBuffer As Byte, _
    ByVal nOutBufferSize As Integer, _
    ByRef lpBytesRead As Integer, ByVal nTimeOut As Integer) As Integer
  3. ในการการสร้างเมนู คลิกสร้างโซลูชัน.

ตรวจสอบว่า รหัสการทำงาน

เมื่อต้องการตรวจสอบว่า รหัสของคุณทำงาน ดำเนินการดังต่อไปนี้:
  1. เมื่อต้องการเริ่มการทำงานโปรแกรมประยุกต์ของเซิร์ฟเวอร์ คลิกเริ่มการทำงานในการตรวจแก้จุดบกพร่องเมนูของโครงการ MyServerApp
  2. ในแบบฟอร์ม Form1 คลิกสร้างไปป์ที่มีชื่อแล้ว คลิกรอให้การเชื่อมต่อไคลเอนต์. โปรแกรมประยุกต์ที่ถูกบล็อคในขณะนี้ และรอสำหรับไคลเอ็นต์ในการเชื่อมต่อ
  3. เมื่อต้องการเริ่มต้นแอพลิเคชันไคลเอนต์ คลิกเริ่มการทำงานในการตรวจแก้จุดบกพร่องเมนูของโครงการ MyClientApp
  4. ในแบบฟอร์ม Form1 พิมพ์10ในการTextBox1กล่อง แล้วคลิกเชื่อมต่อกับเซิร์ฟเวอร์. คุณสามารถดูอาร์เรย์ไบต์ที่รับในการTextBox2กล่อง
  5. เมื่อต้องการยกเลิกการแอพลิเคชันไคลเอนต์จากเซิร์ฟเวอร์ พิมพ์0ในการTextBox1กล่องในแอพลิเคชันไคลเอนต์ และจากนั้น คลิกเชื่อมต่อกับเซิร์ฟเวอร์.
  6. ปิดโปรแกรมประยุกต์ของไคลเอ็นต์
  7. เมื่อต้องการตัดการเชื่อมต่อท้ายไปป์ที่มีชื่อเซิร์ฟเวอร์ และโปรแกรมประยุกต์ของเซิร์ฟเวอร์ที่ปิดแล้ว คลิกตัดการเชื่อมต่อเซิร์ฟเวอร์ในแบบฟอร์ม Form1 ของเซิร์ฟเวอร์แอพลิเคชัน

ข้อมูลอ้างอิง

สำหรับข้อมูลเพิ่มเติม โปรดไปที่เว็บไซต์ของ Microsoft สำหรับนักพัฒนาเครือข่าย (MSDN) ต่อไปนี้:
pipes ที่มีชื่อ
http://msdn2.microsoft.com/en-us/library/aa365590.aspx
ธุรกรรม pipes ที่มีชื่อ
http://msdn2.microsoft.com/en-us/library/aa365789.aspx
ฟังก์ชันของไปป์
http://msdn2.microsoft.com/en-us/library/aa365781.aspx

คุณสมบัติ

หมายเลขบทความ (Article ID): 871044 - รีวิวครั้งสุดท้าย: 18 ตุลาคม 2553 - Revision: 2.0
ใช้กับ
  • Microsoft Visual Basic 2005
  • Microsoft Visual Basic .NET 2003 Standard Edition
  • Microsoft Visual Basic .NET 2002 Standard Edition
Keywords: 
kbvs2005swept kbvs2005applies kbserver kbpipes kbipc kbclient kbhowtomaster kbhowto kbmt KB871044 KbMtth
แปลโดยคอมพิวเตอร์
ข้อมูลสำคัญ: บทความนี้แปลโดยซอฟต์แวร์การแปลด้วยคอมพิวเตอร์ของ Microsoft แทนที่จะเป็นนักแปลที่เป็นบุคคล Microsoft มีบทความที่แปลโดยนักแปลและบทความที่แปลด้วยคอมพิวเตอร์ เพื่อให้คุณสามารถเข้าถึงบทความทั้งหมดในฐานความรู้ของเรา ในภาษาของคุณเอง อย่างไรก็ตาม บทความที่แปลด้วยคอมพิวเตอร์นั้นอาจมีข้อบกพร่อง โดยอาจมีข้อผิดพลาดในคำศัพท์ รูปแบบการใช้ภาษาและไวยากรณ์ เช่นเดียวกับกรณีที่ชาวต่างชาติพูดผิดเมื่อพูดภาษาของคุณ Microsoft ไม่มีส่วนรับผิดชอบต่อความคลาดเคลื่อน ความผิดพลาดหรือความเสียหายที่เกิดจากการแปลเนื้อหาผิดพลาด หรือการใช้บทแปลของลูกค้า และ Microsoft มีการปรับปรุงซอฟต์แวร์การแปลด้วยคอมพิวเตอร์อยู่เป็นประจำ
ต่อไปนี้เป็นฉบับภาษาอังกฤษของบทความนี้:871044

ให้ข้อเสนอแนะ

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com