[(V)C++(/QT)] Foutmelding 0xc0150002 bij uitvoeren

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Rygir
  • Registratie: Mei 2004
  • Laatst online: 01-03 05:45
Heel, heel kort wat ik voor heb gehad : Release build uitvoeren op niet-ontwikkel PC geeft de foutmelding 0xc0150002

Ik zal er maar direct bij zeggen dat ik het alsnog aan de praat heb gekregen maar ik ben allerminst blij met de manier waarop. Daarom wil ik hier het hele verhaal voorleggen aan mensen die deskundiger zijn terzake dan mijzelf, misschien dat daar een elegantere oplossing of op zijn minst een verklaring uit voortkomt.

Om te beginnen, ik heb een C++ project gemaakt met Visual Studio (2005, maar ook 2008) en ik wilde dat nu even "snel" op een willekeurige PC uitvoeren. Viel dat even tegen. Ik was er al op voorbereid dat ik dependency problemen kon tegenkomen, daar er gebruik wordt gemaakt van Irrlicht, QT threads en winsock en verder vooral STL. Als ik dit dus wil runnen moet er sowieso de QTcore4 dll bij en de Irrlicht dll en ik dacht misschien ook iets voor winsock maar dat blijkt gelukkig niet het geval, nu achteraf bekeken.
Ik had er zelfs aan gedacht om in release mode te builden ;) .

Als je dit ooit al eens zelf hebt geprobeerd dan weet je dat C++ projecten die met Visual Studio gecompileerd zijn vereisen dat je de VCredist (Visual studio C redistributable) moet installeren, want anders krijg je volgende geweldig behulpzame foutmelding (ik was het weer vergeten dus ik kwam hem direct tegen) :
---------------------------
iWorld.exe
---------------------------
iWorld.exe

De toepassing kan niet worden gestart omdat de configuratie van de toepassing onjuist is. Het opnieuw installeren van de toepassing kan dit probleem oplossen.
---------------------------
OK
---------------------------

Als je daar informatie over opzoekt op Google dan weet men je te vertellen dat dat waarschijnlijk is omdat je dependencies mist en dat je in je manifest file kan gaan kijken welke dat zijn als je "niet de moeite wilt nemen om te leren hoe je installers moet maken" |:( (persoonlijk vond ik dat een arrogante attitude, waarom moet alles via een installer? Ik prefereer nog altijd 'portable' applicaties - hij had het ook over merge modules, wat dat zijn weet ik dan weer niet). Sowieso weet je dus absoluut niet welke depency hij nu eigenlijk mist en ook Windows zelf is dus al van het gedacht dat een applicatie gewoon kopiëren of uitpakken uit een zipje op één of andere manier minderwaardig is ten opzichte van installeren. Moest ik een installer maken dan zou ik ook NSIS verkiezen en in dat geval moet ik nog altijd weten wat dat ding precies doet, het is niet omdat het geautomatiseerd is dat je niet moet weten wat er gebeurd... }:O

Daar komt nog bij dat ik eerst de verkeerde vcredist had genomen omdat er blijkbaar eentje is voor de SP1 en eentje zonder SP1 van Visual Studio 2005. En dat maakt het nog ingewikkelder want ik heb SP1 niet op alle development machines geïnstalleerd en de ene vcredist installeren deïnstalleert de andere kan ik u nu vertellen.

Ik was zo blij als een kind :> toen ik toch tenminste een vensterkader zag verschijnen eenmaal ik al mijn dlls bij elkaar had verzameld in de programma map en de vcredist_80 geïnstalleerd was, maar dat was maar 1 frame van geluk want het volgende moment stond volgende foutmelding me aan te staren :
---------------------------
iWorld.exe - Toepassingsfout
---------------------------
Kan de toepassing niet juist initialiseren (0xc0150002). Klik op OK om de toepassing te beëindigen.
---------------------------
OK
---------------------------

