C# excel在注册表中的安装位置
我需要检测注册表中的excel安装位置并打开excel文件。我找到了一个示例代码。 我有两个问题:首先,代码中给定的注册表路径中没有InstallRoot directorty RegistryKey rootdir=excelKey.OpenSubKey(当前版本+ @“.0\Excel\InstallRoot”) 但它确实存在于此路径下(SOFTWARE\Wow6432Node\MicroSoft\Office) 另一个问题是,我收到的信息是“无法在excel中打开” 因为excel没有安装。”所以我认为CurrentVersion返回worng值 在我的例子中(自2007年以来),它返回120.0而不是12.0C# excel在注册表中的安装位置,c#,C#,我需要检测注册表中的excel安装位置并打开excel文件。我找到了一个示例代码。 我有两个问题:首先,代码中给定的注册表路径中没有InstallRoot directorty RegistryKey rootdir=excelKey.OpenSubKey(当前版本+ @“.0\Excel\InstallRoot”) 但它确实存在于此路径下(SOFTWARE\Wow6432Node\MicroSoft\Office) 另一个问题是,我收到的信息是“无法在excel中打开” 因为excel没有安装
public void OpenInExcel(string filename)
{
string dir = "";
RegistryKey key = Registry.LocalMachine;
RegistryKey excelKey = key.OpenSubKey(@"SOFTWARE\MicroSoft\Office");
if (excelKey != null)
{
foreach (string valuename in excelKey.GetSubKeyNames())
{
int version = 9;
double currentVersion=0;
if (Double.TryParse(valuename, out currentVersion) && currentVersion >= version)
{
RegistryKey rootdir = excelKey.OpenSubKey(currentVersion + @".0\Excel\InstallRoot");
if (rootdir != null)
{
dir = rootdir.GetValue(rootdir.GetValueNames()[0]).ToString();
break;
}
}
}
}
if (dir != "")
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = dir + @"Excel.exe";
startInfo.Arguments = "\"" + fileName + "\"";
startInfo.UseShellExecute = false;
using (Process process = new Process())
{
process.StartInfo = startInfo;
try
{
process.Start();
}
catch (Exception ex)
{
Console.WriteLine("\n\nCould not start Excel process.");
Console.WriteLine(ex);
}
}
}
else
{
MessageBox.Show("Can't Open in excel because excel is not installed.");
}
}
@编辑:我认为这行出现了一些错误,返回了错误的值,因为它是这样工作的
RegistryKey rootdir=excelKey.OpenSubKey(
@“12.0\Excel\InstallRoot”)
我不知道为什么TryParse返回120.0这不是对您的问题的回答,但它可能会帮助您获得正确的版本号,我不能在评论中发布所有这些代码
public const string CProgIdOutlook = "Outlook.Application";
/// <summary>
/// Method to get the Outlook version number, which will presumably be 11 (2003), 12 (2007),
/// 14 (2010) or 15 (2013). (I wonder what happened to version 13?) An exception is thrown if
/// this method is unable to provide an answer.
///
/// The technique used to get the version number of the "current" installed version of Outlook
/// is one of many possible methods that are described in various Internet sources, and is
/// hopefully the most likely to provide the correct answer with the least side-effects.
/// Problems with some of the alternative registry-based methods typically show up when
/// multiple versions of Outlook are installed or have been installed. The registry values can
/// also depend on x86 vs. x64 systems and whether Outlook was installed for one user or for
/// all users. Techniques involving querying the Outlook automation object have the
/// disadvantage of an instance of the Outlook program getting created - this can be seen in
/// Task Manager.
///
/// The idea for this code came from here: http://support.microsoft.com/kb/240794
/// </summary>
/// <returns>11 (2003), 12 (2007), 14 (2010) or 15 (2013)</returns>
private static int GetOutlookVersion()
{
const string CRegistryKey = @"SOFTWARE\Classes\" + GroupwareProgIds.CProgIdOutlook;
int outlookVersion;
using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(CRegistryKey))
{
outlookVersion = GetOutlookVersion(registryKey);
if (outlookVersion != -1)
return outlookVersion;
}
using (RegistryKey registryKey = Registry.CurrentUser.OpenSubKey(CRegistryKey))
{
outlookVersion = GetOutlookVersion(registryKey);
if (outlookVersion != -1)
return outlookVersion;
}
throw new MerliniaException(0x2d4a67fu, "No registry entry for " + CRegistryKey);
}
/// <summary>
/// Sub-method of above method to do the work for either HKLM or HKCU.
/// </summary>
/// <returns>11 (2003), 12 (2007), 14 (2010) or 15 (2013), or -1 for error</returns>
private static int GetOutlookVersion(RegistryKey registryKey1)
{
const string CCurVer = "CurVer";
if (registryKey1 == null)
return -1;
using (RegistryKey registryKey2 = registryKey1.OpenSubKey(CCurVer))
{
if (registryKey2 == null)
throw new MerliniaException(0x2d43e5au,
"No registry entry for " + registryKey1 + "\\" + CCurVer);
string currentOutlookAppName = registryKey2.GetValue(null) as string;
if (currentOutlookAppName != null)
{
string[] sa = currentOutlookAppName.Split('.');
if (sa.Length == 3)
{
int outlookVersion;
if (int.TryParse(sa[2], NumberStyles.Integer,
CultureInfo.InvariantCulture, out outlookVersion))
return outlookVersion;
}
}
throw new MerliniaException(0x2d4b29du,
"Invalid registry content for " + registryKey1 + "\\" + CCurVer);
}
}
公共常量字符串CProgIdOutlook=“Outlook.Application”;
///
///方法获取Outlook版本号,大概是11(2003)、12(2007),
///第14条(2010年)或第15条(2013年)。(我想知道版本13发生了什么?)如果
///此方法无法提供答案。
///
///用于获取Outlook“当前”安装版本的版本号的技术
///是各种Internet来源中描述的许多可能方法之一,并且
///希望最有可能以最少的副作用提供正确答案。
///一些基于注册表的替代方法的问题通常在
///已安装或已安装多个版本的Outlook。注册表值可以
///还取决于x86和x64系统,以及Outlook是为一个用户安装的还是为其他用户安装的
///所有用户。涉及查询Outlook自动化对象的技术具有以下特点:
///创建Outlook程序实例的缺点-可以在中看到
///任务管理器。
///
///此代码的想法来自于此:http://support.microsoft.com/kb/240794
///
///11(2003)、12(2007)、14(2010)或15(2013)
私有静态int GetOutlookVersion()
{
const string CRegistryKey=@“软件\类\”+GroupwareProgIds.CProgIdOutlook;
国际展望版;
使用(RegistryKey RegistryKey=Registry.LocalMachine.OpenSubKey(CRegistryKey))
{
outlookVersion=GetOutlookVersion(registryKey);
如果(了望版本!=-1)
返回了望版本;
}
使用(RegistryKey RegistryKey=Registry.CurrentUser.OpenSubKey(CRegistryKey))
{
outlookVersion=GetOutlookVersion(registryKey);
如果(了望版本!=-1)
返回了望版本;
}
抛出新的MerliniaException(0x2d4a67fu,“没有“+CRegistryKey”的注册表项);
}
///
///为HKLM或HKCU开展工作的上述方法的子方法。
///
///11(2003)、12(2007)、14(2010)或15(2013)或-1表示错误
私有静态int GetOutlookVersion(RegistryKey registryKey1)
{
常量字符串ccerver=“CurVer”;
如果(registryKey1==null)
返回-1;
使用(RegistryKey registryKey2=registryKey1.OpenSubKey(CCServer))
{
如果(registryKey2==null)
抛出新的MerliniaException(0x2d43e5au,
“没有“+registryKey1+”\\“+CCServer”的注册表项);
字符串currentOutlookAppName=registryKey2.GetValue(null)作为字符串;
如果(currentOutlookAppName!=null)
{
字符串[]sa=currentOutlookAppName.Split('.');
如果(sa.Length==3)
{
国际展望版;
if(int.TryParse(sa[2],numberstyle.Integer,
CultureInfo.InvariantCulture,outlookVersion)
返回了望版本;
}
}
抛出新的MerliniaException(0x2d4b29du,
“+registryKey1+”\\“+CCServer”的注册表内容无效);
}
}
问题在于双重类型和文化 我试着解释: 您将获得双
12.0
值
和ToString
在美国文化中转换为12.0,在文化中转换为120.0(十进制分隔符不相同)
问题是将版本解析为双精度
由于计算机文化的考虑,作为小数点分隔符和。作为千分之一
您可以这样更改代码(当您尝试Double.TryParse
时):
if(Double.TryParse(valuename,System.Globalization.NumberStyles.Any,System.Globalization.CultureInfo.InvariantCulture,out-currentVersion)&¤tVersion>=version)
您有什么特别的原因不想设置startInfo.UseShellExecute=true
,startInfo.FileName=@“document.xls”
剩下的就让操作系统来做吧?你标记了RenniePet答案<代码>这不是对您的问题的回答