【问题标题】:Different users cannot use my WinForms app at the same time不同的用户不能同时使用我的 WinForms 应用程序
【发布时间】:2015-12-20 17:36:47
【问题描述】:

我有一个 VS WinForms 应用程序,它使用 OleDB 从 Excel 文件中读取(只读取,不写入)信息。我的最终用户通过单击一次安装程序,该程序是通过 Visual Studio 社区中的发布选项创建的。安装工作正常。但是:一次只有一个用户能够使用该程序。 Windows 给了我这个错误:

Files that may help descibe the problem:
  C:\Users\shoo\AppData\Local\Temp\WERA825.tmp.WERInternalMetadata.xml
  C:\Users\shoo\AppData\Local\Temp\WERDFAA.tmp.appcompat.txt
  C:\Users\shoo\AppData\Local\Temp\WERE18F.tmp.mdmp

这些文件都包含相同的信息:

    <?xml version="1.0" encoding="UTF-16"?>
<DATABASE>
<EXE NAME="Streetlife Database Lookup.exe" FILTER="CMI_FILTER_PRIVACY">
    <MATCHING_FILE NAME="lcpi.data.oledb.net4.dll" SIZE="841728" CHECKSUM="0x4AEF1CA6" BIN_FILE_VERSION="1.0.1.2490" BIN_PRODUCT_VERSION="1.0.1.2490" PRODUCT_VERSION="1.0.1.2490" FILE_DESCRIPTION="LCPI ADO.NET Data Provider for OLE DB [NET4]" COMPANY_NAME="LCPI" PRODUCT_NAME="lcpi.data.oledb" FILE_VERSION="1.0.1.2490" ORIGINAL_FILENAME="lcpi.data.oledb.net4.dll" INTERNAL_NAME="lcpi.data.oledb.net4.dll" LEGAL_COPYRIGHT="Copyright © LCPI 2011-2015" VERDATEHI="0x0" VERDATELO="0x0" VERFILEOS="0x4" VERFILETYPE="0x2" MODULE_TYPE="WIN32" PE_CHECKSUM="0xD742F" LINKER_VERSION="0x0" UPTO_BIN_FILE_VERSION="1.0.1.2490" UPTO_BIN_PRODUCT_VERSION="1.0.1.2490" LINK_DATE="08/06/2015 14:05:40" UPTO_LINK_DATE="08/06/2015 14:05:40" VER_LANGUAGE="Taalonafhankelijk [0x0]" EXE_WRAPPER="0x0" />
    <MATCHING_FILE NAME="lcpi.lib.net4.dll" SIZE="347136" CHECKSUM="0x3345E399" BIN_FILE_VERSION="1.0.0.1224" BIN_PRODUCT_VERSION="1.0.0.1224" PRODUCT_VERSION="1.0.0.1224" FILE_DESCRIPTION="LCPI Instrumental Library for .NET 4" COMPANY_NAME="LCPI" PRODUCT_NAME="lcpi.lib" FILE_VERSION="1.0.0.1224" ORIGINAL_FILENAME="lcpi.lib.net4.dll" INTERNAL_NAME="lcpi.lib.net4.dll" LEGAL_COPYRIGHT="Copyright © LCPI 2011-2015" VERDATEHI="0x0" VERDATELO="0x0" VERFILEOS="0x4" VERFILETYPE="0x2" MODULE_TYPE="WIN32" PE_CHECKSUM="0x5AFBE" LINKER_VERSION="0x0" UPTO_BIN_FILE_VERSION="1.0.0.1224" UPTO_BIN_PRODUCT_VERSION="1.0.0.1224" LINK_DATE="08/06/2015 14:05:39" UPTO_LINK_DATE="08/06/2015 14:05:39" VER_LANGUAGE="Taalonafhankelijk [0x0]" EXE_WRAPPER="0x0" />
    <MATCHING_FILE NAME="Microsoft.VisualStudio.OLE.Interop.dll" SIZE="118784" CHECKSUM="0xE2A9E029" BIN_FILE_VERSION="7.10.6070.0" BIN_PRODUCT_VERSION="7.10.6070.0" PRODUCT_VERSION="7.10.6070" FILE_DESCRIPTION="" COMPANY_NAME="Microsoft Corporation" PRODUCT_NAME="Microsoft® Visual Studio .NET" FILE_VERSION="7.10.6070" ORIGINAL_FILENAME="" INTERNAL_NAME="" LEGAL_COPYRIGHT="Copyright© Microsoft Corporation.  All rights reserved." VERDATEHI="0x0" VERDATELO="0x0" VERFILEOS="0x4" VERFILETYPE="0x2" MODULE_TYPE="WIN32" PE_CHECKSUM="0x2C347" LINKER_VERSION="0x0" UPTO_BIN_FILE_VERSION="7.10.6070.0" UPTO_BIN_PRODUCT_VERSION="7.10.6070.0" LINK_DATE="08/24/2009 12:53:35" UPTO_LINK_DATE="08/24/2009 12:53:35" VER_LANGUAGE="Engels (Verenigde Staten) [0x409]" EXE_WRAPPER="0x0" />
    <MATCHING_FILE NAME="Streetlife Database Lookup.exe" SIZE="125376" CHECKSUM="0x5042252" BIN_FILE_VERSION="1.0.0.0" BIN_PRODUCT_VERSION="1.0.0.0" PRODUCT_VERSION="1.0.0.0" FILE_DESCRIPTION="WindowsFormsApplication1" COMPANY_NAME="Streetlife" PRODUCT_NAME="Streetlife Databse Lookup" FILE_VERSION="1.0.0.0" ORIGINAL_FILENAME="Streetlife Database Lookup.exe" INTERNAL_NAME="Streetlife Database Lookup.exe" LEGAL_COPYRIGHT="Copyright © SHOO;-)" VERDATEHI="0x0" VERDATELO="0x0" VERFILEOS="0x4" VERFILETYPE="0x1" MODULE_TYPE="WIN32" PE_CHECKSUM="0x2CFAE" LINKER_VERSION="0x0" UPTO_BIN_FILE_VERSION="1.0.0.0" UPTO_BIN_PRODUCT_VERSION="1.0.0.0" LINK_DATE="08/27/2015 10:24:53" UPTO_LINK_DATE="08/27/2015 10:24:53" VER_LANGUAGE="Taalonafhankelijk [0x0]" EXE_WRAPPER="0x0" FILE_ID="00005974d6b5b0b5a80644936a6ef12feedfa35a97e3" PROGRAM_ID="0000da39a3ee5e6b4b0d3255bfef95601890afd80709" />
