无论用户如何浏览它,都可以获得本地路径

时间:2014-08-28 18:43:33

标签: c# .net-assembly unc

我有一个我已经构建的应用程序,我已将其放在服务器上的共享驱动器上,以便将其分发给其他用户。但是,我希望应用程序检查它的启动位置,如果它直接在共享上启动,则弹出一条消息,说明如下:“应用程序无法从此位置运行。是否要安装它你的本地电脑呢?“

我遇到的问题如下:因为用户通过浏览共享来启动它,应用程序中的CurrentDomain与用户浏览共享的方式有关。因此,基本上不可能(这是我的问题:)确定应用程序是否正在服务器上启动!

如果用户通过键入以下内容手动浏览共享:
\\SERVER\SharedFolder\App\MyApp.exe
然后执行的assemly总是返回UNC共享(\ ...)...

但是,如果用户正在远程进入服务器,那么路径将是这样的:
D:\Shares\MyAppSharedFolder\Loader\MyApp.exe

但是,如果用户将SharedFolder映射到他的本地驱动器Z:
Z:\App\MyApp.exe
然后返回的值是Z:\ value。

所以我的问题是:是否有一种简单的方法可以始终获得相同的值,无论用户在启动后如何浏览应用程序?

我试过这个解决方案:
http://briancaos.wordpress.com/2009/03/05/get-local-path-from-unc-path/
但是,如果路径是UNC共享格式(\ ...)

,那只能起作用

那么获取运行TRUE本地路径的.exe的正确方法是什么,无论它在哪里运行或者如何浏览它?

1 个答案:

答案 0 :(得分: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;
    }