2014-08-28 28 views
0

我有一個我已經構建的應用程序,並且我已將它放在服務器上的共享驅動器上,以便將其分發給其他用戶。但是,我希望應用程序檢查它正在啓動的位置,如果它直接在共享上啓動,則會彈出一條消息,其中顯示如下所示:「應用程序無法從此位置運行。是否要將其安裝在你的本地電腦呢?「得到本地路徑,不管用戶如何瀏覽它

我遇到的問題如下:因爲用戶通過瀏覽到共享啓動它,應用程序中的CurrentDomain與用戶瀏覽共享的方式有關。因此,基本上不可能(這是我的問題:)確定應用程序是否在服務器上啓動!

如果用戶手動瀏覽到該共享通過鍵入:
\\SERVER\SharedFolder\App\MyApp.exe
然後執行assemly總是返回UNC共享(\ ...)...

然而,如果用戶被遠程處理到服務器,路徑會是這樣:
D:\Shares\MyAppSharedFolder\Loader\MyApp.exe

如果用戶同時存在着SharedFolder映射到自己的本地驅動器Z:
Z:\App\MyApp.exe
然後返回的值是Z:\值。

所以我的問題是:是否有一種簡單的方法可以始終獲得相同的值,無論用戶在啓動後如何瀏覽應用程序?

我想這個解決方案:
http://briancaos.wordpress.com/2009/03/05/get-local-path-from-unc-path/
但是,這隻能如果路徑是UNC共享格式(\ ...)

那麼,什麼是讓正在運行的.exe文件的有道TRUE本地路徑,無論它正在運行還是瀏覽方式如何?

+0