</EXE>
<EXE NAME="KERNELBASE.dll" FILTER="CMI_FILTER_THISFILEONLY">
    <MATCHING_FILE NAME="KernelBase.dll" SIZE="424448" CHECKSUM="0xBE7BDE30" BIN_FILE_VERSION="6.1.7601.18939" BIN_PRODUCT_VERSION="6.1.7601.18939" PRODUCT_VERSION="6.1.7601.18015" FILE_DESCRIPTION="DLL-bestand voor Windows NT BASE API-client" COMPANY_NAME="Microsoft Corporation" PRODUCT_NAME="Besturingssysteem Microsoft® Windows®" FILE_VERSION="6.1.7601.18015 (win7sp1_gdr.121129-1432)" ORIGINAL_FILENAME="Kernelbase" INTERNAL_NAME="Kernelbase" LEGAL_COPYRIGHT="© Microsoft Corporation. Alle rechten voorbehouden." VERDATEHI="0x0" VERDATELO="0x0" VERFILEOS="0x40004" VERFILETYPE="0x2" MODULE_TYPE="WIN32" PE_CHECKSUM="0x70CFC" LINKER_VERSION="0x60001" UPTO_BIN_FILE_VERSION="6.1.7601.18939" UPTO_BIN_PRODUCT_VERSION="6.1.7601.18939" LINK_DATE="07/22/2015 23:59:55" UPTO_LINK_DATE="07/22/2015 23:59:55" EXPORT_NAME="KERNELBASE.dll" VER_LANGUAGE="Nederlands (Nederland) [0x413]" EXE_WRAPPER="0x0" />
</EXE>
<EXE NAME="kernel32.dll" FILTER="CMI_FILTER_THISFILEONLY">
    <MATCHING_FILE NAME="kernel32.dll" SIZE="1163264" CHECKSUM="0x1FD0A6B3" BIN_FILE_VERSION="6.1.7601.18939" BIN_PRODUCT_VERSION="6.1.7601.18939" PRODUCT_VERSION="6.1.7601.18015" FILE_DESCRIPTION="DLL-bestand voor Windows NT BASE API-client" COMPANY_NAME="Microsoft Corporation" PRODUCT_NAME="Besturingssysteem Microsoft® Windows®" FILE_VERSION="6.1.7601.18015 (win7sp1_gdr.121129-1432)" ORIGINAL_FILENAME="kernel32" INTERNAL_NAME="kernel32" LEGAL_COPYRIGHT="© Microsoft Corporation. Alle rechten voorbehouden." VERDATEHI="0x0" VERDATELO="0x0" VERFILEOS="0x40004" VERFILETYPE="0x2" MODULE_TYPE="WIN32" PE_CHECKSUM="0x12A426" LINKER_VERSION="0x60001" UPTO_BIN_FILE_VERSION="6.1.7601.18939" UPTO_BIN_PRODUCT_VERSION="6.1.7601.18939" LINK_DATE="07/22/2015 23:59:54" UPTO_LINK_DATE="07/22/2015 23:59:54" EXPORT_NAME="KERNEL32.dll" VER_LANGUAGE="Nederlands (Nederland) [0x413]" EXE_WRAPPER="0x0" />
