Skip to content

Commit 39b6dc6

Browse files
committed
Fix FieldWorks startup crashes and RegFree COM registration
Summary: Resolved the "Class not registered" (0x80040154) startup crash by correcting the Registration-Free COM configuration and fixing initialization order. Details: - Build: Added `<NoWin32Manifest>true` to FieldWorks.csproj. This prevents the .NET SDK from embedding a default manifest in Debug builds, allowing the external `FieldWorks.exe.manifest` (which contains the required COM entries) to be used by the Windows Loader. - COM: Explicitly registered managed COM assemblies (LexTextDll, xWorks, FwUtils, etc.) in `BuildInclude.targets` so they are included in the generated application manifest. - COM: Decorated `LexTextApp` with `[ComVisible(true)]` and a stable GUID to ensure it can be instantiated via COM. - Stability: Moved ICU initialization earlier in the startup sequence (`FieldWorks.cs`) to prevent "ICU not initialized" errors. - Dev Env: Improved `FwDirectoryFinder` to reliably locate `DistFiles` relative to the executable in developer builds. - Resources: Restored missing `ErrorReporter.resx` (renamed from ErrorReport.resx) to ensure crash reporting functions correctly. - Config: Added a default layout for `CmObject` in `Cellar.fwlayout` to prevent UI crashes on unknown object types. - Deps: Updated `SharpZipLib` and `System.Net.Fix FieldWorks startup crashes and RegFree COM registration Summary: Resolved the "Class not registered" (0x80040154) startup crash by correcting the Registration-Free COM configuration and fixing initialization order. Details: - Build: Added `<NoWin32Manifest>true` to FieldWorks.csproj. This prevents the .NET SDK from embedding a default manifest in Debug builds, allowing the external `FieldWorks.exe.manifest` (which contains the required COM entries) to be used by the Windows Loader. - COM: Explicitly registered managed COM assemblies (LexTextDll, xWorks, FwUtils, etc.) in `BuildInclude.targets` so they are included in the generated application manifest. - COM: Decorated `LexTextApp` with `[ComVisible(true)]` and a stable GUID to ensure it can be instantiated via COM. - Stability: Moved ICU initialization earlier in the startup sequence (`FieldWorks.cs`) to prevent "ICU not initialized" errors. - Dev Env: Improved `FwDirectoryFinder` to reliably locate `DistFiles` relative to the executable in developer builds. - Resources: Restored missing `ErrorReporter.resx` (renamed from ErrorReport.resx) to ensure crash reporting functions correctly. - Config: Added a default layout for `CmObject` in `Cellar.fwlayout` to prevent UI crashes on unknown object types. - Deps: Updated `SharpZipLib` and `System.Net.
1 parent 30c82d9 commit 39b6dc6

File tree

14 files changed

+111
-50
lines changed

14 files changed

+111
-50
lines changed

DistFiles/Language Explorer/Configuration/Parts/Cellar.fwlayout

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,8 @@
9393
<layout class="StTxtPara" type="jtview" name="publishParagraph">
9494
<part ref="ContentsAsPara" flowType="para"/>
9595
</layout>
96+
97+
<layout class="CmObject" type="jtview" name="default">
98+
<part ref="shortname"/>
99+
</layout>
96100
</LayoutInventory>

Src/Common/FieldWorks/App.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ Comment out the following section when the ParatextData and FieldWorks versions
7979
</dependentAssembly>
8080
<dependentAssembly>
8181
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
82-
<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
82+
<bindingRedirect oldVersion="0.0.0.0-4.3.4.0" newVersion="4.3.4" />
8383
</dependentAssembly>
8484
<dependentAssembly>
8585
<assemblyIdentity name="TagLibSharp" publicKeyToken="db62eba44689b5b0" culture="neutral" />

