Closed joshua-software-dev closed 1 year ago
Upon further testing, this may just be a every .NET 7 program under wine problem. Running a brand new, dotnet new console
hello world, self contained, single file project under wine:
~/.xlcore/compatibilitytool/beta/wine-xiv-staging-fsync-git-7.10.r3.g560db77d/bin/wine64 helloworld.exe
wineserver: using server-side synchronization.
002c:fixme:winediag:LdrInitializeThunk Wine XIV (staging) 7.10 is a testing version containing experimental patches.
002c:fixme:winediag:LdrInitializeThunk Please don't report bugs about it on winehq.org and use https://github.com/goatcorp/wine-xiv-git/issues instead.
0100:fixme:heap:GetNumaHighestNodeNumber semi-stub: 000000000019EFDC
0100:fixme:process:GetProcessGroupAffinity (FFFFFFFFFFFFFFFF,000000000019EF64,0000000000000000): stub
0100:fixme:seh:WerRegisterRuntimeExceptionModule (L"C:\\IINACT\\mscordaccore.dll", 0000000140000000) stub
0100:fixme:ntdll:NtQuerySystemInformation info_class SYSTEM_PERFORMANCE_INFORMATION
Failed to create CoreCLR, HRESULT: 0x80004005
0100:fixme:advapi:RegisterEventSourceW ((null),L".NET Runtime"): stub
0100:fixme:advapi:ReportEventW (00000000CAFE4242,0x0001,0x0000,0x000003ff,0000000000000000,0x0001,0x00000000,000000000019FCA0,0000000000000000): stub
0100:err:eventlog:ReportEventW L"Description: A .NET application failed.\nApplication: helloworld.exe\nPath: C:\\IINACT\\helloworld.exe\nMessage: Failed to create CoreCLR, HRESULT: 0x80004005\n\n"
0100:fixme:advapi:DeregisterEventSource (00000000CAFE4242) stub
Now that dalamud for patch 6.3 is out, it raised the question to me on why IINACT on .NET 7 isn't working, but dalamud on .NET 7 is. The only thing I could think of is the nature of the PublishSingleFile exes vs dalamud's dll loading approach. I tried running both the self-contained and not-self-contained .exe files through ~/.xlcore/runtime/dotnet.exe, but no luck.
However, compiling from source and running the following DOES work, if reverting to .NET 6 seems unappealing.
dotnet publish --self-contained false -p:PublishSingleFile=false -c release -p:EnableWindowsTargeting=true
tar czvf IINACT-dn7-not-self-contained.tar.gz -C IINACT/bin/Release/net7.0-windows/win-x64/publish/ .
mkdir -p ~/.xlcore/wineprefix/drive_c/IINACT/not-self-contained-install-location/
tar xf IINACT-dn7-not-self-contained.tar.gz -C ~/.xlcore/wineprefix/drive_c/IINACT/not-self-contained-install-location/
DOTNET_BUNDLE_EXTRACT_BASE_DIR="" WINEPREFIX=~/.xlcore/wineprefix WINEESYNC=1 WINEDLLOVERRIDES=msquic=,mscoree=n,b ~/.xlcore/compatibilitytool/beta/*/bin/wine64 ~/.xlcore/runtime/dotnet.exe ~/.xlcore/wineprefix/drive_c/IINACT/not-self-contained-install-location/IINACT.dll
I have found a solution to this problem.
According to this comment, setting COMPlus_EnableWriteXorExecute=0
makes IINACT on .NET 7 run fine on my Wine.
...or not, it worked a single time for me, now it stops running again
EDIT: It may have been a fluke altogether, as I suspect that I accidentally mixed some paths. But I'm still looking into this regardless.
Okay I finally got further. Running the not-self-contained version, installing .NET 7 AND setting DOTNET_ROOT="C:\\Program Files\\dotnet"
, I was able to get it to run... somewhat?
Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at System.Net.Quic.MsQuicApi.TryOpenMsQuic(Microsoft.Quic.QUIC_API_TABLE* ByRef, Int32 ByRef)
at System.Net.Quic.MsQuicApi..cctor()
at System.Net.Quic.QuicConnection.get_IsSupported()
at System.Net.Http.HttpConnectionPool..ctor(System.Net.Http.HttpConnectionPoolManager, System.Net.Http.HttpConnectionKind, System.String, Int32,
System.String, System.Uri)
at System.Net.Http.HttpConnectionPoolManager.SendAsyncCore(System.Net.Http.HttpRequestMessage, System.Uri, Boolean, Boolean, Boolean, System.Thre
ading.CancellationToken)
at System.Net.Http.HttpConnectionPoolManager.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, Boolean, System.Threading.CancellationToken)
at System.Net.Http.HttpConnectionHandler.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
at System.Net.Http.HttpMessageHandlerStage.SendAsync(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
at System.Net.Http.DiagnosticsHandler.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
at System.Net.Http.RedirectHandler+<SendAsync>d__4.MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.RedirectHandler+<SendAsync>d__4, System.Net.Http, Version=7.0.0.
0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<SendAsync>d__4 ByRef)
at System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder`1[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, Publi
cKeyToken=7cec85d7bea7798e]].Start[[System.Net.Http.RedirectHandler+<SendAsync>d__4, System.Net.Http, Version=7.0.0.0, Culture=neutral, PublicKeyTok
en=b03f5f7f11d50a3a]](<SendAsync>d__4 ByRef)
at System.Net.Http.RedirectHandler.SendAsync(System.Net.Http.HttpRequestMessage, Boolean, System.Threading.CancellationToken)
at System.Net.Http.HttpMessageHandlerStage.SendAsync(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
at System.Net.Http.SocketsHttpHandler.SendAsync(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
at System.Net.Http.HttpClient+<GetStreamAsyncCore>d__51.MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.Net.Http.HttpClient+<GetStreamAsyncCore>d__51, System.Net.Http, Version=7
.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]](<GetStreamAsyncCore>d__51 ByRef)
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyT
oken=7cec85d7bea7798e]].Start[[System.Net.Http.HttpClient+<GetStreamAsyncCore>d__51, System.Net.Http, Version=7.0.0.0, Culture=neutral, PublicKeyTok
en=b03f5f7f11d50a3a]](<GetStreamAsyncCore>d__51 ByRef)
at System.Net.Http.HttpClient.GetStreamAsyncCore(System.Net.Http.HttpRequestMessage, System.Threading.CancellationToken)
at FetchDependencies.FetchDependencies+<DownloadPlugin>d__7.MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[FetchDependencies.FetchDependencies+<DownloadPlugin>d__7, FetchDependencies, Ver
sion=1.0.0.0, Culture=neutral, PublicKeyToken=null]](<DownloadPlugin>d__7 ByRef)
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[[FetchDependencies.FetchDependencies+<DownloadPlugin>d__7, FetchDependencies, Ver
sion=1.0.0.0, Culture=neutral, PublicKeyToken=null]](<DownloadPlugin>d__7 ByRef)
at FetchDependencies.FetchDependencies.DownloadPlugin(System.String)
at FetchDependencies.FetchDependencies+<GetFfxivPlugin>d__5.MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[FetchDependencies.FetchDependencies+<GetFfxivPlugin>d__5, FetchDependencies, Ver
sion=1.0.0.0, Culture=neutral, PublicKeyToken=null]](<GetFfxivPlugin>d__5 ByRef)
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[[FetchDependencies.FetchDependencies+<GetFfxivPlugin>d__5, FetchDependencies, Ver
sion=1.0.0.0, Culture=neutral, PublicKeyToken=null]](<GetFfxivPlugin>d__5 ByRef)
at FetchDependencies.FetchDependencies.GetFfxivPlugin()
at IINACT.Program.Main(System.String[])
You need to disable msquic, or the very least WINEDLLOVERRIDES=msquic=,mscoree=n,b
is needed.
But thanks for all the investigation so far into it, will do some testing on my laptop today where I can reproduce it
And after disabling msquic, I am now running IINACT 1.0.
So the steps at the moment seem to be:
DOTNET_ROOT="C:\\Program Files\\dotnet"
But as for why the self-contained version has this problem, I am not fully sure. I tried running an strace on it but it also contained traces for wine so it is annoying to strip apart. A CoreHost trace also didn't reveal all too much information:
The only thing it DID reveal was that it apparently couldn't find any CoreCLR paths. Maybe there is a build setting that got its default changed related to this issue?
EDIT: Running a CoreHost trace on the "old" version, the missing CoreCLR path is also the case, so that path doesn't really go anywhere... I might need to compare the logs side by side to see what might be a culprit.
Now that dalamud for patch 6.3 is out, it raised the question to me on why IINACT on .NET 7 isn't working, but dalamud on .NET 7 is. The only thing I could think of is the nature of the PublishSingleFile exes vs dalamud's dll loading approach. I tried running both the self-contained and not-self-contained .exe files through ~/.xlcore/runtime/dotnet.exe, but no luck.
However, compiling from source and running the following DOES work, if reverting to .NET 6 seems unappealing.
dotnet publish --self-contained false -p:PublishSingleFile=false -c release -p:EnableWindowsTargeting=true
tar czvf IINACT-dn7-not-self-contained.tar.gz -C IINACT/bin/Release/net7.0-windows/win-x64/publish/ .
mkdir -p ~/.xlcore/wineprefix/drive_c/IINACT/not-self-contained-install-location/
tar xf IINACT-dn7-not-self-contained.tar.gz -C ~/.xlcore/wineprefix/drive_c/IINACT/not-self-contained-install-location/
DOTNET_BUNDLE_EXTRACT_BASE_DIR="" WINEPREFIX=~/.xlcore/wineprefix WINEESYNC=1 WINEDLLOVERRIDES=msquic=,mscoree=n,b ~/.xlcore/compatibilitytool/beta/*/bin/wine64 ~/.xlcore/runtime/dotnet.exe ~/.xlcore/wineprefix/drive_c/IINACT/not-self-contained-install-location/IINACT.dll
Moving into Dalamud has its own advantages. If IINACT is constantly at the mercy of the Wine settings and .NET versions provided, and its also the only viable install option for MacOS and Linux, it might make sense to look into a plogon as a long term approach
So the steps at the moment seem to be:
1. Install .NET 7 Runtime for desktop applications (because the one for console applications isn't enough) 2. Download and extract the not self contained version 3. Set `DOTNET_ROOT="C:\\Program Files\\dotnet"` * This fixes a potential bug with the search path on wine, where it will try to use the .NET host and shared libraries from the Linux host, as that is mounted onto Z:\ (more than potential, it happened for me) 4. Disable msquic via the WINEDLLOVERRIDES env var like @marzent pointed out or disable it using winecfg.
I wasn't happy with any of the following as a solution:
~/.xlcore/runtime/dotnet.exe
I spent some time putting together various pieces to come up with the following:
DOTNET_ROOT=~/.xlcore/runtime/ DOTNET_BUNDLE_EXTRACT_BASE_DIR= WINEPREFIX=~/.xlcore/wineprefix WINEDLLOVERRIDES=msquic=,wpcap=,mscoree=n,b WINEESYNC=1 ~/.xlcore/compatibilitytool/beta/*/bin/wine64 "$HOME/.xlcore/wineprefix/drive_c/IINACT/IINACT.exe"
this still only works with the non self-contained builds, but I still think its an improvement. Breaking it down:
DOTNET_ROOT=~/.xlcore/runtime/
will use Dalamud's installation of .NET to start the .exe instead of requiring you to install a second copy of it into your wine prefix manually. This also means whenever Dalamud updates their .NET runtime for minor security updates, it'll happen automatically for your IINACT installation as well.DOTNET_BUNDLE_EXTRACT_BASE_DIR=
will unset the environment variable in case any linux native version of .NET set it to something which confuses your windows version.WINEDLLOVERRIDES=msquic=,wpcap=,mscoree=n,b
will disable certain parts of the .NET runtime from loading. I managed to get this to not crash on arch with only WINEDLLOVERRIDES=msquic=
, but it seemed to have a lot of errors when parsing, seems better just to go with what's been working most consistently for everyone, even if its maybe overkill.Setting
WINEDLLOVERRIDES=msquic=,wpcap=,mscoree=n,b
will disable certain parts of the .NET runtime from loading. I managed to get this to not crash on arch with onlyWINEDLLOVERRIDES=msquic=
, but it seemed to have a lot of errors when parsing, seems better just to go with what's been working most consistently for everyone, even if its maybe overkill.
Not all of that is .NET related. The wpcap
part for example disables the builtin winpcap from loading. I think you will still need to install winpcap into the prefix and then you might as well turn wpcap=n
to make sure it only ever loads the native one.
Still, it'd be interesting to know why the bundled version straight up doesn't work...
I actually found something that may be related to this error, but which won't make us happy. Same error, roughly the same setup (single file, self-contained, win-x64), but not in Wine but rather a Windows 10 workstation.
tl;dr: OP tested targeting .NET 8, it worked again, then uninstalled .NET 8 and it was still working, after which the issue was closed.
I have tried out just installing .NET 8 but that alone doesn't do the trick. I might just actually try to build it with .NET 8 tomorrow and see if that fixes it. If so, we could potentially release a .NET 7 and a .NET 8 build once .NET 8 has released, but I don't know if that's really a good solution. Maybe the issue can be reactivated to get a fix into .NET 7 instead, which would be great.
Will still leave this pinned for reference, but closing it since no longer relevant for 2.X
Tested on latest Arch Linux.
with XIV Core Wine
WINEPREFIX=~/.xlcore/wineprefix WINEESYNC=1 DOTNET_BUNDLE_EXTRACT_BASE_DIR="C:\\IINACT\\" ~/.xlcore/compatibilitytool/beta/wine-xiv-staging-fsync-git-7.10.r3.g560db77d/bin/wine64 "$HOME/.xlcore/wineprefix/drive_c/IINACT/IINACT.exe"
with system wine:
WINEPREFIX=~/.xlcore/wineprefix WINEESYNC=1 DOTNET_BUNDLE_EXTRACT_BASE_DIR="C:\\IINACT\\" wine "$HOME/.xlcore/wineprefix/drive_c/IINACT/IINACT.exe"
I also cloned the repo and set all the csproj's to net6-windows from net7-windows (as well as patching various files in FFXIVClientStructs to not use .NET 7isms) and everything worked fine. I'm able to parse in game successfully with my manually built version. I'm thinking its somehow related to .NET 7 because of this, as from searching the error is seems to be an extremely early load failure for .NET, such that it might even be difficult to do debugging as the CLR hasn't setup any of the debugging utils as early as this fails. The command I used to compile to .NET 6 version for info:
dotnet publish --self-contained true -c release --maxcpucount:1 -p:EnableWindowsTargeting=true