</EXE>
</DATABASE>

我已执行以下操作来帮助避免错误:

  • 我只读取 Excel 文件并将实际的 Excel 文件设为只读。
  • 我在填充数据集或使用阅读器后直接关闭所有连接。
  • 一个没有 OleDB 并通过发布分发的 WinForms 应用>单击一次即可同时为多个用户工作。
  • 如果我开始一个新项目,复制/粘贴我所有的代码(所以它完全一样,但应用程序名称不同):我的程序的两个实例可以同时运行...李>

这是我的第一次 C# 体验,所以请温柔 ;-)

【问题讨论】:

  • 很难从文件中判断错误可能是什么。如果您尝试在需要时复制正在阅读的 excel 文件,怎么样。因此,不是每个用户都访问同一个文件,而是制作一个临时副本,这样每个用户在技术上都在阅读他们“自己的”文件。如果您在这条路线上需要帮助,请告诉我
  • @TheDanMan:这可能是个好主意!我找到了以下代码来创建它。这是正确的吗? 'code'string fileName = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".xlsx";'code' 然后我是否在 OleDB 的连接字符串中使用我的字符串 fileName?跨度>
  • 是的,这样的东西可以工作。那么用户读取该文件
  • 但是我应该把我想要从(副本)创建临时文件的现有文件的文件路径放在哪里?
  • 这取决于您的软件是如何部署的。如果一个文件在多个 mashine 之间共享,我建议您将“主要”放在网络驱动器上。然后,当您的应用程序需要该文件时,它可以将其从网络驱动器复制到应用程序文件夹 Application.StartupPath() ,然后使用该文件保持主文件不变。同样,如果在用户处理文件时出现问题或文件崩溃,那么您知道它只是一个临时文件而不是主文件。请参阅下面的答案

标签: c# excel winforms oledb multiple-users


【解决方案1】:

我认为问题在于,当您打开一个 excel 文件时,它会创建一个“锁”。通常,如果您通过 MS Excel 界面执行此操作,它会提示您一个警告,您可以选择要做什么See here。但在这种情况下,由于您是从 C# 程序中读取它,它可能会返回那个奇怪的错误

我建议您尝试将主文件存储在网络驱动器上,并将其复制到本地的应用程序文件夹中,以便每个用户使用自己的文件,而不是一次读取同一个文件。 See here for file copying

试试下面的代码

string filename = "Streetlife Product Database.xlsx";
string fullfilename = String.Format(@"//MILKYWAY/SO_Arc/template/{1}", Application.StartupPath, filename);
string tempath = System.IO.Path.GetTempPath();
string filenameTemp = String.Format("{0}.xlsx", System.IO.Path.GetTempFileName());
System.IO.File.Copy(fullfilename, filenameTemp, true);
string connetionString = String.Format(@"Provider = Microsoft.ACE.OLEDB.12.0; Data Source ={0};Extended Properties = ""Excel 12.0 Xml;HDR=YES;IMEX=1""", filenameTemp);

using (OleDbConnection oledb = new OleDbConnection(connetionString))
{
    try
    {
        oledb.Open();
    }
    catch (Exception ex)
    {
        oledb.Close();
        oledb.Dispose();

        MessageBox.Show("Error trying to read file: " + ex.Message);                    
    }
 }

【讨论】:

  • 感谢@TheDanMan 的所有帮助!我现在将我的 Excel 数据库重新创建为 SQL 服务器表,并在我的 winform 中使用它。这很好用,我可以让我的表单的多个实例运行并读取我想要的数据库......
【解决方案2】:

您似乎只能与某个文件建立一个 OleDB 连接。因此,当一个用户连接到文件时,另一个用户不能。

遗憾的是,默认情况下,OleDB 驱动程序会以独占方式打开文件,当它被其他人使用时,您无法打开它,即使只是为了阅读。

取自Read Excel file with OleDB c#, when it is used by other process

所以现在我将(母)excel 文件复制到用户计算机上的临时位置,并连接到那里的临时(子)文件。这似乎可行,但我还不能退出获取正确的代码。

到目前为止我有这个:

 string filename = @"//MILKYWAY/SO_Arc/template/Streetlife Product Database.xlsx";
            string filenameTemp = System.IO.Path.GetTempFileName();
            System.IO.File.Copy(filename, filenameTemp, true);
            string connetionString = @"Provider = Microsoft.ACE.OLEDB.12.0; Data Source =" + filenameTemp + ";Extended Properties = 'Excel 12.0 Xml;HDR=YES;IMEX=1'";

【讨论】:

  • 您应该将此添加为评论而不是“答案”以避免混淆。我已经编辑了您的代码 sn-p 并让它在多个用户和多台 PC 上运行。请看我的回答。如果有效,请将其标记为答案。
猜你喜欢
  • 1970-01-01
  • 2020-03-31
  • 2011-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-14
  • 1970-01-01
相关资源
最近更新 更多