You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB6调用.NET COM组件连接Sage 50 Canada时无法打开公司文件

COM可见.NET程序集在VB6调用时无法打开Sage 50公司文件

我们开发了供遗留VB6应用调用的COM可见.NET程序集,调用SDKInstanceManager.Instance.OpenDatabase时持续收到“Unable to open company file”错误,但该方法在其他.NET程序集中调用完全正常。

.NET COM可见程序集代码

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComSourceInterfaces(typeof(IMyClass_ThreadedEvents))]
[Guid("A8F518D8-6446-11E2-BC88-724F6188709B")]
public class MyClass : IDisposable
{    
    public string OpenConnection()
    {
        string retVal = string.Empty;

        try
        {
            retVal = "OpenConnection|@@|*NOERROR*|@@|*ALLOK*|@@||@@|";

            string conInstallFolder = @"C:\Users\Public\Documents\Simply Accounting\2017\Samdata\Pro";
            string conCompany = "Universl";
            string conUserName = "sysadmin";
            string conPassword = "12345";
            string conVersName = "Sage 50 Accounts";
            string conVersNumber = "2017";
            string conVersCountry = "Canada";

            bool allok = SDKInstanceManager.Instance.OpenDatabase(conInstallFolder + @"\" + conCompany + ".SAI", conUserName, conPassword, true,
                conVersName + " " + conVersNumber + " " + conVersCountry, "SASDK", 1);
        }
        catch (Exception ex)
        {
            retVal = "OpenConnection|@@|*ERROR*|@@|" + ex.Message;
        }
        return retVal;
    }
}

VB6调用代码

Private Function RunTestTasks()
    Dim MyClass As New MyDLL.MyClass
    Dim retval As String
  
    retval = MyClass.OpenConnection()
  
    Call MyClass.CloseConnection
      
    Set MyClass = Nothing
End Function 

已知环境信息

  • .NET程序集仅引用Sage_SA.SDK、Sage_SA.Domain和Sage_SA.Domain.Utility
  • 程序集目标架构设置为x86
  • 确认无其他Sage或第三方应用占用目标公司文件
  • VB6程序以Windows管理员权限运行

可能的排查方向及解决方法

  1. COM线程模型冲突
    VB6默认使用单线程单元(STA),未显式指定线程模型的.NET程序集可能导致Sage SDK调用上下文异常。可在类上添加[STAThread]标记,或通过注册函数设置线程模型:

    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    [ComSourceInterfaces(typeof(IMyClass_ThreadedEvents))]
    [Guid("A8F518D8-6446-11E2-BC88-724F6188709B")]
    [STAThread] // 添加STA线程标记
    public class MyClass : IDisposable
    {
        // 现有代码...
    }
    

    或者添加注册函数设置线程模型:

    [ComRegisterFunction]
    public static void RegisterClass(Type t)
    {
        RegistryKey key = Registry.ClassesRoot.OpenSubKey(@"CLSID\" + t.GUID.ToString("B"), true);
        RegistryKey inprocServer32 = key.OpenSubKey("InprocServer32", true);
        inprocServer32.SetValue("ThreadingModel", "STA");
        inprocServer32.Close();
        key.Close();
    }
    
  2. 文件路径解析与权限问题
    VB6运行时的当前工作目录可能与.NET程序集不同,导致路径解析错误。建议:

    • 使用Path.Combine拼接路径,避免手动拼接的语法错误:
      string companyFilePath = Path.Combine(conInstallFolder, $"{conCompany}.SAI");
      bool allok = SDKInstanceManager.Instance.OpenDatabase(companyFilePath, ...);
      
    • 在OpenConnection中输出当前工作目录,确认路径上下文:
      string currentDir = Environment.CurrentDirectory;
      retVal += $"|@@|CurrentDir: {currentDir}";
      
  3. 异常信息深度捕获
    当前仅捕获顶层异常,建议输出内部异常以获取更详细的错误原因:

    catch (Exception ex)
    {
        string fullError = ex.Message;
        if (ex.InnerException != null)
        {
            fullError += $" | InnerException: {ex.InnerException.Message}";
        }
        retVal = $"OpenConnection|@@|*ERROR*|@@|{fullError}";
    }
    
  4. Sage SDK初始化验证
    确认Sage SDK在COM环境下已正确初始化,可在类构造函数中添加SDK初始化逻辑(若有对应方法):

    public MyClass()
    {
        // 调用SDK初始化方法(如果存在)
        // SDKInstanceManager.Instance.Initialize();
    }
    

内容的提问来源于stack exchange,提问作者MikeG001

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 17:43:09