Src/Common/FieldWorks/BuildInclude.targets

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@
33
<PropertyGroup>
44
<Executable>$(OutDir)FieldWorks.exe</Executable>
55
</PropertyGroup>
6+
<ItemGroup>
7+
<!-- Ensure reg-free manifest includes the core managed COM servers used by FieldWorks.exe -->
8+
<ManagedComAssemblies Include="$(OutDir)FwUtils.dll" />
9+
<ManagedComAssemblies Include="$(OutDir)SimpleRootSite.dll" />
10+
<ManagedComAssemblies Include="$(OutDir)ManagedLgIcuCollator.dll" />
11+
<ManagedComAssemblies Include="$(OutDir)ManagedVwWindow.dll" />
12+
<ManagedComAssemblies Include="$(OutDir)xWorks.dll" />
13+
<ManagedComAssemblies Include="$(OutDir)LexTextDll.dll" />
14+
</ItemGroup>
615
<Import Project="../../../Build/RegFree.targets" />
716
<Target Name="InvokeRegFree" AfterTargets="Build" DependsOnTargets="RegFree"></Target>
817
</Project>

Src/Common/FieldWorks/FieldWorks.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,8 @@ static int Main(string[] rgArgs)
155155
var newPath = $"{pathName}{Path.PathSeparator}{Environment.GetEnvironmentVariable("PATH")}";
156156
Environment.SetEnvironmentVariable("PATH", newPath);
157157
Icu.Wrapper.ConfineIcuVersions(70);
158-
// ICU will be initialized further down (by calling FwUtils.InitializeIcu())
158+
// Initialize ICU before anything touches it so icu.net does not warn about missing Init().
159+
FwUtils.InitializeIcu();
159160
FwRegistryHelper.Initialize();
160161

161162
try
@@ -283,8 +284,6 @@ static int Main(string[] rgArgs)
283284
// by a bug in XP.
284285
Application.EnableVisualStyles();
285286

286-
FwUtils.InitializeIcu();
287-
288287
// initialize the SLDR
289288
Sldr.Initialize();
290289

@@ -3518,11 +3517,11 @@ private static void StaticDispose()
35183517

35193518
KeyboardController.Shutdown();
35203519

3520+
GracefullyShutDown();
3521+
35213522
if (Sldr.IsInitialized)
35223523
Sldr.Cleanup();
35233524

3524-
GracefullyShutDown();
3525-
35263525
if (s_threadHelper != null)
35273526
s_threadHelper.Dispose();
35283527
s_threadHelper = null;

Src/Common/FieldWorks/FieldWorks.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
99
<Deterministic>false</Deterministic>
1010
<ApplicationIcon>Branding\LT.ico</ApplicationIcon>
11+
<NoWin32Manifest>true</NoWin32Manifest>
1112
<EnableRegFreeCom>true</EnableRegFreeCom>
1213
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
1314
<UseDevTraceConfig Condition="'$(UseDevTraceConfig)'=='' and '$(FW_TRACE_LOG)'!=''">true</UseDevTraceConfig>

Src/Common/FwUtils/FwDirectoryFinder.cs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,17 @@ string defaultDir
325325
return dir.Length > 2 ? dir : dir + Path.DirectorySeparatorChar;
326326
}
327327

328+
private static string GetDevDistFilesPath()
329+
{
330+
string assemblyDir = Path.GetDirectoryName(FileUtils.StripFilePrefix(Assembly.GetExecutingAssembly().CodeBase));
331+
// Check if we are in Output/Debug or Output/Release
332+
// DistFiles is at ../../DistFiles
333+
string distFiles = Path.GetFullPath(Path.Combine(assemblyDir, "..", "..", "DistFiles"));
334+
if (Directory.Exists(distFiles))
335+
return distFiles;
336+
return null;
337+
}
338+
328339
/// ------------------------------------------------------------------------------------
329340
/// <summary>
330341
/// Gets the directory where FieldWorks code was installed (usually
@@ -343,6 +354,11 @@ public static string CodeDirectory
343354
CompanyName,
344355
$"FieldWorks {FwUtils.SuiteVersion}"
345356
);
357+
358+
string devDistFiles = GetDevDistFilesPath();
359+
if (devDistFiles != null)
360+
defaultDir = devDistFiles;
361+
346362
return GetDirectory("RootCodeDir", defaultDir);
347363
}
348364
}
@@ -357,11 +373,22 @@ public static string CodeDirectory
357373
/// <exception cref="ApplicationException">If an installation directory could not be
358374
/// found.</exception>
359375
/// ------------------------------------------------------------------------------------
360-
public static string DataDirectory =>
361-
GetDirectory(
362-
ksRootDataDir,
363-
Path.Combine(LcmFileHelper.CommonApplicationData, CompanyName, ksFieldWorks)
364-
);
376+
public static string DataDirectory
377+
{
378+
get
379+
{
380+
string defaultDir = Path.Combine(LcmFileHelper.CommonApplicationData, CompanyName, ksFieldWorks);
381+
382+
string devDistFiles = GetDevDistFilesPath();
383+
if (devDistFiles != null)
384+
defaultDir = devDistFiles;
385+
386+
return GetDirectory(
387+
ksRootDataDir,
388+
defaultDir
389+
);
390+
}
391+
}
365392

