好的,这就是我最终要做的……不,这个问题没有答案/不是重复的。
简而言之,我的问题的答案是这样的:
它无法完成/没有简单且内置的方法可以知道应用程序在何处真正运行,而不考虑“用户域/配置文件/上下文”。
因此,必须以以下方式(伪编码)实现更复杂和全面的解决方案:
使 RunLocation = GetEntryAssembly!
IF RunLocation == ServerLocationAsUNC 或 LocalServerLocation
{
//所以在这里,如果位置是 \\SERVER\SharedFolder\App\ OR D:\Shares\MyAppSharedFolder\Loader\
提示安装位置/不要运行!
}
别的
{
IF RunLocation 以“\\”开头
{
从 RunLocation 中提取服务器名称
获取该服务器的 IP 地址
IF RunLocationIP == KnownServerIP
{
提示安装位置/不要运行!
}
别的
{
允许运行!
}
}
ELSE(如果 RunLocation 不以“\\”开头)
{
获取 RunLocation 的 DriveInfo(例如:“E:\”)
如果 DriveInfo 不是网络位置
{
允许运行!
}
别的
{
使用 ManagementObject,获取该 DriveInfo 的 UNC 路径
从 UNCPath 中提取服务器名称
获取该服务器的 IP 地址
IF DriveLocationIP == KnownServerIP
{
提示安装位置/不要运行!
}
别的
{
允许运行!
}
}
}
}
这就是伪代码版本...
这是我最终构建的实际方法,用于检查并在需要它的任何地方使用它...请记住,这并非完美无缺(例如,如果本地 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;
}