2012-02-17 2 views
4

Следующий вызов WNetAddConnection2, похоже, вечен навсегда. Обратите внимание, что имя машины преднамеренно неверно - я бы хотел, чтобы это быстро закончилось, а не блокировалось навсегда. Есть ли способ достичь аналогичной функциональности, но с тайм-аутом?Как достичь эквивалента WNetAddConnection2 с таймаутом?

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 
using System.Diagnostics; 

namespace WindowsFormsApplication2 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     public class NETRESOURCE 
     { 
      public int dwScope; 
      public int dwType; 
      public int dwDisplayType; 
      public int dwUsage; 
      public string LocalName; 
      public string RemoteName; 
      public string Comment; 
      public string Provider; 
     } 
     [DllImport("mpr.dll")] 
     public static extern int WNetAddConnection2(NETRESOURCE netResource, string password, string username, int flags); 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      NETRESOURCE myResource = new NETRESOURCE(); 
      myResource.dwScope = 0; 
      myResource.dwType = 0; //RESOURCETYPE_ANY 
      myResource.dwDisplayType = 0; 
      myResource.LocalName = ""; 
      myResource.RemoteName = @"\\invalid.machine.com"; 
      myResource.dwUsage = 0; 
      myResource.Comment = ""; 
      myResource.Provider = ""; 

      int returnValue = WNetAddConnection2(myResource, "password", "username", 0); //hangs forever 
      Debug.Print("Finished connecting"); 
     } 
    } 
} 
+2

навсегда долгое время. Как долго вы ждали? Это должно в конечном итоге перерыв. –

+0

Несколько минут :) Я бы предпочел, чтобы мой поток подождал секунды. – Jon

+0

Поместите его в поток и настройте WaitHandle (как 'ManualResetEvent') с тайм-аутом на' WaitOne', а затем (сделайте грязный путь) завершите поток, используя 'Thread.Abort'. –

ответ

1

В более ранних версиях Windows, это было невозможно завершить процесс, застрял в одной из функций WNetAddConnection. Это было исправлено в Vista. According to Larry Osterman, исправление CancelSynchronousIo функция.

Решение вашей проблемы:

  1. Начать новую тему для запуска WNetAddConnection2
  2. Установка таймера или ждать в существующей теме.
  3. После вызова таймаута CancelSynchronousIo указывая дескриптор потока соединения.

Я не могу думать о какой-либо причине, почему это плохо взаимодействуют с .Net, но я на самом деле не пробовал ...

+0

+1 для ответа, но это ставит вопрос: «Как вы получаете дескриптор собственного потока управляемого потока, и вы должны это делать, если собственные потоки не имеют фиксированной связи с управляемым потоком?» – Jon

+0

Вы можете подключиться к GetCurrentThreadId непосредственно перед вызовом WNetAddConnection2, хотя это не на 100% надежнее (ваш управляемый поток может быть перенесен на другой собственный поток между двумя вызовами). Вы можете написать неуправляемую DLL, которая запустила WNetAddConnection в новом потоке и вернула идентификатор потока. Хотя это немного неряшливо. – arx

+0

Я пробовал это, но получил ERROR_NOT_FOUND, хотя поток был заблокирован на WNetAddConnection2. Согласно http://msdn.microsoft.com/en-us/library/windows/desktop/aa363794%28v=vs.85%29.aspx: «Если эта функция не может найти запрос на отмену, возвращаемое значение равно 0 (ноль), а GetLastError возвращает ERROR_NOT_FOUND. " – Jon

Смежные вопросы