可能重複[如何確定給定的驅動器號是否是本地/映射/ USB驅動器?](http:// stackoverflow。COM /問題/ 4396634 /如何-可以-I-確定-IF-A-給驅動器字母-is-a的本地映射-USB驅動器)。問題的根源在於驅動器是否本地,其原因是輔助的。 – 2014-08-28 18:45:27

+0

@ErikPhilips我不同意...我想獲得執行程序集的本地路徑,無論用戶域在哪裏運行,或者他/她如何瀏覽它......如果答案是「你不能和必須考慮所有場景「,那麼我會用這個答案來幫助我構建這個(更大的)代碼段,但是有沒有辦法以其他方式輕鬆獲取本地/實際組裝路徑? – MaxOvrdrv 2014-08-28 18:46:59

+0

然後你問你如何得到[Assembly.GetExecutingAssembly()](http://msdn.microsoft.com/en-us/library/system.reflection.assembly.getexecutingassembly(v = vs.110).aspx)執行[位置](http://msdn.microsoft.com/en-us/library/system.reflection.assembly.location(v = vs.110).aspx)?我也不知道'用戶域'是什麼意思,並且知道如何執行應用程序對根問題沒有用處(因爲如果我在桌面上創建一個快捷方式,這是瀏覽到的位置,啓動應用程序,但現在它從哪裏執行)。 – 2014-08-28 18:48:30

回答

0

好吧,所以這裏是我最終做的......不,這個問題沒有答案/不是重複的。

總之,我的問題的答案是這樣的:
它不能完成/沒有簡單的內置方式來知道應用程序在哪裏運行真正的運行沒有考慮到「用戶域/資料/語境」。

因此,更爲複雜和全面的解決方案有以下方式(僞碼),以實現:

 

Make RunLocation = GetEntryAssembly! 

IF RunLocation == ServerLocationAsUNC OR LocalServerLocation 
{ 
//so here, if the location is \\SERVER\SharedFolder\App\ OR D:\Shares\MyAppSharedFolder\Loader\ 
    PROMPT FOR INSTALL LOCATION/DO NOT RUN! 
} 
ELSE 
{ 
    IF RunLocation Starts With a "\\" 
    { 
     Extract the Server name from RunLocation 
     Get the IP Address of that server 

     IF RunLocationIP == KnownServerIP 
     { 
      PROMPT FOR INSTALL LOCATION/DO NOT RUN! 
     } 
     ELSE 
     { 
      ALLOW TO RUN! 
     } 
    } 
    ELSE (if RunLocation does NOT start with a "\\") 
    { 
     Get the DriveInfo for RunLocation (example: "E:\") 
     IF the DriveInfo is NOT a Network Location 
     { 
      ALLOW TO RUN! 
     } 
     ELSE 
     { 
      Using ManagementObject, Get the UNC path for that DriveInfo 
      Extract the Server name from UNCPath 
      Get the IP Address of that server 

      IF DriveLocationIP == KnownServerIP 
      { 
       PROMPT FOR INSTALL LOCATION/DO NOT RUN! 
      } 
      ELSE 
      { 
       ALLOW TO RUN! 
      } 
     } 
    } 
} 

所以這是僞代碼版本...

這裏的實際方法我結束了建設檢查這一點,並在任何我需要它的地方使用它...請記住,這不是完美的(例如,如果本地PC具有相同的預期本地服務器路徑,並選擇,它會提示對於安裝位置,當它不應該,我真的不介意我自己),它是爲我的需要而建立的,所以我在那裏有一些額外的檢查(像,不能是桌面),你可能不需要...但不管,這裏是實際的編碼版本。

private enum I_Am 
    { 
     OnTheServer, 
     OnTheLocalPC 
    } 

    /// <summary> 
    /// This method returns whether or not the application is being run at an appropriate location. 
    /// </summary> 
    /// <returns>Enum I_Am - Either: I_Am.OnTheServer OR I_Am.OnTheLocalPC</returns> 
    private I_Am CheckLocation() 
    { 
     //decalre local vars... 
     string bs = Path.DirectorySeparatorChar.ToString(); 
     string dbs = bs +bs; 
     string dir = MyBaseDir; 
     I_Am retval = I_Am.OnTheServer; 

     //if run location is the UNC Share Server Path OR the Expected Local Server Path, or the Desktop or at the Root of a drive 
     //consider this a server/invalid run location. 
     if (dir == ServerBaseDir || 
      dir == LocalServerBaseDir || 
      dir == DesktopDir || 
      IsRootDrive(dir)) 
     { 
      retval = I_Am.OnTheServer; 
     } 
     else 
     { 
      //if the location is a UNC path entered by the user (e.g.: "\\ServerName") 
      if (dir.StartsWith(dbs)) 
      { 
       //extract the server name from the path 
       dir = dir.Remove(0, 2); 
       List<string> parts = dir.Split(new string[] { bs }, StringSplitOptions.None).ToList(); 
       string servername = parts[0]; 
       //get the list of possible IP addresses for that server 
       System.Net.IPHostEntry server = System.Net.Dns.GetHostEntry(servername); 
       //if that list of IPs contains our distribution server, consider this a server/invalid run location. 
       //else, all good/allow to run! 
       if (server.AddressList.Contains(System.Net.IPAddress.Parse(ServerIP))) 
        retval = I_Am.OnTheServer; 
       else 
        retval = I_Am.OnTheLocalPC; 

      } 
      else 
      { 
       //if this is a local drive, it could be mapped to a share/network location which we must check) 

       //get the drive info for the drive... 
       DriveInfo drive = new DriveInfo(dir[0].ToString()); 
       //if it's NOT a network drive, all good/allow to run! 
       if (drive.DriveType != DriveType.Network) 
       { 
        return I_Am.OnTheLocalPC; 
       } 
       else 
       { 
        //if this is a network drive, we now have to check the UNC to IP mapping again... 

        //get the UNC path from the ManagementObject... 
        ManagementObject mo = new ManagementObject(); 
        mo.Path = new ManagementPath(string.Format("Win32_LogicalDisk='{0}'", drive.Name)); 
        dir = Convert.ToString(mo["ProviderName"]); 

        //extract the server name from the path 
        dir = dir.Remove(0, 2); 
        List<string> parts = dir.Split(new string[] { bs }, StringSplitOptions.None).ToList(); 
        string servername = parts[0]; 
        //get the list of possible IP addresses for that server 
        System.Net.IPHostEntry server = System.Net.Dns.GetHostEntry(servername); 
        //if that list of IPs contains our distribution server, consider this a server/invalid run location. 
        //else, all good/allow to run! 
        if (server.AddressList.Contains(System.Net.IPAddress.Parse(ServerIP))) 
         retval = I_Am.OnTheServer; 
        else 
         retval = I_Am.OnTheLocalPC; 
       } 
      } 
     } 

     return retval; 
    }