2009-09-16 57 views
0

我們正在開發一個Web服務,該服務必須運行與映射網絡驅動器交互的第三方進程。所以我們必須以Web服務的編程方式映射這個驅動器。C# - 從Web服務映射網絡驅動器

我已經包裹起來WNetAddConnection2,等在另一個項目一個更好的課,所以我扔的代碼權利英寸

我們的Web服務是根據UltiDev卡西尼號(而不是IIS)這下運行運行系統帳戶。我們每次都得到「指定設備名稱無效」的錯誤代碼。我也嘗試在web.config文件中模擬其他用戶,結果相同。

驅動器將映射得很好,當我從一個正常的用戶帳戶下的控制檯程序運行我的代碼。

我也嘗試從C#運行等效的「net use」命令,其結果與WNetAddConnection完全相同。

有誰知道爲什麼Windows服務或系統用戶將無法映射網絡驅動器?

有誰知道解決方法?在系統啓動時簡單映射驅動器將是一個解決方案,但系統/模擬用戶如何訪問它?

鏈接UltiDev卡西尼號:UltiDev

SOLUTION:我設置UltiDev卡西尼服務在管理員登錄,一切工作正常。 ASP .Net模擬不能按計劃運行。

回答

2

如果您使用本地系統帳戶,那麼我認爲它本質上不能訪問網絡[foo]。我會說模仿是你唯一可行的途徑。從技術上講,你可以減少對共享的訪問控制,以便任何人都可以讀取/寫入共享,但這會帶來比解決方案更多的問題。

+0

那麼爲什麼web.config模擬不起作用?我在我們的日誌中打印了Environment.Username,並打印了管理員,但是如果我查看UltiDev進程 - 它仍在Local System下。 UltiDev能做些奇怪的事情嗎? – jonathanpeppers 2009-09-16 13:42:15

+1

本地系統帳戶具有網絡訪問權限,但它向網絡資源提供匿名憑據。 – bryanbcook 2009-09-16 13:53:25

1

我們遇到了同樣的問題。由於代碼正在運行的帳戶發生問題。您可以像我們通過使用以下課程那樣解決此問題。您必須將驅動器映射到您用來訪問/複製文件的相同代碼中。我們使用的模式是始終檢查驅動器是否先連接。如果是這樣,我們斷開它,然後重新連接它。如果沒有,我們只是連接它。它似乎清除了你所描述的問題。

public static class NetworkDrives 
    { 
     public static bool MapDrive(string DriveLetter, string Path, string Username, string Password) 
     { 

      bool ReturnValue = false; 

      if(System.IO.Directory.Exists(DriveLetter + ":\\")) 
      { 
       DisconnectDrive(DriveLetter); 
      } 
      System.Diagnostics.Process p = new System.Diagnostics.Process(); 
      p.StartInfo.UseShellExecute = false; 
      p.StartInfo.CreateNoWindow = true; 
      p.StartInfo.RedirectStandardError = true; 
      p.StartInfo.RedirectStandardOutput = true; 

      p.StartInfo.FileName = "net.exe"; 
      p.StartInfo.Arguments = " use " + DriveLetter + ": " + '"' + Path + '"' + " " + Password + " /user:" + Username; 
      p.Start(); 
      p.WaitForExit(); 

      string ErrorMessage = p.StandardError.ReadToEnd(); 
      string OuputMessage = p.StandardOutput.ReadToEnd(); 
      if (ErrorMessage.Length > 0) 
      { 
       throw new Exception("Error:" + ErrorMessage); 
      } 
      else 
      { 
       ReturnValue = true; 
      } 
      return ReturnValue; 
     } 
     public static bool DisconnectDrive(string DriveLetter) 
     { 
      bool ReturnValue = false; 
      System.Diagnostics.Process p = new System.Diagnostics.Process(); 
      p.StartInfo.UseShellExecute = false; 
      p.StartInfo.CreateNoWindow = true; 
      p.StartInfo.RedirectStandardError = true; 
      p.StartInfo.RedirectStandardOutput = true; 

      p.StartInfo.FileName = "net.exe"; 
      p.StartInfo.Arguments = " use " + DriveLetter + ": /DELETE"; 
      p.Start(); 
      p.WaitForExit(); 

      string ErrorMessage = p.StandardError.ReadToEnd(); 
      string OuputMessage = p.StandardOutput.ReadToEnd(); 
      if (ErrorMessage.Length > 0) 
      { 
       throw new Exception("Error:" + ErrorMessage); 
      } 
      else 
      { 
       ReturnValue = true; 
      } 
      return ReturnValue; 
     } 

    } 
+0

我無法斷開連接並重新連接,因爲它不會首先連接。 – jonathanpeppers 2009-09-16 14:12:30

0

而不是一個映射的驅動器,你可以連接使用UNC共享?

我仍然冒充有權訪問共享的用戶。

+0

我們與之交互的第三方進程必須使用普通驅動器號,例如f:\ – jonathanpeppers 2009-09-16 13:54:27

0

我以前實際上已經做到了這一點,但它是很久以前的 - 比如1997年和Win NT 3。51用Delphi 2

我是從內存中運行,但我認爲這是這樣的: 您使用贏API:

WNetAddConnection2()

信息上的電話:http://msdn.microsoft.com/en-us/library/aa385413(VS.85).aspx

您可以從pInvoke.net獲得C#簽名:http://www.pinvoke.net/default.aspx/mpr/WNetAddConnection2.html

注意的配置: 我認爲你將需要建立一個域帳戶服務,並使用該帳戶的身份而不是本地系統運行該服務。我認爲你傳遞null作爲用戶名和密碼。

可能能夠運行服務作爲本地系統傳遞域帳戶的用戶名和密碼 - 我不知道系統帳戶是否允許任何網絡訪問。

+0

我已經實現了WNetAddConnection2。 – jonathanpeppers 2009-09-16 14:11:36

+0

@Jonathan:你在我的文章中應用了配置註釋嗎?它可能不適用於以本地系統運行的服務 - 您需要設置一個具有網絡訪問權限和訪問您正在連接的共享的適當權限的域帳戶。該服務必須以該帳戶運行,而不是本地系統。 – JMarsch 2009-09-16 15:45:31

0

要記住的一般概念是'映射驅動器字母'是用戶的概念,而不是系統的概念。因此,當Joe登錄到Windows計算機時,映射的驅動器將連接到Joe用戶帳戶。 Windows服務運行時,通常在LOCAL_SYSTEM'用戶帳戶'下運行,這意味着LOCAL_SYSTEM不知道Joe的映射驅動器號。

因此,UNC訪問網絡共享是嘗試從Windows服務中訪問任何遠程資源時要走的路。請注意,您可以在'Joe'用戶帳戶的上下文中運行Windows服務,或者您可以創建一個名爲「MyServiceAccount」的虛擬AD帳戶,並將該帳戶權限授予UNC,或者您可以使用模擬並擁有Windows服務使用具有模擬句柄的NetLogon()函數登錄到本地工作站,然後從那裏訪問UNC。

有很多方法可以做到這一點,但所有涉及到用戶帳戶都與映射驅動器和UNC訪問相關聯。

祝你好運,希望這個信息有幫助!

相關問題