我有一个我已经构建的应用程序,我已将其放在服务器上的共享驱动器上,以便将其分发给其他用户。但是,我希望应用程序检查它的启动位置,如果它直接在共享上启动,则弹出一条消息,说明如下:“应用程序无法从此位置运行。是否要安装它你的本地电脑呢?“
我遇到的问题如下:因为用户通过浏览共享来启动它,应用程序中的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的正确方法是什么,无论它在哪里运行或者如何浏览它?
答案 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;
}