Toen begon de miserie pas :F , die VCredist was mijn eigen fout dat ik er niet sneller aan had gedacht, maar deze foutmelding leidt naar vreemde onderwerpen zoals Office 2003 dat geïnstalleerd wordt op een PC die van SP1a naar SP2 wordt geupgrade en dat daar iets mis bij gaat en je je service pack moet herinstalleren. Eerst en vooral staat er SP3 op die PCs, ten tweede had het niks met office te maken want dat staat er niet op. Andere oplossingen als je op de foutcode alleen zoekt en niet het hele bericht gaan over explorer.exe dat niet zou starten en dergelijke, allemaal niet relevant. Dus die foutmelding kon Google niet direct mee helpen in ieder geval. Omdat ik me nu toch wel begon af te vragen welke depency ik nog kon missen (voor de rest werkt dat programma op de development PCs, ik had zo direct geen andere verklaring voor een foutmelding) heb ik dan even Hello World gemaakt in de vorm van "main(){}", al dan niet met wat cout en system("pause") naar smaak toegevoegd. Dat werkte... Ja dan zal het toch Irrlicht of QT zijn of misschien Winsock, want de rest is allemaal STL en puur C++, dacht ik toen. Ok, ik bouw een hello world met irrlicht (een modelletje inladen en tonen)... dat werkt prima. Natuurlijk moet je dan weer door dezelfde hell gaan van het opzetten van een project waarbij je alle include directories en dergelijk moet bij elkaar zoeken, ik weet niet wat jullie daarvan vinden, maar bij VS C++ vind ik dat een ramp. Bij Java in Eclipse is dat ff klik klik 1 directorietje toevoegen, bij VS C# en VB.NET is het even simpel, maar VC++... daar zit je met 3 of 4 plekken waar je libs moet koppelen, include directories moet toevoegen, en dan moet je nog code toevoegen vaak ook om maar te kunnen beginnen. Kortom, een hoop tijdverlies. Vermits Irrlicht werkt, dan maar QT geprobeerd. Weer een threadje gemaakt en gestart, weer dezelfde komedie van libs includen (ook al staan die al op je path omgevingsvariabele nota bene). En ook dat werkte! Ja zeg, dan schiet enkel nog winsock over? Dus ja, ik registreer een listener, ik verstuur wat UDP packets... en na een berg linker errors merk ik dat ik ook daar de winsock lib weer ben vergeten te includen. En... jawel, ook dat runt nog steeds op die andere PCs. Om een lang verhaal lang te maken : Nu had ik alle componenten gebruikt die mijn volledige project ook gebruikte en het ene werkt en het andere niet. Ja goed, zit er niets anders op dan code te schrappen uit het project totdat het werkt. Gewoon even begonnen met een lege main door alles in commentaar te gooien, en jawel, dat werkte. Zo stukje bij beetje code toegevoegd tot ik het probleem geisoleerd had : Zodra ik QMutex en QWaitCondition gebruikte was het om zeep... kleine ramp want daarzonder is heel het ding niet meer threadsafe natuurlijk! 8)7

Logische conclusie die ik daar uit haalde was : Dump de hele /bin directory van QT dan maar bij het programma. Maar helaas, 200MB aan dll's later was ik geen stap verder. Nog steeds diezelfde foutmelding. Toen maar eens gaan googlen op QMutex en de foutmelding, wat 2 resultaten geeft en die wijzen toch wel zeker niet opnieuw naar VCredist. Ja zeg, die staat er op nu! . Daar stond een link bij naar MSDN waar nu toevallig eens wel een uitleg stond over hoe je een applicatie kan deployen op andere machines zonder een installer te bouwen of VCredist te installeren, namelijk zoals ik het steeds doe door gewoon alle dependencies in de vorm van dll's er bij te zetten in dezelfde map. En belangrijker : er stond bij waar je vcredist op je lokale ontwikkelmachine kan vinden... dus ik al die dlls in die submap van visual studio aan't kopiëren die onder de installatiemap van visual studio in \VC\redist\x86 stonden. Helaas, pindakaas, geen verandering. Maar ik zag daar ook nog het mapje non-redist staan blinken, met daarin de *d.dll's, dus de debug versies. Waarom niet, die er ook even bij gezwierd... en het werkt :9~ . Het werkt! Dat was dus de oplossing :*) .

Laat dat even tot je doordringen : Dat wil zeggen dat als je QMutex gebruikt, QT iets doet, waardoor je de debug libraries moet hebben. Had ik nu gedaan waar iedereen "op google" zo op hamert, namelijk gewoon een installer genereren dan had die dat misschien uitgevogeld en in stilte debug libraries zitten includen en dan werkte dat allemaal prima maar ondertussen wordt iedereen opgezadeld met overbodige dll's. Dat vind ik persoonlijk niet kunnen... :/

