2014-08-28 27 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; 
    }