Skip to content

Commit d3a1111

Browse files
authored
Merge pull request #4517 from comintern/next
Sort out dlls for different versions.
2 parents c5c9083 + cd62988 commit d3a1111

File tree

4 files changed

+129
-26
lines changed

4 files changed

+129
-26
lines changed

Rubberduck.VBEEditor/VBERuntime/Settings/VBESettings.cs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
24
using Microsoft.Win32;
35
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
46
using Rubberduck.VBEditor.Utility;
@@ -7,26 +9,27 @@ namespace Rubberduck.VBEditor.VbeRuntime.Settings
79
{
810
public class VbeSettings : IVbeSettings
911
{
10-
private const string Vbe7SettingPath = @"HKEY_CURRENT_USER\Software\Microsoft\VBA\7.0\Common";
11-
private const string Vbe6SettingPath = @"HKEY_CURRENT_USER\Software\Microsoft\VBA\6.0\Common";
12+
private static readonly List<string> VbeVersions = new List<string> { "6.0", "7.0", "7.1" };
13+
private const string VbeSettingPathTemplate = @"HKEY_CURRENT_USER\Software\Microsoft\VBA\{0}\Common";
14+
private const string Vb6SettingPath = @"HKEY_CURRENT_USER\Software\Microsoft\VBA\Microsoft Visual Basic";
1215

1316
private readonly IRegistryWrapper _registry;
1417
private readonly string _activeRegistryRootPath;
15-
private readonly string[] _registryRootPaths = { Vbe7SettingPath, Vbe6SettingPath };
18+
1619

1720
public VbeSettings(IVBE vbe, IRegistryWrapper registry)
1821
{
1922
try
2023
{
21-
switch (VbeDllVersion.GetCurrentVersion(vbe))
24+
Version = VbeDllVersion.GetCurrentVersion(vbe);
25+
switch (Version)
2226
{
27+
case DllVersion.Vbe7:
2328
case DllVersion.Vbe6:
24-
Version = DllVersion.Vbe6;
25-
_activeRegistryRootPath = Vbe6SettingPath;
29+
_activeRegistryRootPath = string.Format(VbeSettingPathTemplate, vbe.Version.Substring(0, 3));
2630
break;
27-
case DllVersion.Vbe7:
28-
Version = DllVersion.Vbe7;
29-
_activeRegistryRootPath = Vbe7SettingPath;
31+
case DllVersion.Vb98:
32+
_activeRegistryRootPath = Vb6SettingPath;
3033
break;
3134
default:
3235
Version = DllVersion.Unknown;
@@ -62,7 +65,10 @@ private bool ReadActiveRegistryPath(string keyName)
6265

6366
private void WriteAllRegistryPaths(string keyName, bool value)
6467
{
65-
foreach (var path in _registryRootPaths)
68+
var paths = VbeVersions.Select(version => string.Format(VbeSettingPathTemplate, version))
69+
.Union(new[] {Vb6SettingPath});
70+
71+
foreach (var path in paths)
6672
{
6773
if (DWordToBooleanConverter(path, keyName) != null)
6874
{

Rubberduck.VBEEditor/VBERuntime/VBEDllVersion.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
1+
using Rubberduck.VBEditor.SafeComWrappers;
2+
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
23

34
namespace Rubberduck.VBEditor.VbeRuntime
45
{
56
public enum DllVersion
67
{
78
Unknown,
9+
Vb98,
810
Vbe6,
911
Vbe7
1012
}
@@ -18,7 +20,7 @@ public static DllVersion GetCurrentVersion(IVBE vbe)
1820
switch (int.Parse(vbe.Version.Split('.')[0]))
1921
{
2022
case 6:
21-
return DllVersion.Vbe6;
23+
return vbe.Kind == VBEKind.Standalone ? DllVersion.Vb98 : DllVersion.Vbe6;
2224
case 7:
2325
return DllVersion.Vbe7;
2426
default:
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
using System;
2+
using System.Runtime.InteropServices;
3+
using Rubberduck.VBEditor.VbeRuntime;
4+
5+
namespace Rubberduck.VBEditor.VBERuntime
6+
{
7+
internal class Vb6NativeApi : IVbeNativeApi
8+
{
9+
// This is the correct dll - why MS named this vba6 instead of vb6 is beyond me.
10+
// vbe6.dll already taken? Oh, I know, lets confuse the f*ck out of everyone and use vba6.
11+
private const string _dllName = "vba6.dll";
12+
13+
public string DllName => _dllName;
14+
15+
[DllImport(_dllName)]
16+
private static extern int rtcDoEvents();
17+
public int DoEvents()
18+
{
19+
return rtcDoEvents();
20+
}
21+
22+
[DllImport(_dllName, SetLastError = true)]
23+
[return: MarshalAs(UnmanagedType.R4)]
24+
private static extern float rtcGetTimer();
25+
public float GetTimer()
26+
{
27+
return rtcGetTimer();
28+
}
29+
30+
[DllImport(_dllName, SetLastError = true)]
31+
private static extern void rtcGetDateVar(out object retVal);
32+
public void GetDateVar(out object retval)
33+
{
34+
rtcGetDateVar(out retval);
35+
}
36+
37+
[DllImport(_dllName, SetLastError = true)]
38+
private static extern void rtcGetPresentDate(out object retVal);
39+
public void GetPresentDate(out object retVal)
40+
{
41+
rtcGetPresentDate(out retVal);
42+
}
43+
44+
[DllImport(_dllName, SetLastError = true)]
45+
private static extern double rtcShell(IntPtr pathname, short windowstyle);
46+
public double Shell(IntPtr pathname, short windowstyle)
47+
{
48+
return rtcShell(pathname, windowstyle);
49+
}
50+
51+
[DllImport(_dllName, SetLastError = true)]
52+
private static extern void rtcGetTimeVar(out object retVal);
53+
public void GetTimeVar(out object retVal)
54+
{
55+
rtcGetTimeVar(out retVal);
56+
}
57+
58+
[DllImport(_dllName, SetLastError = true)]
59+
private static extern void rtcChangeDir(IntPtr path);
60+
public void ChangeDir(IntPtr path)
61+
{
62+
rtcChangeDir(path);
63+
}
64+
65+
[DllImport(_dllName, SetLastError = true)]
66+
private static extern void rtcChangeDrive(IntPtr driveletter);
67+
public void ChangeDrive(IntPtr driveletter)
68+
{
69+
rtcChangeDrive(driveletter);
70+
}
71+
72+
[DllImport(_dllName, SetLastError = true)]
73+
private static extern void rtcKillFiles(IntPtr pathname);
74+
public void KillFiles(IntPtr pathname)
75+
{
76+
rtcKillFiles(pathname);
77+
}
78+
79+
[DllImport(_dllName, SetLastError = true)]
80+
private static extern void rtcMakeDir(IntPtr path);
81+
public void MakeDir(IntPtr path)
82+
{
83+
rtcMakeDir(path);
84+
}
85+
86+
[DllImport(_dllName, SetLastError = true)]
87+
private static extern void rtcRemoveDir(IntPtr path);
88+
public void RemoveDir(IntPtr path)
89+
{
90+
rtcRemoveDir(path);
91+
}
92+
93+
[DllImport(_dllName, SetLastError = true)]
94+
private static extern void rtcBeep();
95+
public void Beep()
96+
{
97+
rtcBeep();
98+
}
99+
}
100+
}

Rubberduck.VBEEditor/VbeRuntime/VbeNativeApiAccessor.cs

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
3+
using Rubberduck.VBEditor.VBERuntime;
34

45
namespace Rubberduck.VBEditor.VbeRuntime
56
{
@@ -37,36 +38,30 @@ private static IVbeNativeApi InitializeRuntime()
3738
return new VbeNativeApi7();
3839
case DllVersion.Vbe6:
3940
return new VbeNativeApi6();
41+
case DllVersion.Vb98:
42+
return new Vb6NativeApi();
4043
default:
4144
return DetermineVersion();
4245
}
4346
}
4447

4548
private static IVbeNativeApi DetermineVersion()
4649
{
47-
IVbeNativeApi runtime;
48-
try
49-
{
50-
runtime = new VbeNativeApi7();
51-
runtime.GetTimer();
52-
_version = DllVersion.Vbe7;
53-
}
54-
catch
50+
foreach (var type in new[] {typeof(VbeNativeApi7), typeof(VbeNativeApi6), typeof(Vb6NativeApi)})
5551
{
5652
try
5753
{
58-
runtime = new VbeNativeApi6();
54+
var runtime = (IVbeNativeApi)Activator.CreateInstance(type);
5955
runtime.GetTimer();
60-
_version = DllVersion.Vbe6;
56+
return runtime;
6157
}
6258
catch
6359
{
64-
// we shouldn't be here.... Rubberduck is a VBA add-in, so how the heck could it have loaded without a VBE dll?!?
65-
throw new InvalidOperationException("Cannot execute DoEvents; the VBE dll could not be located.");
60+
// ignored
6661
}
6762
}
68-
69-
return _version != DllVersion.Unknown ? runtime : null;
63+
// we shouldn't be here.... Rubberduck is a VBE add-in, so how the heck could it have loaded without a runtime dll?!?
64+
throw new InvalidOperationException("Cannot execute library function; the VBE dll could not be located.");
7065
}
7166

7267
public string DllName => _runtime.DllName;

0 commit comments

Comments
 (0)