Kan iemand me verklaren waardoor dat veroorzaakt wordt? Mij lijkt het een bug? Ik ga het nog eens benadrukken, ik heb wel zeker gebuild in release mode. Als ik in debug mode compileerde werkte het nog steeds niet (ok nu misschien wel nu ik echt alle dll's er bij heb gedumpt - dat heb ik niet getest, maar dan werkte de versie zonder QMutex ook niet bedoel ik). Dat ik alsnog de debug versies van dll's nodig heb lijkt me niet de bedoeling.

Als je een motivatie zoekt waarom ik toch geen installer wil maken : Omdat dit project een soort van "mmo" basis is of fancy chat met 3D als je het zo wilt bekijken wil ik het testen op een machine of 10 tegelijk zodat ik tenminste de aanpak kan verifiëren. Ik ga daar echt niet overal Visual Studio op installeren en vermits ik om de 5 seconden aanpassingen maak en hercompileer wil ik het liever van een netwerkshare runnen dan packagen en herinstalleren iedere keer. Nu moet ik enkel nog de .Exe vervangen in die map en hop het werkt. En dat zonder dat ik een hoop rommel achterlaat op de machines waarop ik het uitvoer nadien, gewoon de map verwijderen en klaar.

Is het zo raar om gewoon even je debug exe te willen runnen op een boel machines? Dat zou toch vrij eenvoudig moeten zijn om gewoon je tussentijdse resultaten even bijeen te rapen en te runnen op andere machines zonder dat je direct ontwikkelomgevingen moet installeren...? Ik vind het vrij triestig dat ik nergens een gids ben tegengekomen die me zei welke dll's ik moest hebben om debug versies te runnen, noch dat de foutmelding wees op het vereisen van die dll's. Nu ben je eigenlijk verplicht om nog een keer extra te compileren. En dat allemaal omdat Visual Studio depencies veroorzaakt waardoor gewoon het bijvoegen van de debug dll's van QT en irrlicht niet voldoende is.

Ook wil ik graag weten waarom het nu nodig is dat als je pakweg "main(){}" compileert en runnen wilt dat daar absoluut die VC++ redistributable voor nodig zijn, is dat nu echt onmogelijk om in deze tijd nog iets te programmeren dat niet al van in het begin met een zwerm dependencies is opgezadeld? De java VM, .NET, enz... daar zie ik nog ergens de logica van in, maar het moet toch mogelijk zijn om puur C++ rechtstreeks naar standalone executable te compileren? Hoe maak je daar anders een OS mee? Ik hoop half en half dat ik daarvoor enkel iets moet veranderen in de opties van het VS project... O-)

PS : Is er trouwens een tag in verband met het "deployen" of "uitrollen" van applicaties naar "gebruikersmachines" of iets dergelijks?
PS 2 : Mijn excuses dat ik mijn ergernissen hier kom ventileren, hoop dat mijn gemoedstoestand de boodschap niet vertroebeld heeft.
PS 3 : Bedankt voor wie de tijd neemt om het hele bericht te lezen O+

Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

Makkelijke oplossing: maak een installer.
Moeilijke oplossing: zoek alle dependecies en hun dependencies, en kopieer die mee. Daarbij moet je alleen niet-systeem dependencies kopieren (bijvoorbeeld: alle applicaties hebben een dependency op kernel32.dll, maar die moet je dus niet meekopieren).

Als vuistregel, alles in de Windows SDK zit in systeembestanden, en de DLL's daarvan zijn op alle systemen aanwezig (bijvoorbeeld de door jou genoemde winsock valt daaronder).

Je kan de MSVC runtime elimineren door alle projecten te compileren met /MT inplaats van /MD, dan linkt hij de CRT statisch (in jouw .exe dus), en heb je geen VCredist nodig. Als 1 van je dependencies nog wel op de VC redist depend, lost dit natuurlijk niks op, dit is een per-project setting.

Ook raad ik je aan om nooit debug DLL's te distribueren (ik geloof dat je die van de VC runtime niet eens MAG distribueren), release enkel release DLL's (zie je hoe die woorden overeenkomen? :P)

Die merge modules zijn een side-effect van SxS, dat er (erg simpel uitgelegd) voor zorgt dat je meerdere DLL's met dezelfde naam kan hebben in je systeem. Dit is de oplossing van DLL-hell zoals bedacht door MS (in hoeverre dit geen hel is, wil ik van af zijn, maar dit werkt wel, als je weet hoe het systeem werkt).

Je kan voor meer uitleg eens zoeken op SxS (side-by-side) op google, er zijn best goede artikelen over te vinden.

