Wine: установка InputLanguage.DefaultInputLanguage для исправления .NET CultureNotFoundException? - PullRequest
0 голосов
/ 11 декабря 2018

Я пытаюсь запустить DesignSpark Mechanical 2.0 в Wine на Ubuntu 18.04, для которого есть рекомендации по запуску на виртуальной машине:

... но есть и другие подсказки, что связанное программное обеспечение может работать в Wine:

Итак, я попробовал DSMv2_32_20150802.1 (последняя доступная 32-разрядная версия), и оказалось, что это приложение .NET.После некоторого возни с фреймворками .NET я заставил его работать под Wine 3.21-staging (под PlayOnLinux), примерно до такой же точки:

Форумы WineHQ • Просмотр темы - WINE и EXE-файл DOTNet (SpaceClaim).exe) https://forum.winehq.org/viewtopic.php?f=2&t=27919&view=previous

... на котором отображается экран регистрации, который успешно завершается, - а затем при запуске происходит сбой приложения.По крайней мере, wine ./SpaceClaimViewer.exe работает и показывает 3D-модели, поэтому я почти уверен, что основное приложение можно заставить работать тоже.

С winedbg я дошел до:

> WINEDEBUG=+relay wine ./SpaceClaim.exe
winedbg ./SpaceClaim.exe  ## it breaks, but late:

0009:Call KERNEL32.OutputDebugStringW(0404c9e8 L"Unhandled exception. (System.Globalization.CultureNotFoundException) Culture is not supported.\r\nParameter name: culture\r\n0 (0x0000) is an invalid culture identifier.\r\nException Traceback:    at System.Globalization.CultureInfo.InitializeFromCultureId(Int32 culture, Boolean useUserOverride)\r\n "...) ret=05b5de91

0009:fixme:ver:GetCurrentPackageId (0x320944 (nil)): stub
0009:warn:debugstr:OutputDebugStringA "Unhandled exception. (System.Globalization.CultureNotFoundException) Culture is not supported.\r\nParameter name: culture\r\n0 (0x0000) is an invalid culture identifier.\r\nException Traceback:    at System.Globalization.CultureInfo.InitializeFromCultureId(Int32 culture, Boolean useUserOverride)\r\n ".

Итак, я попытался использовать mdbg, чтобы получить более полезную трассировку стека;он должен быть вызван с (SpaceClaim.exe является exe для DSM):

wineconsole --backend=user /path/to/drive_c/MDbgSample/bin/Release/mdbg.exe ./SpaceClaim.exe

С его помощью я могу получить более полезную трассировку стека при сбое:

[p#:0, t#:0] mdbg> where
Thread [#:0]
*0. SpaceClaim.Error.DumpException (source line information unavailable)
 1. SpaceClaim.Program.DomainUnhandledExceptionHandler (source line information unavailable)
 2. System.Globalization.CultureInfo.InitializeFromCultureId (source line inform ation unavailable)
 3. System.Globalization.CultureInfo..ctor (source line information unavailable)
 4. System.Globalization.CultureInfo..ctor (source line information unavailable)
 5. System.Windows.Forms.InputLanguage.get_Culture (source line information unav ailable)
 6. SpaceClaim.DetailSettingsHelper.DefaultFontFromDefaultGtolFont (source line information unavailable)
 7. SpaceClaim.DetailSettingsHelper.DefaultFontFromDefaultGtolFont (source line information unavailable)
 8. SpaceClaim.UserInterface.AnnotationsEditTool.FontSizeCommandComponentAdded ( source line information unavailable)
 9. SpaceClaim.MainForm.fontSizeCommand_ComponentAdded (source line information unavailable)
 10. SpaceClaim.UICommands.UICommand.OnComponentAdded (source line information u navailable)
 11. SpaceClaim.UICommands.UICommand.SetComponent (source line information unava ilable)
 12. SpaceClaim.UICommands.UICommandManager.SetUICommand (source line informatio n unavailable)
 13. SpaceClaim.MainForm.InitializeComponent (source line information unavailabl e)
 14. SpaceClaim.MainForm..ctor (source line information unavailable)
 15. SpaceClaim.Application.Initialize (source line information unavailable)
 16. SpaceClaim.Application.get_ApplicationForm (source line information unavail able)
 17. SpaceClaim.Program.RunApplication (source line information unavailable)
 18. SpaceClaim.Program.Main (source line information unavailable)

[p#:0, t#:0] mdbg> up
Current Frame:SpaceClaim.Program.DomainUnhandledExceptionHandler
IP: 29 @ SpaceClaim.Program.DomainUnhandledExceptionHandler - MAPPING_EXACT
[p#:0, t#:0] mdbg> up
Current Frame:System.Globalization.CultureInfo.InitializeFromCultureId
IP: 66 @ System.Globalization.CultureInfo.InitializeFromCultureId - MAPPING_APPR OXIMATE
[p#:0, t#:0] mdbg> up
Current Frame:System.Globalization.CultureInfo..ctor
IP: 47 @ System.Globalization.CultureInfo..ctor - MAPPING_EXACT
[p#:0, t#:0] mdbg> up
Current Frame:System.Globalization.CultureInfo..ctor
IP: 8 @ System.Globalization.CultureInfo..ctor - MAPPING_EXACT
[p#:0, t#:0] mdbg> up
Current Frame:System.Windows.Forms.InputLanguage.get_Culture
IP: 22 @ System.Windows.Forms.InputLanguage.get_Culture - MAPPING_EXACT
[p#:0, t#:0] mdbg> up
Current Frame:SpaceClaim.DetailSettingsHelper.DefaultFontFromDefaultGtolFont
IP: 97 @ SpaceClaim.DetailSettingsHelper.DefaultFontFromDefaultGtolFont - MAPPIN G_APPROXIMATE  # in DwgInsertUtil.dll [NativeCppClass]
[p#:0, t#:0] mdbg> print
local_0=True
gtolFont="SpaceClaim ASME CB"
overrideReplacementFont=""

Используя ILSpy, я попытался декомпилировать SpaceClaim.exe, и, похоже, мне удалось найти .NET-эквивалент отказавшего класса (даже если там указано DwgInsertUtil.dll [NativeCppClass]) - он находится в декомпилированном файле DetailSettingsHelper.cs:

public static string DefaultFontFromDefaultGtolFont(string gtolFont)
{
        return DefaultFontFromDefaultGtolFont(gtolFont, string.Empty);
}

public static string DefaultFontFromDefaultGtolFont(string gtolFont, string overrideReplacementFont)
{
        bool flag = Interlocked.CompareExchange(ref firstCall, 1, 0) != 0;
        if (!string.IsNullOrEmpty(overrideReplacementFont))
        {
                return overrideReplacementFont;
        }
        if (InputLanguage.CurrentInputLanguage.Culture.ThreeLetterISOLanguageName == "jpn" && (gtolFont.Equals(FontCache.AsmeFontName) || gtolFont.Equals(FontCache.IsoFontName)))
        {
                return japaneseFont;
        }
        if (InputLanguage.DefaultInputLanguage.Culture.TwoLetterISOLanguageName == "zh" && (gtolFont.Equals(FontCache.AsmeFontName) || gtolFont.Equals(FontCache.IsoFontName)))
        {
                return chineseFont;
        }
        return gtolFont;
}

И так как InputLanguage.get_Culture приводит к трассировке стека, я считаю, что один из этих вызовов здесь сбой.Итак, в отладчике я попробовал это:

[p#:1, t#:0] mdbg> Set $empty = ""
$empty=""
[p#:1, t#:0] mdbg> funceval SpaceClaim.DetailSettingsHelper.DefaultFontFromDefaultGtolFont $empty
Func-eval not fully completed and debuggee has stopped
Result of funceval won't be printed when finished.
STOP: Breakpoint 1 Hit
IP: 0 @ SpaceClaim.DetailSettingsHelper.DefaultFontFromDefaultGtolFont - MAPPING_EXACT

## NB: don't have to call funceval with $empty if calling with just that argument

[p#:2, t#:0] mdbg> funceval System.Windows.Forms.InputLanguage.get_CurrentInputLanguage
result = System.Windows.Forms.InputLanguage
        handle=67699721
results saved to $result

[p#:3, t#:0] mdbg> funceval System.Windows.Forms.InputLanguage.get_Culture $result
result = System.Globalization.CultureInfo
        m_isReadOnly=False
....
        cultureID=127
        m_consoleFallbackCulture=<null>
        m_name="en-US"
....

[p#:3, t#:0] mdbg> funceval System.Windows.Forms.InputLanguage.get_DefaultInputLanguage
result = System.Windows.Forms.InputLanguage
        handle=0
results saved to $result
STOP EvalComplete
IP: 0 @ SpaceClaim.DetailSettingsHelper.DefaultFontFromDefaultGtolFont - MAPPING_EXACT
[p#:3, t#:0] mdbg> funceval System.Windows.Forms.InputLanguage.get_Culture $result
result = System.Globalization.CultureNotFoundException
        m_invalidCultureName=<null>
        m_invalidCultureId=System.Nullable`1<System.Int32>
...
        _exceptionMethod=<null>
        _exceptionMethodString=<null>
        _message="Culture is not supported."
...

Из этого я понял, что InputLanguage.CurrentInputLanguage.get_Culture успешно завершается и возвращает en-US locale;в то время как InputLanguage.DefaultInputLanguage.get_Culture возвращает "нулевую" культуру и исключение.

Итак, я думаю, мне придется каким-то образом настроить Wine, поэтому .NET находит DefaultInputLanguage как en-US вместо этого "нулевого""культура / язык.За исключением того, что я пробовал все это:

В любом случае, вызов API GetThreadLocale получает свое возвращаемое значение из записи реестра "Locale"упоминалось выше, в то время как другие (GetUserDefaultLCID, GetSystemDefaultLCID и т. д.) используют запись реестра «LocaleName».

Добавлено "LocaleName" с "en-US" через wine regedit, не помогло;

... заставил меня попробовать:

LANGUAGE=en-US wine ./DSLib/SpaceClaim.exe
LANG=en wine ./DSLib/SpaceClaim.exe

... тоже не сработало.

Итак - кто-нибудь узнает, если можноНастройте Wine под Linux, поэтому языковой стандарт «язык ввода по умолчанию» установлен на доступный «en-US», поэтому вызов .NET на InputLanguage.DefaultInputLanguage.get_Culture может быть успешным, вместо того, чтобы возвращать «нулевую» культуру и исключение?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...