I have a .NET project that I've been compiling with Visual Studio and running successfully on Windows for years. I'd like to move to use Mac OS X to run this particular program, and so have been working with mono for just a little while do make that possible. The results have been excellent, with the program performing as expected under mono (2.10.9, BTW).
The only hitch is that the program does not exit after it is done. It is a single-threaded process, but when its work is completed (which it reports at the end of the Main(string[]) method), the process does not exit; ^C is required to return to the shell prompt. Adding an explicit System.Environment.Exit(exitCode); call at the end has no effect.
I found only one other tale of this sort of problem from some years ago, here, though that ML thread provided no potential solution.
Rolf (in his comment on the question) was right, the vm was deadlocking upon shutdown.
I'm using IKVM in this application, and there are certain circumstances where it needs to start a thread at vm shutdown to clean up its JVM<->CLR interop machinery; this apparently does not sit well with mono (but always works in .NET).
This was discovered on a thread on the IKVM dev list by IKVM's author, who filed this bug with the mono project.
The workaround in my case was to explicitly call java.lang.System.exit(exitCode) instead of simply letting the program terminate naturally or using System.Environment.Exit(exitCode). This allows IKVM to shut down outside of the vm termination lifecycle, thereby avoiding the mono bug.
Related
Has anyone been successful at packaging a Gtk3 app for Windows for the Microsoft store?
I'm playing with this at the moment:
Visual Studio 2019;
Gtk3/Gtkmm distro obtained via vcpkg;
C++ app;
VS Application Packaging Project.
The application runs fine on its own. I then package it, and then run the MSIX bundle installer. When I then run the installed application, it starts but:
an Access Denied error appears in a dialog box;
the application appears with broken icons and incorrect colors (wrong or no theme).
I have tracked the error having to do with Gio-2.DLL where it attempts to spawn a child process, looks like something to do with creating a dbus server/session (??). I believe the child process (dbus server?) starts but then attempts to do something that is not permitted in the sandbox that Windows creates for the app.
Anyone?
After some more investigation, I may have found a workaround. I'll post it here in case it helps anyone else. This workaround allows making a packaged Gtk3 application for Windows. A Windows packaged application runs in a sandbox of sorts, with heavily restricted access to resources outside the package.
First, the issue: during initialization, the version of Gio-2.DLL for Windows spawns a child process to serve as a DBus session daemon (I may get the terminology wrong here as I'm not that familiar with DBus). It does so only for the first instance. If one launches additional instances of applications that use Gio-2.DLL, the additional instances use the existing daemon from the first instance.
To launch the daemon, Gio-2.DLL calls CreateProcess() to fork a RUNDLL32.EXE child, with the full path to Gio-2.DLL (i.e. itself), and g_win32_run_session_bus() as the name of the function to call. It looks like RUNDLL32.EXE does launch successfully, since it is able to display the "RUNDLL" error dialog box. However it fails to make the requested function call into Gio-2.DLL. I gather that at least one of the system calls that RUNDLL32.EXE makes to load the DLL and call the requested function is prohibited when running in a packaged application.
At the moment, my workaround is this. Assume my application executable is called 'myapp.exe':
the application package contains myapp.exe, all the necessary DLLs for Gtk3 and dependencies, and another executable 'dbus_daemon_launcher.exe';
before entering the Gtk main loop, myapp.exe calls CreateProcess() to start dbus_daemon_launcher.exe;
dbus_daemon_launcher.exe is also linked with Gio-2.DLL and makes a call to g_win32_run_session_bus() with the DLL;
myapp.exe then proceeds to start the Gtk main loop. Since the Dbus daemon is then already running, Gio-2.DLL does not attempt to call RUNDLL32.EXE to launch it, which avoids the error.
This workaround has the advantage that it does not require making a custom version of Gio-2.DLL. Also, I'm using Gtk3: perhaps this issue has been addressed in the more recent Gtk4, and the workaround is unnecessary in this case.
We're having a very strange behaviour that I'm unable to identify a root cause for. We use TFS (2017.U2) to compile our legacy system, and are trying to update our build farm from 2008R2 up to 2016. The build system uses PowerShell (v5) to cycle through a list of VBP projects and run a VBS script to compile the projects.
First a bit of basics. UAC is totally disabled (in the registry, not just the slider control), VB6.EXE is also set to XP SP3 compatability, and also to run as the administrator.
Unfortunately, while we can see VB6.EXE start in task manager - it just hangs. Zero activity. Running the same compile interactively works just fine with the same user. This led me to theorize it was an environment problem, however process explorer shows me a valid user environment on the VB6.EXE process.
I don't believe this is due to VB6 throwing an error, as (at least in previous versions of Windows Server) when a background process opens a UI element, the OS indicates to the foreground that the background wants to break in. We dont see that.
We've stubbed this back to a bare minimum code example which I call "test.ps1":
$vb6="C:\Program Files (x86)\Microsoft Visual Studio\VB98\vb6.exe"
Set-Location D:\Builds\27\s\path\prjdir
start-process $vb6 -ArgumentList "/make /out errors.txt project.vbp" -wait
We've been using "start-process" to trigger the VB6 compiles because direct invokation via PowerShell doesn't ingest the parameters properly (they're actually built out of strings passed into the master script in the full blown process... this is the simplified version).
When run interactively (.\test.ps1) this functions properly. The project compiled and I get an errors.txt file written.
When started as a process (start-process .\test.ps1) this again functions properly.
When triggered via a TFS "PowerShell Script" task, this fails to complete the VB6 step - the VB6.EXE can be seen in the Task viewer with the appropriate arguments, and no CPU or IO is associated with the task. No errors.txt file is written. No new DLL is created.
I was able to dummy this down even further and remove TFS from the stack by running the test script from another machine. I ran a remote invokation of the script, and duplicated the result using this command:
PS C:\Users\svc_build> Invoke-Command –ComputerName TestBuild02 –ScriptBlock {powershell C:\Users\svc_build\desktop\test.ps1 }
Again, no errors.txt, and no new DLL. VB6.EXE starts up and just sits there. Process monitor doesnt provide any help in diagnosing what might be the issue.
This now smells of a security door being shut on me - even though the same domain user is running the same job, the difference is that this is a background process... and something is preventing a background process of executing in the same context as a foreground process.
Assuming this assumption is correct, can someone point me at the reason a remotely triggered (background) session isn't able to run VB6.EXE? (and of course, a work around for the situation would be appreciated :) )
If this is not a security issue - can someone identify the real culprit, and the solution to getting VB6 running as a background process, like we're used to seeing it run on W2K8R2?
I'm a bit late to the party, but this sounds like a very similar scenario to what I've just encountered.
Windows 10 v2004
UAC disabled
Compiling by running VB6.exe via a PowerShell script.
Using Bamboo as the build server, running as a Managed Service Account.
When running the build on the server via Bamboo, it hangs. When logging into the build server and running the build manually, it succeeded.
After cutting down the code I was able to reproduce a minimal failing case. The hang was caused by code in a UserControl's UserControl_Initialize method that was manipulating UI controls, but only when that UserControl was placed on a Form in the same project.
During compilation, the compiler will create an instance of the Form (why, I don't know), which in turn creates an instance of the UserControl, which in turn runs the UserControl_Initialize method. I can only assume that running the code at that point resulted in an error of some sort, and that resulted in the compiler hanging.
The same error can be caused by the UserControl_Resize event. That case is reasonably easy to fix by checking if Ambient.UserMode is true before trying to resize the child controls.
Private Sub UserControl_Resize()
If UserControl.Ambient.UserMode Then
' Position the child controls
End If
End Sub
Fixing the UserControl_Initialize methods required the code in those methods to be run at a different point (for example, when the UserControl is given the data to display, we now run the code that was previously in UserControl_Initialize).
Also worth noting is the compatibility settings for VB6.exe that we had to use. Using "Windows XP SP3" compatibility mode resulted in VB6.exe hanging immediately. We had to set it to not use any compatibility mode, but we did have to set Run this program as an adminisrtator, and had that applying for all users.
I've completed work on a project that is all ready to go except for one problem : Upon installation, it fails to run on a fresh system (that is, one that has never been updated, had anything installed to it, or anything else).
The system installs by a Microsoft Setup and Deployment project, and successfully downloads .Net Framework 4.5 but it still fails to run, and the error is completely useless.
The program is written on the .Net 4.5 framework, and is written in C#/WPF/XAML. Other than needing .Net 4.5, what other prerequisites should I be checking for/downloading to the target system?
When I say "It fails to run", what I mean is that the program does not launch. The user double-clicks the shortcut, and they get a message box that says
PROGRAM has stopped working.
A problem has caused the program to stop working correctly.
Windows will close the program and notify you if a solution is available
Also; The program works perfectly fine on other systems, it's just it seems systems fresh out of the box it fails on (in the manner as noted above).
The short answer is that you need to identify the software your program uses that is not part of the .NET Framework. That might include Crystal Reports, some SQL components, any third party NET controls, COM components. Typically the first cut is Microsoft vs 3rd party because 3rd party software will not be on someone's random system. After that, see what Microsoft components you might be using that are separate redistributables.
It may be useful to have a message box as the first thing your program does (as a test). If it's all .NET and it starts, then probably most of the NET references are there. If it doesn't start you are probably missing a referenced assembly. If it crashes later, then all you need is some diagnostic or trace data (and error handling) to see if you trying to do something like create a COM object that hasn't been installed.
However if it's not a dependency issue then it could be an architecture issue if you have an AnyCpu build and trying to call a Dll with the wrong bitness, and not designing for 64-bit and 32-bit systems. Or if you're doing something really unusual, Data Execution Prevention might be preventing the program from running - I think you'll see that message in those cases. I also suspect that some AntiVirus programs will step in and cause this error if they see the code doing something prohibited.
My problem is not the best scenario for fork(). However, this is the best func I can get.
I am working on a Firefox plugin on Mac OSX. To make it robust, I need to create a new process to run my plugin. The problem is, when I forked a new process, much like this:
if (fork() == 0) exit(other_main());
However, since the state is not cleaned, I cannot properly initialized my new process (call NSApplicationLoad etc.). Any ideas? BTW, I certainly don't want create a new binary and exec it.
In general, you need to exec() after fork() on Mac OS X.
From the fork(2) man page:
There are limits to what you can do in the child process. To be totally safe you should restrict your-self to only executing async-signal safe operations until such time as one of the exec functions is called. All APIs, including global data symbols, in any framework or library should be assumed to be unsafe after a fork() unless explicitly documented to be safe or async-signal safe. If you need to use these frameworks in the child process, you must exec. In this situation it is reasonable to exec yourself.
TN2083 also comments on this subject:
Many Mac OS X frameworks do not work reliably if you call fork but do not call exec. The only exception is the System framework and, even there, the POSIX standard places severe constraints on what you can do between a fork and an exec.
IMPORTANT: In fact, in Mac OS X 10.5 and later, Core Foundation will detect this situation and print the warning message shown in Listing 13.
Listing 13: Core Foundation complaining about fork-without-exec
The process has forked and you cannot use this CoreFoundation functionality safely. You MUST exec().
Break on __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__() to debug.
fork without exec is basically entirely unsafe on OSX. You will end up with stale mach ports for example.
I'm writing the FreeWRL plugin for Firefox (Linux at the moment, Mac & Windows soon).
http://freewrl.sourceforge.net/
It's based on fork+exec to launch FreeWRL and swallow its window into Firefox.
You'll have to use a pipe to correctly handle the possible failure of fork+exec or the failure of your child process :
How to handle execvp(...) errors after fork()?
Cheers,
C
I have a console application (written in VB6 ) which is behaving strangely on my machine. I kick it off from the command line and what should be a two minute job drops straight back to the prompt - if I run this on another machine the executable will sit and wait until the job finishes before returning control back to the prompt. If I check process explorer I can see that the executable is running as a background process and other than this strange background-ness is running as expected.
Any thoughts on why this could be happening? (Running on 32-bit Windows XP Pro SP3.)
It's totally unclear whether this is an application you wrote and have the source code for. If that's the case, you need to get in and start debugging. At the least, use OutputDebugString to send information about what's going on to any number of potential viewers. Taking that a step further, consider rewiring the app using the Console module I wrote, along with vbAdvance to recompile. This combination will allow you the full power of the VB6 IDE to debug within. No more guessing about what's going on.
Then again, if it's not your app, I'm not sure what VB6 has to do with it and wish you the best of luck trying to figure out what's up.
It sounds to me as though the app isn't being recognised as a console app on one of your machines. Console apps weren't officially supported in VB6, although there are some well-known hacks for creating them (particularly the free add-in vbAdvance). Possibly your console app is a bit unreliable? If Windows thinks your app is a GUI rather than a console app, it won't wait for it to finish.
As a pragmatic workaround: try launching with start /wait rather than just using the exename. That forces the command prompt to wait for the program to finish, whether it's a GUI app or a console app.
Sounds like an error is occurring that is being 'swallowed' by the application. Do you have the source code?
Errors in VB6 apps are often due to some COM component not installed and/or registered.
Download SysInternals Process Monitor and this will show up accesses to ProgIDs that fail (uninstalled/unregistered COM components).
Check out: Process Monitor - Hands-On Labs and Examples.
Have you checked permissions? Is the application accessing any network based resources?