[ Voor 18% gewijzigd door MLM op 26-04-2010 08:47 ]

-niks-


Acties:
  • 0 Henk 'm!

  • NC83
  • Registratie: Juni 2007
  • Laatst online: 21-08 21:44
En anders is depends.exe ook een goeie tool om uit te vinden welke dlls nodig zijn tool kun je vinden in ..\Microsoft Visual Studio 8\Common7\Tools\Bin\

Dependancy walker is depends.exe trouwens

[ Voor 12% gewijzigd door NC83 op 26-04-2010 12:13 ]

ex-FE Programmer: CMR:DiRT2,DiRT 3, DiRT Showdown, GRID 2, Mad Max


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

NC83 schreef op maandag 26 april 2010 @ 09:30:
En anders is depends.exe ook een goeie tool om uit te vinden welke dlls nodig zijn tool kun je vinden in ..\Microsoft Visual Studio 8\Common7\Tools\Bin\
Ik gebruik altijd "dependency walker". Let ook op 32 vs 64 bit DLLs... en delay-loaded DLLs, die zijn soms niet aanwezig, maar dat geeft niet als je ze niet gebruikt. 64-bit Windows 7 mist bijvoorbeeld zelf een aantal 64 bit system (delay-loaded) DLLs, dus elke app geeft zo'n beetje dependency errors.

Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

Zoijar schreef op maandag 26 april 2010 @ 11:14:
[...]

Ik gebruik altijd "dependency walker". Let ook op 32 vs 64 bit DLLs... en delay-loaded DLLs, die zijn soms niet aanwezig, maar dat geeft niet als je ze niet gebruikt. 64-bit Windows 7 mist bijvoorbeeld zelf een aantal 64 bit system (delay-loaded) DLLs, dus elke app geeft zo'n beetje dependency errors.
Is exact hetzelfde programma. Je kan hem ook krijgen van http://www.dependencywalker.com/ mocht je hem nog niet hebben op je PC.

-niks-


Acties:
  • 0 Henk 'm!

  • Rygir
  • Registratie: Mei 2004
  • Laatst online: 01-03 05:45
MLM schreef op maandag 26 april 2010 @ 08:44:
Makkelijke oplossing: maak een installer.
Dat camoufleert het probleem enkel, hij blijft dependencies houden die niet horen dan, je merkt het alleen niet.

En functioneel : Dat zou verhinderen dat ik het resultaat portable gebruik, specifiek in combinatie met liveCDs, dan zou ik die installer al in de liveCD moeten inbakken etc. Niet handig.
Moeilijke oplossing: zoek alle dependecies en hun dependencies, en kopieer die mee. Daarbij moet je alleen niet-systeem dependencies kopieren (bijvoorbeeld: alle applicaties hebben een dependency op kernel32.dll, maar die moet je dus niet meekopieren).
Daar had ik dus last mee omdat ik nog nooit van dependency walker had gehoord, dus dat moet ik zeker bestuderen.

Kernel32 ken ik nu bvb ook, maar is er een manier om te onderscheiden wat een "systeem" dependency is en wat niet? Dus wat standaard in windows zit en wat niet? Handmatig zoeken naar de bestanden?
Als vuistregel, alles in de Windows SDK zit in systeembestanden, en de DLL's daarvan zijn op alle systemen aanwezig (bijvoorbeeld de door jou genoemde winsock valt daaronder).
Dit zal wel een "stomme vraag" zijn, maar de Windows SDK waar jij het over hebt, ik veronderstel dat dat onderdeel is van Visual Studio? Hoe kan ik die SDK bekijken, voor te weten wat daar in zit?
Je kan de MSVC runtime elimineren door alle projecten te compileren met /MT inplaats van /MD, dan linkt hij de CRT statisch (in jouw .exe dus), en heb je geen VCredist nodig. Als 1 van je dependencies nog wel op de VC redist depend, lost dit natuurlijk niks op, dit is een per-project setting.
Interessant, maar dan pakt hij de noodzakelijke redist elementen dus mee in de exe... moet ik me dat dan voorstellen als dat hij pakweg de STL libraries include in de exe en zitten die anders in de DLLs?

