Skip to content

Commit d816f2b

Browse files
committed
2 parents 5d728c3 + 12f5b5d commit d816f2b

File tree

118 files changed

+5411
-18072
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

118 files changed

+5411
-18072
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,3 +165,4 @@ $RECYCLE.BIN/
165165

166166
# Workbook for debugging
167167
*.xlsm
168+
Installers/

Installer Build Script.iss

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
#define BuildDir SourcePath + "RetailCoder.VBE\bin\release"
2+
#define AppName "Rubberduck"
3+
#define AddinDLL "Rubberduck.dll"
4+
#define AppVersion GetFileVersion(SourcePath + "RetailCoder.VBE\bin\release\Rubberduck.dll")
5+
#define AppPublisher "Rubberduck"
6+
#define AppURL "http://rubberduck-vba.com"
7+
#define License SourcePath + "\License.rtf"
8+
#define OutputDirectory SourcePath + "\Installers"
9+
#define AddinProgId "Rubberduck.Extension"
10+
#define AddinCLSID "8D052AD8-BBD2-4C59-8DEC-F697CA1F8A66"
11+
12+
[Setup]
13+
; TODO this CLSID should match the one used by the current installer.
14+
AppId={{979AFF96-DD9E-4FC2-802D-9E0C36A60D09}
15+
AppName={#AppName}
16+
AppVersion={#AppVersion}
17+
AppPublisher={#AppPublisher}
18+
AppPublisherURL={#AppURL}
19+
AppSupportURL={#AppURL}
20+
AppUpdatesURL={#AppURL}
21+
; use the local appdata folder instead of the program files dir.
22+
DefaultDirName={commonappdata}\{#AppName}
23+
DefaultGroupName=Rubberduck
24+
AllowNoIcons=yes
25+
LicenseFile={#License}
26+
OutputDir={#OutputDirectory}
27+
OutputBaseFilename=Rubberduck.Setup.{#AppVersion}
28+
Compression=lzma
29+
SolidCompression=yes
30+
31+
ArchitecturesAllowed=x86 x64
32+
ArchitecturesInstallIn64BitMode=x64
33+
34+
[Languages]
35+
; TODO add additional installation languages here.
36+
Name: "English"; MessagesFile: "compiler:Default.isl"
37+
38+
[Files]
39+
; We are taking everything from the Build directory and adding it to the installer. This
40+
; might not be what we want to do.
41+
Source: "{#BuildDir}\*"; DestDir: "{app}"; Flags: ignoreversion; Excludes: "{#AddinDLL}"; Check: Is64BitOfficeInstalled
42+
Source: "{#BuildDir}\NativeBinaries\amd64\*"; DestDir: "{app}"; Flags: ignoreversion; Excludes: "{#AddinDLL}"; Check: Is64BitOfficeInstalled
43+
Source: "{#BuildDir}\{#AddinDLL}"; DestDir: "{app}"; Flags: ignoreversion; Check: Is64BitOfficeInstalled; AfterInstall: RegisterAddin
44+
45+
Source: "{#BuildDir}\*"; DestDir: "{app}"; Flags: ignoreversion; Excludes: "{#AddinDLL}"; Check: Is32BitOfficeInstalled
46+
Source: "{#BuildDir}\NativeBinaries\x86\*"; DestDir: "{app}"; Flags: ignoreversion; Excludes: "{#AddinDLL}"; Check: Is32BitOfficeInstalled
47+
Source: "{#BuildDir}\{#AddinDLL}"; DestDir: "{app}"; Flags: ignoreversion; Check: Is32BitOfficeInstalled; AfterInstall: RegisterAddin
48+
49+
[UninstallDelete]
50+
; Removing all application files (except for configuration).
51+
Name: "{app}\*.dll"; Type: filesandordirs
52+
Name: "{app}\*.xml"; Type: filesandordirs
53+
Name: "{app}\*.pdb"; Type: filesandordirs
54+
55+
[Run]
56+
; http://stackoverflow.com/questions/5618337/how-to-register-a-net-dll-using-inno-setup
57+
Filename: "{dotnet4032}\RegAsm.exe"; Parameters: "/codebase {#AddinDLL}"; WorkingDir: "{app}"; Flags: runascurrentuser runminimized; StatusMsg: "Registering Controls..."; Check: Is32BitOfficeInstalled
58+
Filename: "{dotnet4064}\RegAsm.exe"; Parameters: "/codebase {#AddinDLL}"; WorkingDir: "{app}"; Flags: runascurrentuser runminimized; StatusMsg: "Registering Controls..."; Check: Is64BitOfficeInstalled
59+
60+
[UninstallRun]
61+
Filename: "{dotnet4032}\RegAsm.exe"; Parameters: "/u {#AddinDLL}"; WorkingDir: "{app}"; StatusMsg: "Unregistering Controls..."; Flags: runascurrentuser runminimized; Check: Is32BitOfficeInstalled
62+
Filename: "{dotnet4064}\RegAsm.exe"; Parameters: "/u {#AddinDLL}"; WorkingDir: "{app}"; StatusMsg: "Unregistering Controls..."; Flags: runascurrentuser runminimized; Check: Is64BitOfficeInstalled
63+
64+
[CustomMessages]
65+
; TODO add additional languages here.
66+
English.NETFramework40NotInstalled=Microsoft .NET Framework 4.0 installation was not detected.
67+
68+
[Icons]
69+
Name: "{group}\{cm:ProgramOnTheWeb,{#AppName}}"; Filename: "{#AppURL}"
70+
Name: "{group}\{cm:UninstallProgram,{#AppName}}"; Filename: "{uninstallexe}"
71+
72+
[Code]
73+
// The following code is adapted from: http://stackoverflow.com/a/11651515/2301065
74+
const
75+
SCS_32BIT_BINARY = 0;
76+
SCS_64BIT_BINARY = 6;
77+
// There are other values that GetBinaryType can return, but we're not interested in them.
78+
OfficeNotFound = -1;
79+
80+
var
81+
HasCheckedOfficeBitness: Boolean;
82+
OfficeIs64Bit: Boolean;
83+
84+
function GetBinaryType(lpApplicationName: AnsiString; var lpBinaryType: Integer): Boolean;
85+
external 'GetBinaryTypeA@kernel32.dll stdcall';
86+
87+
function GetOfficeAppBitness(exeName: string): Integer;
88+
var
89+
appPath: String;
90+
binaryType: Integer;
91+
begin
92+
Result := OfficeNotFound; // Default value.
93+
94+
if RegQueryStringValue(HKEY_LOCAL_MACHINE,
95+
'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\' + exeName,
96+
'', appPath) then begin
97+
try
98+
if GetBinaryType(appPath, binaryType) then Result := binaryType;
99+
except
100+
end;
101+
end;
102+
end;
103+
104+
function GetOfficeBitness(): Integer;
105+
var
106+
appBitness: Integer;
107+
officeExeNames: array[0..4] of String;
108+
i: Integer;
109+
begin
110+
officeExeNames[0] := 'excel.exe';
111+
officeExeNames[1] := 'msaccess.exe';
112+
officeExeNames[2] := 'winword.exe';
113+
officeExeNames[3] := 'outlook.exe';
114+
officeExeNames[4] := 'powerpnt.exe';
115+
116+
for i := 0 to 4 do begin
117+
appBitness := GetOfficeAppBitness(officeExeNames[i]);
118+
if appBitness <> OfficeNotFound then begin
119+
Result := appBitness;
120+
exit;
121+
end;
122+
end;
123+
// Note if we get to here then we haven't found any Office versions. Should
124+
// we fail the installation?
125+
end;
126+
127+
function Is64BitOfficeInstalled(): Boolean;
128+
begin
129+
if (not HasCheckedOfficeBitness) then
130+
OfficeIs64Bit := (GetOfficeBitness() = SCS_64BIT_BINARY);
131+
Result := OfficeIs64Bit;
132+
end;
133+
134+
function Is32BitOfficeInstalled(): Boolean;
135+
begin
136+
Result := (not Is64BitOfficeInstalled());
137+
end;
138+
139+
// http://kynosarges.org/DotNetVersion.html
140+
function IsDotNetDetected(version: string; service: cardinal): boolean;
141+
// Indicates whether the specified version and service pack of the .NET Framework is installed.
142+
//
143+
// version -- Specify one of these strings for the required .NET Framework version:
144+
// 'v1.1.4322' .NET Framework 1.1
145+
// 'v2.0.50727' .NET Framework 2.0
146+
// 'v3.0' .NET Framework 3.0
147+
// 'v3.5' .NET Framework 3.5
148+
// 'v4\Client' .NET Framework 4.0 Client Profile
149+
// 'v4\Full' .NET Framework 4.0 Full Installation
150+
// 'v4.5' .NET Framework 4.5
151+
//
152+
// service -- Specify any non-negative integer for the required service pack level:
153+
// 0 No service packs required
154+
// 1, 2, etc. Service pack 1, 2, etc. required
155+
var
156+
key: string;
157+
install, release, serviceCount: cardinal;
158+
check45, success: boolean;
159+
begin
160+
// .NET 4.5 installs as update to .NET 4.0 Full
161+
if version = 'v4.5' then begin
162+
version := 'v4\Full';
163+
check45 := true;
164+
end else
165+
check45 := false;
166+
167+
// installation key group for all .NET versions
168+
key := 'SOFTWARE\Microsoft\NET Framework Setup\NDP\' + version;
169+
170+
// .NET 3.0 uses value InstallSuccess in subkey Setup
171+
if Pos('v3.0', version) = 1 then begin
172+
success := RegQueryDWordValue(HKLM, key + '\Setup', 'InstallSuccess', install);
173+
end else begin
174+
success := RegQueryDWordValue(HKLM, key, 'Install', install);
175+
end;
176+
177+
// .NET 4.0/4.5 uses value Servicing instead of SP
178+
if Pos('v4', version) = 1 then begin
179+
success := success and RegQueryDWordValue(HKLM, key, 'Servicing', serviceCount);
180+
end else begin
181+
success := success and RegQueryDWordValue(HKLM, key, 'SP', serviceCount);
182+
end;
183+
184+
// .NET 4.5 uses additional value Release
185+
if check45 then begin
186+
success := success and RegQueryDWordValue(HKLM, key, 'Release', release);
187+
success := success and (release >= 378389);
188+
end;
189+
190+
result := success and (install = 1) and (serviceCount >= service);
191+
end;
192+
193+
function InitializeSetup(): Boolean;
194+
var
195+
iErrorCode: Integer;
196+
begin
197+
// MS .NET Framework 4.5 must be installed for this application to work.
198+
if not IsDotNetDetected('v4.5', 0) then
199+
begin
200+
MsgBox(ExpandConstant('{cm:NETFramework40NotInstalled}'), mbCriticalError, mb_Ok);
201+
ShellExec('open', 'http://msdn.microsoft.com/en-us/netframework/aa731542', '', '', SW_SHOW, ewNoWait, iErrorCode)
202+
Result := False;
203+
end
204+
else
205+
Result := True;
206+
end;
207+
208+
procedure RegisterAddinForIDE(const iRootKey: Integer; const sAddinSubKey: String; const sProgIDConnect: String);
209+
begin
210+
RegWriteStringValue(iRootKey, sAddinSubKey + '\' + sProgIDConnect, 'FriendlyName', '{#AppName}');
211+
RegWriteStringValue(iRootKey, sAddinSubKey + '\' + sProgIDConnect, 'Description' , '{#AppName}');
212+
RegWriteDWordValue (iRootKey, sAddinSubKey + '\' + sProgIDConnect, 'LoadBehavior', 3);
213+
end;
214+
215+
procedure UnregisterAddinForIDE(const iRootKey: Integer; const sAddinSubKey: String; const sProgIDConnect: String);
216+
begin
217+
if RegKeyExists(iRootKey, sAddinSubKey + '\' + sProgIDConnect) then
218+
RegDeleteKeyIncludingSubkeys(iRootKey, sAddinSubKey + '\' + sProgIDConnect);
219+
end;
220+
221+
procedure RegisterAddin();
222+
begin
223+
if Is32BitOfficeInstalled() then
224+
RegisterAddinForIDE(HKCU32, 'Software\Microsoft\VBA\VBE\6.0\Addins', '{#AddinProgId}');
225+
226+
if Is64BitOfficeInstalled() then
227+
RegisterAddinForIDE(HKCU64, 'Software\Microsoft\VBA\VBE\6.0\Addins64', '{#AddinProgId}');
228+
end;
229+
230+
procedure UnregisterAddin();
231+
begin
232+
UnregisterAddinForIDE(HKCU32, 'Software\Microsoft\VBA\VBE\6.0\Addins', '{#AddinProgId}');
233+
if IsWin64() then
234+
UnregisterAddinForIDE(HKCU64, 'Software\Microsoft\VBA\VBE\6.0\Addins64', '{#AddinProgId}');
235+
end;
236+
237+
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
238+
begin
239+
if CurUninstallStep = usUninstall then UnregisterAddin();
240+
end;

RetailCoder.VBE/Extensions/CodePaneExtensions.cs

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -28,35 +28,7 @@ public static QualifiedSelection GetSelection(this CodePane code)
2828
}
2929

3030
var selection = new Selection(startLine, startColumn, endLine, endColumn);
31-
return new QualifiedSelection(code.CodeModule.Parent.QualifiedName(), selection);
32-
}
33-
34-
/// <summary>
35-
/// Returns a <see cref="Selection"/> representing the position
36-
/// </summary>
37-
///
38-
/// <param name="selection"> The selection. </param>
39-
/// <returns> A QualifiedSelection object representing the procedure the cursor is currently in. </returns>
40-
public static Selection SelectedProcedure(this CodePane code, Selection selection)
41-
{
42-
vbext_ProcKind kind;
43-
var procedure = code.CodeModule.get_ProcOfLine(selection.StartLine, out kind);
44-
var startLine = code.CodeModule.get_ProcStartLine(procedure, kind);
45-
var endLine = startLine + code.CodeModule.get_ProcCountLines(procedure, kind) + 1;
46-
47-
return new Selection(startLine, 1, endLine, 1);
48-
}
49-
50-
/// <summary>
51-
/// Sets the cursor to the first position of the given line.
52-
/// </summary>
53-
/// <param name="codePane"></param>
54-
/// <param name="lineNumber"></param>
55-
public static void SetSelection(this CodePane codePane, int lineNumber)
56-
{
57-
var line = codePane.CodeModule.Lines[lineNumber, 1];
58-
var selection = new Selection(lineNumber, 1, lineNumber, line.Length);
59-
codePane.SetSelection(selection);
31+
return new QualifiedSelection(new QualifiedModuleName(code.CodeModule.Parent), selection);
6032
}
6133

6234
/// <summary>

0 commit comments

Comments
 (0)