我正在尝试使用Path.GetFullPath()
获取应用程序“ WinMergeU.exe”的路径,但是此代码的返回值是我的应用程序的文件夹。
当使用C:
返回值为d
时,如何在Path.GetFullPath()
驱动器中获取应用程序的完整路径。
答案 0 :(得分:3)
您必须搜索以查找文件,例如
using system.Linq;
...
// Either full path of "WinMergeU.exe" file or null (if not found)
string result = Directory
.EnumerateFiles(@"c:\", "WinMergeU.exe", SearchOption.AllDirectories)
.FirstOrDefault();
编辑:如果应用程序位于C:\Program Files
中(请参见注释),我们可以限制扫描:
string result = Directory
.EnumerateFiles(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles),
"WinMergeU.exe",
SearchOption.AllDirectories)
.FirstOrDefault();
或者(如果我们非常确定在c:\Program Files\WinMerge
路径中),我们可以测试文件是否退出:
string result = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles),
"WinMerge",
"WinMergeU.exe");
if (File.Exists(result)) {
// we have the file
}
答案 1 :(得分:2)
我安装了它,因为它看起来很方便,并且搜索了注册表。
string key = @"HKEY_LOCAL_MACHINE\SOFTWARE\Classes\WinMerge.Project.File\shell\open\command";
string path = Microsoft.Win32.Registry.GetValue(key, "", -1);
...似乎包含您需要的值。就我而言:
"C:\Program Files (x86)\WinMerge\WinMergeU.exe" "%1"
如果找不到密钥,该方法将返回-1。
答案 2 :(得分:0)
WinMerge不允许更改其安装文件夹AFAIK,因此搜索整个驱动器C实在是过大。
这足够了:
static string GetWinMergeFullPath()
{
const string executableName = "WinMergeU.exe";
const string installationFolder = "WinMerge";
var locations = new Environment.SpecialFolder[]
{
Environment.SpecialFolder.ProgramFiles,
Environment.SpecialFolder.ProgramFilesX86
};
string fullPath = locations
.Select(l => Path.Combine(Environment.GetFolderPath(l), installationFolder, executableName))
.Where(File.Exists)
.FirstOrDefault();
return fullPath ?? throw new FileNotFoundException(executableName);
}
编辑
正如上面所评论的那样,这还不够:)。以下版本使用两个注册表位置,其中应包含该路径。一个是安装程序提供的“应用程序路径”,第二个是“卸载”。尽管我相信“应用程序路径”应该足够了,但我仍然提供了第二个功能来确保鲁棒性。请注意,即使在安装程序中未选中外壳集成,它也能正常工作!涵盖了32位和64位安装。
static string GetWinMergeFullPathFromRegistryEx()
{
const string executableName = "WinMergeU.exe";
const string appPathKeyName = @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\";
const string uninstallKeyName = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\WinMerge_is1";
const string installLocationName = "InstallLocation";
var locations = new List<(string path, string value, bool withFilename)>
{
($"{appPathKeyName}{executableName}", null, true),
(uninstallKeyName, installLocationName, false),
};
List<RegistryView> views = Environment.Is64BitOperatingSystem ?
new List<RegistryView>() { RegistryView.Registry32, RegistryView.Registry64 } :
new List<RegistryView>() { RegistryView.Default };
foreach (var view in views)
{
using (RegistryKey localMachine = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, view))
foreach (var (path, value, withFilename) in locations)
{
using (RegistryKey key = localMachine.OpenSubKey(path, false))
{
var fullpathValue = key?.GetValue(value);
if (fullpathValue != null)
{
string fullpath = (string)fullpathValue;
if (!withFilename)
fullpath = Path.Combine(fullpath, executableName);
if (File.Exists(fullpath))
return fullpath;
}
}
}
}
throw new FileNotFoundException(executableName);
}
当然,我的假设是实际上已安装WinMerge。如果您应该支持手动部署WinMerge的情况,那么仍然可以使用完整扫描选项作为后备。