C# microsoft access未在windows server 2012 r2中正确安装

C# microsoft access未在windows server 2012 r2中正确安装,c#,excel,ms-access,windows-server-2012-r2,regedit,C#,Excel,Ms Access,Windows Server 2012 R2,Regedit,我有一个C#自动化代码,可以从Microsoft Excel中提取一些数据。当我尝试在虚拟机(windows server 2012 r2)中运行此代码时,我遇到以下错误 'System.Runtime.InteropServices.COMException(0x80040154):正在检索 具有CLSID的组件的COM类工厂 {00024500-0000-0000-C000-0000000000 46}由于以下原因失败 错误:80040154类未注册(HRESULT异常: 0x8004015

我有一个C#自动化代码,可以从Microsoft Excel中提取一些数据。当我尝试在虚拟机(windows server 2012 r2)中运行此代码时,我遇到以下错误

'System.Runtime.InteropServices.COMException(0x80040154):正在检索 具有CLSID的组件的COM类工厂 {00024500-0000-0000-C000-0000000000 46}由于以下原因失败 错误:80040154类未注册(HRESULT异常: 0x80040154(REGDB_E_CLASSNOTREG))。'

我发现未安装Microsoft Access,并尝试安装相同的(Microsoft Access 2013运行时),安装成功。但奇怪的是,它没有完全安装。在
C:\ProgramFiles(x86)\Microsoft Office\Office15
中,与本地系统中的DLL相比,我只能看到一些DLL(项目引用中缺少Microsoft.Office.Interop.Access DLL)。此外,注册表中也没有键为00024500-0000-0000-C000-0000000000 46的条目

从excel获取数据的代码

 public static Dictionary<string, string> GetExcelData(string testDatapath, string testDataSheet, string testcaseID)
    {
        testCaseValues.Clear();
        Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
        Workbook book = null;
        Range range = null;
        bool arrayFlag = false;
        int iVal = 0;
        ArrayList excelValues = new ArrayList();
        ArrayList header = new ArrayList();
        try
        {
            app.Visible = false;
            app.ScreenUpdating = false;
            app.DisplayAlerts = false;
            book = app.Workbooks.Open(testDatapath);
            Console.WriteLine("fetching the excel from " + testDatapath);
            foreach (Worksheet sheet in book.Worksheets)
            {
                if (sheet.Name.Equals(testDataSheet))
                {
                    Console.WriteLine("Test data sheet is " + testDataSheet);
                    // get a range to work with
                    range = sheet.get_Range("A1", Missing.Value);
                    // get the end of values to the right (will stop at the first empty cell)
                    range = range.get_End(XlDirection.xlToRight);
                    // get the end of values toward the bottom, looking in the last column (will stop at first empty cell)
                    range = range.get_End(XlDirection.xlDown);
                    // get the address of the bottom, right cell
                    string downAddress = range.get_Address(false, false, XlReferenceStyle.xlA1, Type.Missing, Type.Missing);
                    // Get the range, then values from a1
                    range = sheet.get_Range("A1", downAddress);
                    object[,] values = (object[,])range.Value2;
                    //To fetech the header values
                    for (int headCount = 1; headCount <= values.GetLength(1); headCount++)
                    {
                        try
                        {
                            header.Add((string)values.GetValue(1, headCount));
                            arrayFlag = true;
                        }
                        catch (Exception ApplicationException)
                        {
                            Console.WriteLine(ApplicationException.Message);
                            arrayFlag = false;
                            break;
                        }
                    }
                    //To fetch test data
                    if (arrayFlag == true)
                    {
                        for (int i = 1; i <= values.GetLength(0); i++)
                        {
                            for (int j = 1; j <= values.GetLength(1); j++)
                            {
                                string actualTestCaseID = (string)values.GetValue(i, 1);
                                //  Console.WriteLine("Actual Test case is " + actualTestCaseID);
                                if (actualTestCaseID.Equals(testcaseID))
                                {
                                    Console.WriteLine("Inside if");
                                    iVal = i;
                                    arrayFlag = true;
                                    break;
                                }
                            }
                        }
                    }
                    if (arrayFlag == true)
                    {
                        //Add Excel Values
                        for (int j = 1; j <= values.GetLength(1); j++)
                        {
                           excelValues.Add((string)values.GetValue(iVal, j));
                        }
                        //Create HashmapTable
                        int colCount = sheet.UsedRange.Columns.Count;
                        for (int hashVal = 0; hashVal <= colCount - 1; hashVal++)
                        {
                            if (excelValues[hashVal] != null)
                            {
                                testCaseValues.Add(header[hashVal].ToString(), excelValues[hashVal].ToString());
                            }
                            else
                            {
                                testCaseValues.Add(header[hashVal].ToString(), "");
                            }

                        }
                    }
                    break;
                }
            }
        }
        catch (Exception e)
        {
            throw e;
        }
        finally
        {
            range = null;
            if (book != null)
                book.Close(false, Missing.Value, Missing.Value);
            book = null;
            if (app != null)
                app.Quit();
            app = null;
        }

        return testCaseValues;
    }
公共静态字典GetExcelData(字符串testDatapath、字符串testDataSheet、字符串testcaseID)
{
testCaseValues.Clear();
Microsoft.Office.Interop.Excel.Application app=新的Microsoft.Office.Interop.Excel.Application();
工作簿=空;
范围=空;
bool-arrayFlag=false;
int-iVal=0;
ArrayList excelValues=新的ArrayList();
ArrayList标头=新的ArrayList();
尝试
{
app.Visible=false;
app.screenUpdate=false;
app.DisplayAlerts=false;
book=app.Workbooks.Open(testDatapath);
WriteLine(“从“+testDatapath”获取excel);
foreach(书本中的工作表。工作表)
{
if(sheet.Name.Equals(testDataSheet))
{
Console.WriteLine(“测试数据表为”+测试数据表);
//找到一个可以合作的范围
范围=表。获取范围(“A1”,缺少。值);
//将值的末尾移到右侧(将在第一个空单元格处停止)
range=range.get\u End(XlDirection.xlToRight);
//从底部获取值的末尾,查看最后一列(将在第一个空单元格处停止)
range=range.get\u End(XlDirection.xlDown);
//获取右下方单元格的地址
string downAddress=range.get_Address(false,false,XlReferenceStyle.xlA1,Type.Missing,Type.Missing);
//获取范围,然后从a1获取值
范围=表。获取范围(“A1”,下行地址);
对象[,]值=(对象[,])范围。值2;
//要显示标题值,请执行以下操作:

对于(int headCount=1;headCount安装MS Access运行时不会安装Microsoft Excel。只有安装Microsoft Office才会安装Excel。这意味着购买软件包时,软件包必须获得完全许可。没有免费版本

Microsoft Access运行时旨在允许没有Microsoft Access的用户运行使用该应用程序的完整版本创建的数据库。运行时不会安装完整版本附带的所有DLL

在任何情况下,在服务器端安装MicrosoftOfficeProducts都是一个坏主意,因为它们是最终用户工具。这意味着在某些情况下,它们可能会“暂停”(似乎崩溃),因为它们正在等待用户输入。您应该咨询


使用“互操作”有多种替代方法,但由于不知道要做什么,因此无法提出任何建议。这将是另一个问题的主题…

为什么要安装Microsoft Access以使用Excel?您是否意识到它们是不同的产品?无论如何,如果您只想从Excel文件中读取数据,interop是一个糟糕的解决方案。它是不可靠且效率低下。有许多免费的.NET库可以直接读取和写入Excel(和其他Office)文件,而无需Excel应用程序或其任何DLL。您可以通过在线搜索轻松找到它们