Repository: electron
Issue: Electron fails to launch on Windows when null device is disabled
Labels: platform/windows,bug :beetle:,has-repro-comment,33-x-y

### Preflight Checklist

- [x] I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/main/CONTRIBUTING.md) for this project.
- [x] I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/main/CODE_OF_CONDUCT.md) that this project adheres to.
- [x] I have searched the [issue tracker](https://www.github.com/electron/electron/issues) for a bug report that matches the one I want to file, without success.

### Electron Version

33.2.0

### What operating system(s) are you using?

Windows

### Operating System Version

Windows 10

### What arch are you using?

x64

### Last Known Working Electron version

28.3.3

### Expected Behavior

Electron launches normally.

### Actual Behavior

Electron crashes in node::InitializeOncePerProcess and fails to launch.
![Image](https://github.com/user-attachments/assets/90d07b0e-9245-4c58-9e91-400961373219)


### Testcase Gist URL

_No response_

### Additional Information

I have submitted this issue before with another account. But that account is suspended and my issue and pull request are 404 now. I don't know what happened to my account and fail to get my account back after a long struggle, so I submit this issue again with my new account.

It is rare but legal to disable null device on windows platform, in which situation, electron fails to launch definitely because node tries to reinitialize stdio with null device. 
To reproduce this issue, we can just set Start = 4 (which is 1 normally) in registry key HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Null
![Image](https://github.com/user-attachments/assets/27d22a4b-796e-4363-b889-35c7ae7f9168)

This issue was introduced in electron v29.0.0, when node was upgraded from v18.2.8 to v20.9.0 in this commit https://github.com/electron/electron/commit/9c94fd7afb4706c2d2228a455f0874a0370cfe1d
![Image](https://github.com/user-attachments/assets/93b41a60-859b-4d5f-8da6-4c140e057ad2)

Since node v19.0.0, PlatformInit is changed to be invoked definitely, while in old versions, it is controlled by flag kRunPlatformInit and not invoked in electron. https://github.com/nodejs/node/commit/b6971602564fc93c536ad469947536b487c968ea
![Image](https://github.com/user-attachments/assets/95b1a0ff-598a-44cb-b2d3-9d186a3f6001)

In PlatformInit, stdio is reinitialized with nul device. 
```
#ifdef _WIN32
  if (!(flags & ProcessInitializationFlags::kNoStdioInitialization)) {
    for (int fd = 0; fd <= 2; ++fd) {
      auto handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
      if (handle == INVALID_HANDLE_VALUE ||
          GetFileType(handle) == FILE_TYPE_UNKNOWN) {
        // Ignore _close result. If it fails or not depends on used Windows
        // version. We will just check _open result.
        _close(fd);
        if (fd != _open("nul", _O_RDWR)) ABORT();
      }
    }
  }
#endif  // _WIN32
```
However, in widows gui apps, _get_osfhandle will always fail because stdio is not associated with a stream by default.
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/get-osfhandle?view=msvc-170
> When stdin, stdout, and stderr aren't associated with a stream (for example, in a Windows application without a console window), the file descriptor values for these streams are returned from [_fileno](https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/fileno?view=msvc-170) as the special value -2. Similarly, if you use a 0, 1, or 2 as the file descriptor parameter instead of the result of a call to _fileno, _get_osfhandle also returns the special value -2 when the file descriptor is not associated with a stream, and does not set errno. However, this is not a valid file handle value, and subsequent calls that attempt to use it are likely to fail.

So node will always open null device to replace stdio. Once null device is disabled, node fails to open null device and aborts here.

PlatformInit was not invoked and node feature StdioInitialization was not used in old electron versions, which works fine. So I think electron doesn't depend on this feature and it is safe to add flag node::ProcessInitializationFlags::kNoStdioInitialization when initializing node in electron to solve this issue.