366393
/// ------------------------------------------------------------------------------------
367394
/// <summary>

Src/Common/FwUtils/FwUtils.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using System.Runtime.InteropServices;
1212
using System.Collections.Generic;
1313
using System.IO;
14+
using Icu;
1415
using Icu.Collation;
1516
using SIL.LCModel.Core.Text;
1617
using SIL.LCModel.Core.WritingSystems;
@@ -191,6 +192,12 @@ public static void InitializeIcu()
191192
// ICU_DATA should point to the directory that contains nfc_fw.nrm and nfkc_fw.nrm
192193
// (i.e. icudt54l).
193194
CustomIcu.InitIcuDataDir();
195+
196+
var initResult = Wrapper.Init();
197+
if (initResult != ErrorCode.ZERO_ERROR && initResult != ErrorCode.NoErrors)
198+
{
199+
Trace.WriteLine($"ICU initialization returned {initResult}");
200+
}
194201
}
195202

196203
/// <summary>

Src/LexText/LexTextDll/LexTextApp.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Windows.Forms;
99
using System.Diagnostics;
1010
using System.ComponentModel;
11+
using System.Runtime.InteropServices;
1112
using SIL.FieldWorks.Common.Controls;
1213
using SIL.FieldWorks.Common.Framework;
1314
using SIL.FieldWorks.Common.FwUtils;
@@ -31,6 +32,9 @@ namespace SIL.FieldWorks.XWorks.LexText
3132
/// <summary>
3233
/// Summary description for LexTextApp.
3334
/// </summary>
35+
[ComVisible(true)]
36+
[Guid("E03DB914-31F2-4B9C-8E3A-2E0F1091F5B1")]
37+
[ClassInterface(ClassInterfaceType.None)]
3438
public class LexTextApp : FwXApp, IApp, IxCoreColleague
3539
{
3640
protected XMessageBoxExManager m_messageBoxExManager;
File renamed without changes.

Src/Utilities/Reporting/Reporting.csproj

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
99
<GenerateResourceUsePreserializedResources>true</GenerateResourceUsePreserializedResources>
1010
<Prefer32Bit>false</Prefer32Bit>
11+
<EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems>
1112
</PropertyGroup>
1213
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
1314
<DefineConstants>DEBUG;TRACE</DefineConstants>
@@ -35,7 +36,17 @@
3536
<ProjectReference Include="../../Common/FwUtils/FwUtils.csproj" />
3637
</ItemGroup>
3738
<ItemGroup>
39+
<EmbeddedResource Include="ErrorReporter.resx">
40+
<DependentUpon>ErrorReport.cs</DependentUpon>
41+
</EmbeddedResource>
42+
<EmbeddedResource Include="ReportingStrings.resx">
43+
<Generator>ResXFileCodeGenerator</Generator>
44+
<LastGenOutput>ReportingStrings.Designer.cs</LastGenOutput>
45+
</EmbeddedResource>
3846
<EmbeddedResource Include="Usage.ico" />
47+
<EmbeddedResource Include="UsageEmailDialog.resx">
48+
<DependentUpon>UsageEmailDialog.cs</DependentUpon>
49+
</EmbeddedResource>
3950
</ItemGroup>
4051
<ItemGroup>
4152
<Compile Include="..\..\CommonAssemblyInfo.cs">

0 commit comments

Comments
 (0)