A while ago i wrote a C++ CLI Windows Form app, which compiled fine in Visual Studio 2013. Now i wanted to recompile it in Visual Studio 2015 Update 1 but i'm facing a problem, and after hours of tests i figured out the culprit is afxwin.h.
TL;DR - Is there any way i can use stdafx.h (so afxwin.h and all other imports coming with it) in a Windows Form app compiled with Visual Studio 2015 without having the app crash upon start?
Here's how to reproduce the same issues i'm facing in my app.
Since Windows Form is no longer available as project template in VS2015, i created a CLR Empty Project called Test
Ctrl-Shift-A to add a UI > Windows Form called MyForm
In MyForm.cpp i added this:
#include "MyForm.h"
using namespace System;
using namespace System::Windows::Forms;
[STAThread]
int main(cli::array<System::String^>^ args)
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
Test::MyForm form;
Application::Run(%form);
}
Under Configuration Properties > Linker > Advanced i set Entry Point to main
Under Configuration Properties > Linker > System i set SubSystem to Windows (/SUBSYSTEM/WINDOWS)
COMPILE (DEBUG CONFIGURATION): compiles with no errors/warnings
RUN: runs without any problem.
Now lets try adding afxwin.h to MyForm.cpp:
#include <afxwin.h>
Under Configuration Properties > General i set Use of MFC to Use MFC in a shared DLL
COMPILE (DEBUG CONFIGURATION): compiles with no errors/warnings
RUN: the app wont even start, it just shows Debug Assertion Failed error in expression _CrtIsValidHeapPointer(block)
Now to fix this error i found that it's necessary to remove the Entry Point, so:
Under Configuration Properties > Linker > Advanced i removed Entry Point value (which i previously set to main)
COMPILE (DEBUG CONFIGURATION): compiles with no errors/warnings
RUN: the app again wont even start, it no longer shows Debug Assertion Failed but System.AccessViolationException in an unknown module and "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
These are the errors i get in my app, and i'm wondering how is it possible that simply including afxwin.h gives all these problems in VS2015 while it didnt in VS2013.
Is there anything i can do to fix it, without going back to VS2013?
The C runtime library was significantly rewritten for VS2015 by James McNellis. He's a big C++ fan, the new code he's written suffers from the chronic SIOF problem that's so common in a C++ program. The Static Initialization Order Fiasco was surely present in your VS2013 project as well but happened not to byte, the original CRT code was exposed to SIOF for many years so likely to behave better.
Excessively hard to debug in this case, the code that fails comes from a CRT source code file that is not included in the install named thread_safe_statics.cpp. Not 100% sure what it does given that there's no source code to look at but the name of the file leaves little to the imagination.
MFC has static state that needs to be initialized before it is usable. In particular, the program must have a static CWinApp variable that is initialized at Just the Right Time. That requires the entrypoint to be WinMain(), implemented in MFC, and an explicit declaration of a CWinApp instance in your source code. Like this:
[STAThread]
int main(cli::array<System::String^>^ args)
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
Application::Run(gcnew Test::MyForm);
}
class MyMfcApp : public CWinApp {
public:
virtual int Run() override {
return main(__nullptr);
}
} MyApp;
Reset the linker's EntryPoint setting back to its default (blank) so the CRT is initialized first and MFC's WinMain function runs next. And beware I took a shortcut, you get no args. And I fixed a bug in your main() function, it used stack semantics incorrectly.
This hack gets your program running again. Whether it is actually correct is rather doubtful. This suffers from the "Who is the Boss" syndrome that's associated with big frameworks. Don't depend on any MFC window to work correctly since it is Winforms that is dispatching messages. But you should have had that problem in VS2013 as well. "Don't do it" is the only solid advice.
Related
I'm a rookie at C in general and VS 2013 also. I am trying to use some C code provided by a vendor in VS 2013 express. It compiles and runs without problem using the command line compiler but I would like to use the IDE.
I started a new project, C++ for console app, and I have pasted the code into the IDE and saved it as xyy.c so that it builds successfully. I thought it would be nice to have it in a GUI, so I duplicated the effort with a Win32 app project. It also builds.
The program's job is to connect to a PCI card that has Plx chip as an interface and program an FPGA. The Win32 program succeeds, even though I can't see any of the info printed by the program. The console program fails and I think it is because it fails to find the driver for the Plx chip. I thought I would get a clue by single stepping through the Win32 program to see which driver was supposed to be found.
However, after the first pass through a while loop, I get a pop up that says "Source Not Found" and "stack.cpp not found". Google wasn't any help to me.
I be grateful for any suggestions.
You might have "Enable .NET Framework source stepping" enabled (see http://msdn.microsoft.com/en-us/library/cc667410.aspx). So when you are at Stack... and trying to step into, it will actually try, but you don't have the sources for that. There is also a new experience for using the .NET framework reference source that was announced recently: http://blogs.msdn.com/b/dotnet/archive/2014/02/24/a-new-look-for-net-reference-source.aspx
I faced the same problem. I advise at the moment of receiving the information "stack.cpp not found" to look at the stack trace and check if there is something like this: "RTC".
If there is, you need to change the flag along the path (for example, set the Default or a more convenient configuration for you):
Project Properties -> C/C++ -> Code Generation -> Basic Runtime Checks
More details: https://learn.microsoft.com/en-us/cpp/build/reference/rtc-run-time-error-checks?view=msvc-160
When I launch my WPF application and when it goes to InitializeComponent function call of one user control, it silently quits and only leaves one message in the output window saying Managed (v4.0.30319)' has exited with code -1073740771 (0xc000041d). When I say "silently", I mean there is no exception is caught even if I wrap this InitializeComponent call with a try-catch block (that's how I normally find where the problem is)
Here is what I did: in this application project we need to use a reference Microsoft.Office.Interop.Owc.dll, with version number 10.0.4504.0. Since it is an interop library, when I added this reference in VS2012, it automatically sets the property Embedded Interop Types as true, which I assume means it will not keep an individual dll in the output folder but instead embed this library into the main output (at least this is how it seems in our other references, for example, Microsoft.Office.Interop.Outlook.dll). However, when I launch the project, it throws an XamlParseException saying:
"Could not load file or assembly 'Microsoft.Office.Interop.Owc, Version=10.0.4504.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system
cannot find the file specified.":"Microsoft.Office.Interop.Owc, Version=10.0.4504.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35""
It seems that the reference was not embedded(or the version is not currect. But I verified that the reference version is indeed 10.0.4504.0)
Next I copied this dll directly to the output folder bin\Debug\, to make sure that it can find this library. This time the exception is not thrown, but the whole application just silently quits as I described in the beginning. I tried to google the code -1073740771 (0xc000041d) but there is no article about it. I tried to set the Embedded Interop Types to true/false but the problem is the same.
UPDATE:
I'd like to add more description here. As mentioned above, the problematic library is OWC(Office Web Component)10. I followed this link to make OWC work with VB.NET desktop application: HOW TO: Handle Events for the Office Web Components in Visual Studio .NET. But this official article is so old so I had to make a lot of changes to compile the wrapper dll(mainly because of namespace mismatch). Then when I add the reference to the actual interop library Microsoft.Office.Interop.Owc, if I follow the default setting and let the Embedded Interop Types as True, at runtime it will complain (throw a XamlParseException) that the assembly cannot be loaded (see description above). What the hell? I thought make it as "embedded" would guarantee this library will be found. Then I copy this dll to the output folder, then I have this silently quit problem. But it might be worth mentioning that this time the output window shows the Microsoft.Office.Interop.Owc.dll is indeed loaded. Actually it is the last message before the managed has exited message. So it must still relate to this library.
All of this only happens with OWC10. There is actually a similar way to do that in OWC11(the latest, but unfortunately still pretty old version since it came with Office2003): HOW TO: Handle Events for the Office 2003 Web Components in Visual Studio .NET. But it actually works and the control is displayed on my application. It is because of some other reason that I wanted to try OWC10 instead of OWC11
When I launch my WPF application and when it goes to InitializeComponent function call of one user >control, it silently quits and only leaves one message in the output window saying Managed
(v4.0.30319)' has exited with code -1073740771 (0xc000041d). When I say "silently", I mean there is >no exception is caught even if I wrap this InitializeComponent call with a try-catch block (that's >how I normally find where the problem is)
Next I copied this dll directly to the output folder bin\Debug\, to make sure that it can find this >library. This time the exception is not thrown, but the whole application just silently quits as I >described in the beginning. I tried to google the code -1073740771 (0xc000041d) but there is no >article about it. I tried to set the Embedded Interop Types to true/false but the problem is the >same.
I had exactly the same thing happening to me today, "has exited with code -1073740771 (0xc000041d)." (This happened in both a VB and C# .NET WinForms application for me). I tried debugging and saw I never even got into the Form_Load code block.
I "solved" this in the end by running visual studio as an administrator (and then just opening & building and running the project via the menu).
This is a win8 security issue and it isn't well explained anywhere.
(I got distracted and just opened up a specific project straight out of my task bar/solution file which caused this to happen to me).
You've probably found this out by yourself by now, hope you didn't lose any hair over it :)
Just pointing this out for other people who might have this error occuring somewhere.
Also had this issue, the 'silent' exit with code -1073740771 (0xc000041d) on x64 platforms, on x86 platforms everything was OK.
Part of my application is unmanaged C++, another part is C#. It turned out that my C++ code was not completely ready for the x64 platform. The following change fixed the issue in my case:
// before
g_OrigWndProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(hWnd, GWLP_WNDPROC,
reinterpret_cast<LONG>(WindowProc)));
// fixed version
g_OrigWndProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(hWnd, GWLP_WNDPROC,
reinterpret_cast<LONG_PTR>(WindowProc)));
So, the generic recommendation is to verify that your code is completely ready for the x64 platform.
Background info
I'm maintaining a Winforms application in C# using VS2010. The main form has a TabControl with a few tabs. The startup object is a class with a Main funcion (nothing new here) that does nothing more than firing the main form.
The form creates a Datastore object that gets it's connection string to the DB server from a static Settings class. This class has a static intializer block:
static Settings()
{
IniReader reader = new IniReader("config.ini");
//...
}
The configuration file resides in the main project folder (same as the startup object) (and also in the bin and debug folders).
Problem
In solution explorer, when I double click the main form to open it in the designer, VS crashes with the exception mentioned in the title of this question, but also with an error stating that it can't find the config.ini file in "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE".
The problem can be resolved by copying the config file to that location, but I don't find this a real solution.
Why would VS search for the file in that location?
Strangely, the last time I opened the solution, I didn't have this problem. I haven't installed new Windows updates since then.
Remark
The architecture of the application and other design decisions aren't mine. I'm just extending the program and while doing this, I'm trying to improve on the architecture. But that's not the subject of this question.
I think you already understand that the VS designer creates an instance of the form it's trying to show, and that means it will invoke the constructor and any static constructor.
The most common pattern I've seen for avoiding this kind of problem is to move any non-trivial initialisation logic into a separate Initialise method. In there, and in any method other than a constructor, you can use...
if (!DesignMode)
{
//your code here
}
...around any code that isn't actually needed for the form to render correctly in the designer. I realise that means some refactoring of the code and you may not want to do that, but I have used this approach and it avoids this kind of problem well.
I have an image processing C program which uses OpenCV library. I was developing this with Visual Studio 2008 until this happened. So I moved the whole project to netbeans(6.9) and MinGW.
I have configured netbeans to use OpenCV libraries as guided in this blog.
But when I run the program it gives this error " The application failed to initialize properly (0xc0150002) "
I don't think this happens when trying to read any image files from the hard disk. It gives the error without even executing 1st line in the main method.
The only change I made to the code is this.
static __inline void release_mem( CvPoint2D64f*, CvPoint2D64f*, static struct feature** );
this gave me error : storage class specified for parameter 'type name'
so I changed the code to (Trial and error rather than any logic)
static __inline void release_mem( CvPoint2D64f*, CvPoint2D64f*, struct feature** );
It is a side-by-side configuration problem. Your program contains a manifest that states what DLL it needs from the SxS cache. And Windows can't find it. Start by looking at the Windows event log, it will tell you what DLL couldn't be found.
This is more typically a VS2008 problem, its DLL version of the CRT libraries are stored in the side-by-side cache. Like msvcrt90.dll. Maybe you didn't quite manage to get the code converted to your new build environment. Which is odd, embedding the manifest is an explicit build step. Do check that you don't have a .manifest file in your build directory.
This hoopla got retired in VS2010 btw. VS2010 Express could be your 3rd attempt.
I've got a WPF app that runs perfectly fine inside VS.NET, but if I try to run it outside of VS.NET, I get a "... has encountered a problem and needs to close.." dialog. This happens in Debug and Release modes. Why is this happening?
Most likely this is an uncaught exception. You might want to try using the Application.DispatcherUnhandledException Event to display a message box with the exception to narrow down the problem:
Add this to your App.xaml as an attribute to the <Application> tag:
DispatcherUnhandledException="Application_DispatcherUnhandledException"
while the implementation of that handler might look like the following:
private void Application_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
System.Windows.MessageBox.Show(e.Exception.ToString());
}
But without much context this could be anything that is causing it and you probably have a better understanding where it comes from when looking at the exception.
Make sure that you have all libraries that your executable requires to run in the same folder as the executable, as well as any necessary configuration files or manifest files.
Have you already attempted to run the application straight from the debug/release folders? Are all of your references marked as "Copy to output directory"?
Another thing to check is that your project file is not configured to add a parameter to your application.