Pak nu
code:
1
main(){}
, als ik dat compileer met iets anders dan visual studio dan heeft dat bij mijn weten geen dependencies? Dan is dat gewoon een standalone executable of vergis ik me daarin? Ik bedoel, ik heb nog nooit van een GCCredistributable gehoord maar misschien ligt dat aan mij? Maar Visual Studio vertikt het om dit uit te voeren zonder vcredist kennelijk. Wat heeft die dan nodig daaruit?
Ook raad ik je aan om nooit debug DLL's te distribueren (ik geloof dat je die van de VC runtime niet eens MAG distribueren), release enkel release DLL's (zie je hoe die woorden overeenkomen? :P)
Grapjas :p dat is de hele reden dat ik dit topic heb gestart, voelde me vuil en vies van al die *d.dll bestanden te kopiëren ;) . Denk trouwens ook dat dat tegen de EULA van het een of het ander zou zijn kunnen maar voor hier even tussentijds te testen is dat geen ramp.

In ieder geval, het probleem is dus letterlijk dat ik een release build doe en hij niet wil starten zonder de debug dll's. Dat zou geen probleem mogen zijn, en zonder QMutex te gebruiken is het dat ook niet.
Die merge modules zijn een side-effect van SxS, dat er (erg simpel uitgelegd) voor zorgt dat je meerdere DLL's met dezelfde naam kan hebben in je systeem. Dit is de oplossing van DLL-hell zoals bedacht door MS (in hoeverre dit geen hel is, wil ik van af zijn, maar dit werkt wel, als je weet hoe het systeem werkt).

Je kan voor meer uitleg eens zoeken op SxS (side-by-side) op google, er zijn best goede artikelen over te vinden.
Aha, bedankt! Dat zou dus meer een oplossing moeten zijn voor als je een versie conflict hebt met dlls...wat hier zich niet kan voordoen gelukkig.

Acties:
  • 0 Henk 'm!

  • Rygir
  • Registratie: Mei 2004
  • Laatst online: 01-03 05:45
NC83 schreef op maandag 26 april 2010 @ 09:30:
En anders is depends.exe ook een goeie tool om uit te vinden welke dlls nodig zijn tool kun je vinden in ..\Microsoft Visual Studio 8\Common7\Tools\Bin\

Dependancy walker is depends.exe trouwens
Goh...een wereld gaat voor me open :D
Wat doen al die progjes daar en waarom zijn er geen snelkoppelingen naar vanuit het start menu gemaakt (niet om flauw te klinken maar het is nooit in me opgekomen om in submappen naar tools te gaan zoeken;))! Dat is toch echt essentieel gereedschap wat daar staat :D

Ik heb met dependency walker het ding nu eens geopend en het bevestigd wat ik vandaag hebt ontdekt, namelijk dat in de releasebuild een debug versie van een qtlib werd gebruikt, waardoor hij de QT debug dll gebruikt en die wil dan natuurlijk ook de debug versies van de andere dlls. Sterk dat hij voor threads daar geen last van heeft, enkel mutexen. Als ik die lib in de debug versie nu aanpas zal het wel in orde zijn, die was ik volledig vergeten met al die dll's elders.

Het eerste niveau, dus zonder een op een plusje te klikken simpel gezegd, in Dependency Walker zijn alle dependencies waar je zelf controle over hebt, als ik het goed begrepen heb?

Acties:
  • 0 Henk 'm!

  • Rygir
  • Registratie: Mei 2004
  • Laatst online: 01-03 05:45
Zoijar schreef op maandag 26 april 2010 @ 11:14:
[...]

Ik gebruik altijd "dependency walker". Let ook op 32 vs 64 bit DLLs... en delay-loaded DLLs, die zijn soms niet aanwezig, maar dat geeft niet als je ze niet gebruikt. 64-bit Windows 7 mist bijvoorbeeld zelf een aantal 64 bit system (delay-loaded) DLLs, dus elke app geeft zo'n beetje dependency errors.
Ja dat merkte ik net toen ik toen ik een paar exe's probeerde, dat noemt hij warnings en zo heeft hij er praktisch bij elke exe wel een paar... als die optioneel zijn, wat is het nut er dan van?

Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Rygir schreef op donderdag 29 april 2010 @ 18:42:
[...]

Ja dat merkte ik net toen ik toen ik een paar exe's probeerde, dat noemt hij warnings en zo heeft hij er praktisch bij elke exe wel een paar... als die optioneel zijn, wat is het nut er dan van?
Omdat je app crashed als hij die functionaliteit wel gebruikt, maar zolang die functies niet gebruikt worden hoeft de DLL niet geladen te worden en werkt het prima.
Pagina: 1