Frage zu Inno-Setup bzw. Warten auf Beenden von fremden Programmen



  • Hallo!

    Ich möchte ein Setup erstellen. Allerdings ist das leider nicht nur Daten auf Platte kopieren und gut - das wäre ja zu einfach. 😉

    Also, folgende Aufgaben müssen nacheinander gemacht werden und die voherige muss erfolgreich abgeschlossen sein, sonst kann ich gleich alles wieder rückgängig machen.

    1.) MSDE 2000 installieren. Setupdateien habe ich -> Fremdsetup
    2.) Script auf der MSDE ausführen
    3.) ODBC Datenquelle erstellen, falls sie nicht existiert
    4.) Mein Programm installieren

    zu 1 habe ich noch eine Frage, vielleicht weiß es ja jemand:
    Wie löse ich das, wenn es schon eine Fremdinstanz (oder eine eigene) von der MSDE gibt? 😕

    So, kann ich Inno-Setup irgendwie sagen, dass da noch ein anderes Setup im Verlauf ausgeführt werden soll oder muss ich dafür ein Programm stricken?
    Und wie merke ich, dass das Programm fertig ist mit dem was es tun sollte und ob es erfolgreich war? 😕

    Danke für Tips oder Links 🙂



  • Wow, ein Moderator benutzt das falsche Forum. 😮 👎



  • Also als aller erstes würde ich (mach ich auch so) Punkt 3 so oder so aus deinem Programm raus machen. Sind nur ein paar Zeilen Code, also nicht wirklich dramatisch.

    Was ist Inno-Setup warum nimmst du nicht Installshield for MSVC da kannste imho das alles ohne Probleme machen.



  • Inno Setup war das von der Handhabung her angenehmste und lies sehr schnell Ergebnisse sehen.
    Ist der Installshield schon bei der Standardedition dabei?

    Das zu Punkt 3 hast du für MS-SQL schon gemacht, richtig? Ist der Code komplett hier im Forum? Sonst poste ihn bitte mal. 🙂

    @comti: Von 4 Fragen ist eine nicht-MFC... 🙄



  • öhm Code poste ich nachher mal für MSSQL, nach der Mittagspause muss erst suchen. Ob das Installshield dabei ist, ich denke schon, da ich normalerweise nicht mehr wie standard hier bekomm 🙄 und ich habs drauf 😉



  • so jetzt hab ich mal gesucht. das erstellen (wirklich rein nur das erstellen) mit festen Parametern sieht bei mir so aus:

    void CACRSQLSet::CreateDSN()
    {
    	SQLConfigDataSource(NULL,
    	ODBC_ADD_SYS_DSN, 
    	"SQL Server",
    	"DSN=ACR\0"
    	"Description=ACR\0"
    	"Server=RAEDV10\0"
    	"Database=4862TRW\0"
    	);
    }
    

    Und das funktioniert auch. Das mit dem Einlesen war ein anderes Projekt, da greif ich auf Access zu: sieht dann bei mir so aus ( ich hab noch nicht aufgeräumt einen Teil davon braucht man glaub gar nicht mehr, hab aber leider grad nicht die Zeit zu schauen wo was raus kann. ich ruf aber createDSN auf, kannst also schauen was daraus aufgerufen wird

    /////////////////////////////////////////////////////////////////////////////////////
    // Subklasse hinzufügen der DSN-Attribute geschieht hier
    class CSqlConfigString : public CStringArray 
    { 
        char *m_buffer; 
        int m_iBufferSize; 
    public: 
        CSqlConfigString() 
        { 
            m_buffer = NULL; 
            m_iBufferSize = 0; 
    
        } 
        ~CSqlConfigString() 
        { 
            delete[] m_buffer; 
        } 
    
        operator const char*() { 
                AFX_MANAGE_STATE(AfxGetStaticModuleState()); 
    
            int iSize = 0; 
            for(int i=0;i<GetSize();i++) 
                iSize += GetAt(i).GetLength()+1; 
    
            if(iSize+1>m_iBufferSize) 
            { 
                       delete[] m_buffer; 
                       m_buffer = new char [iSize+1]; 
                            m_iBufferSize=iSize+1; 
            } 
    
            char *ptr = m_buffer; 
            for(int n=0;n<GetSize();n++) 
            { 
                strcpy(ptr,GetAt(n)); 
                ptr+=GetAt(n).GetLength(); 
                *ptr=0;++ptr; 
            } 
            *ptr = 0; 
            return m_buffer; 
        } 
    };
    
    //holt den Pfad von dem aus die Applikation gestartet wurde
    CString GetApplicationDirectory()
    {
       TCHAR szPathName[_MAX_PATH];
       ::GetModuleFileName(NULL, szPathName, _MAX_PATH);
       LPTSTR pszFileName = _tcsrchr(szPathName, '\\') + 1;
       *pszFileName = '\0'; return szPathName;
    }
    
    /////////////////////////////////////////////////////////////////////////////////////
    // Erzeugt/löscht eine SystemDSN / Richtet ODBC-Treiber ein
    bool CDokumentenVerwaltungSet::CreateDSN(const CString & dsnname, const CString & treibername, const CString & datei, bool add)
    {
        CString treibernamen(""); 
        CSqlConfigString dsn; 
        dsn.Add("DSN="+dsnname); 
    
    	if(datei.IsEmpty()) 
    	{ 
    		CFileDialog fileDlg( true, NULL, NULL, NULL , "DokumentenverwaltungsDatenbank (*.mdb)|*.mdb|"); 
    		if( fileDlg.DoModal ()==IDOK ) 
    		{ 
    			dsn.Add("DBQ="+fileDlg.GetPathName()); 
    			SetCurrentDirectory(GetApplicationDirectory()); 
    		} 
    		else 
    		{ 
    			return false; 
    		} 
    	} 
    	else 
    	{ 
    		dsn.Add("DBQ="+datei); 
    	} 
    	treibernamen = "Microsoft Access-Treiber (*.mdb)"; 
    
        const char* pSAttributes = (const char*)dsn; 
    
        if(add) 
        { 
            if(SQLConfigDataSource(NULL, ODBC_ADD_SYS_DSN,treibernamen,pSAttributes) == 0) return false; 
    
        } 
        else 
        { 
            if(SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN,treibernamen,pSAttributes) == 0) return false; 
        } 
        return true; 
    }
    


  • Danke!

    Sobald ich an meine Dateien komme, teste ich das mal. 🙂



  • falls was nicht geht musst dich halt noml melden!
    gern geschehen!
    😉



  • *meld* 😞

    RETCODE retcode;
    		CString szDriver = "SQL Server";
    		CString szAttributes =
    			"DSN=audiodatic\0DESCRIPTION=Audiodatic 3 Datenbank\0"
    			"SERVER=(local)\0ADDRESS=(local)\0NETWORK=OPP\0"
    			"DATABASE=ad3\0";
    		retcode = SQLConfigDataSource(NULL,
    			ODBC_ADD_DSN,
    			szDriver,
    			szAttributes);
    		ASSERT(retcode != ODBC_ERROR_GENERAL_ERR);
    		ASSERT(retcode != ODBC_ERROR_INVALID_HWND);
    		ASSERT(retcode != ODBC_ERROR_INVALID_REQUEST_TYPE);
    		ASSERT(retcode != ODBC_ERROR_INVALID_NAME);
    		ASSERT(retcode != ODBC_ERROR_INVALID_KEYWORD_VALUE);
    		ASSERT(retcode != ODBC_ERROR_REQUEST_FAILED);
    // 		ASSERT(retcode != ODBC_ERROR_LOAD_LIBRARY_FAILED);
    		ASSERT(retcode != ODBC_ERROR_OUT_OF_MEM);
    

    Es schlägt keiner der ASSERTs an, keine Exception fliegt - aber nix passiert. 😕

    Ich hab keine Ahnung mehr, wo ich suchen soll. 😞



  • Lies dir nochmal die Dokumentation durch. Mit dem Error-Code hast du was völlig falsch gemacht. Die Funktion kann nur TRUE oder FALSE zurück geben. Den Error Code bekommst du über ne andere Funktion.



  • Ups, das läßt sich aber leicht überlesen... ich versuchs mal. 🙂

    Edit: Wie funktioniert die Funktion? Ich kriege es nicht hin. 😞
    Entweder kriege ich keine Rückmeldung - oder mir fliegt ne Exception um die Ohren. 😞



  • Kennt hier keiner die Funktionen? 😞



  • So ich war gestern leider nicht da, aber heute dafür wieder voll und ganz. ich glaube du suchst folgendes:

    Diagnostics

    When ConfigDSN returns FALSE, an associated *pfErrorCode value is posted to the installer error buffer by a call to SQLPostInstallerError, and may be obtained by calling SQLInstallerError. The following table lists the *pfErrorCode values that can be returned by SQLInstallerError and explains each one in the context of this function.

    und schaut man sich dann mal die genannten FKTs an so erfährt man:

    Summary

    SQLInstallerError returns error or status information for the ODBC installer functions.

    und so weiter schau am besten mal selbst in die MSDN am besten findest du es wenn du direkt auf sqlconfigdatasource F1 drückst und dann die ODBC Help aufmachst. da findest du den Teil Diagnostic den ich oben zitiert hab, und noch ein wenig mehr zu den Fehlern. die Funktionen kannst du direkt in das IndexSuchfeld eingeben und solltest dann direkt zu der Stelle kommen.

    Nochmal zum eigentlichen Problem; Wenn schlicht weg nichts passiert, muss es nicht zwingend ein Fehler sein! Schau mal nach ob die ODBC-DSN schon besteht mit dem Namen, dann erstellt er ja auch keine, wie ich im ersten beitrag geschrieben hab, der gepostete Code ist rein nur fürs erstellen der DSN er überprüft nicht ob eine besteht ...



  • Ich habe die DSN extra umbenannt, es gibt sie also nicht und sie wird auch nicht erstellt. 😞

    Das aus der MSDN habe ich gelesen aber nicht anwenden können. 😞

    try
    	{
    		CString szDriver = "SQL Server";
    		CSqlConfigString arrAttributes;
    		arrAttributes.Add("DSN=audiodatic");
    		arrAttributes.Add("DESCRIPTION=Audiodatic 3 Datenbank");
    		arrAttributes.Add("SERVER=BOECKHOFF-OPP");
    // 		arrAttributes.Add("ADDRESS=(local)");
    // 		arrAttributes.Add("NETWORK=BOECKHOFF-OPP");
    		arrAttributes.Add("DATABASE=ad3");
    		arrAttributes.Add("UID=sa");
    		arrAttributes.Add("PWD=manager");
    		if (!SQLConfigDataSource(NULL, ODBC_ADD_DSN, szDriver, arrAttributes))
    		{
    			 DWORD     pfErrorCode;
    			 LPSTR     lpszErrorMsg;
    			 WORD     pcbErrorMsg;
    		RETCODE retcode = SQLInstallerError(1,&pfErrorCode,lpszErrorMsg,SQL_MAX_MESSAGE_LENGTH -2,&pcbErrorMsg);
    
    		ASSERT(retcode != ODBC_ERROR_GENERAL_ERR);
    		ASSERT(retcode != ODBC_ERROR_INVALID_HWND);
    		ASSERT(retcode != ODBC_ERROR_INVALID_REQUEST_TYPE);
    		ASSERT(retcode != ODBC_ERROR_INVALID_NAME);
    		ASSERT(retcode != ODBC_ERROR_INVALID_KEYWORD_VALUE);
    		ASSERT(retcode != ODBC_ERROR_REQUEST_FAILED);
    // 		ASSERT(retcode != ODBC_ERROR_LOAD_LIBRARY_FAILED);
    		ASSERT(retcode != ODBC_ERROR_OUT_OF_MEM);
    		}
    	}
    	catch (CDBException* p)
    	{
    		p->Delete();
    	}
    

    So weit hab ich es irgendwie geschafft, aber selbst die Fehlerdiagnose klappt nicht. 😞

    Achja:
    (Edit) Was muss man fangen, wenn SQLInstallerError was wirft?



  • deine Asserts können ja gar nicht anschalgen!

    Returns

    SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, or SQL_ERROR.

    So jetzt zäumen wir mal das Pferd von hinten auf! Jetzt versuchen wir mal einfach eine DSN einzurichten die nichts kann, dann eine die den Server kennt, dann eine die dazu noch user und PWD kennt ...

    fang so an:

    void DEINE::CreateDSN()
    {
        SQLConfigDataSource(NULL,
        ODBC_ADD_SYS_DSN, 
        "SQL Server",
        "DSN=audiodactic\0"
        );
    }
    

    führe die Funktion aus und schau ob du eine DSN bekommst, dann mach weiter, und versuch ne Description im gleichen Stil mit ein zu bringen . . .
    Denk dran die DSN immer wieder zu löschen oder umzubenennen.
    Wenn du willst darfst es mir auch gerne schicken und ich schau mal ob ich es dir rein basteln kann.

    Achja zu deinem Edit SQLInstallerError wirft gar nichts selbst!!
    Lies hierzu die Diagnostic.



  • So, aktueller Stand:
    Ich kriege die Datenquelle erstellt. Man darf User und Passwort nicht mit angeben. 🙄
    Danke für den Wink mit dem "klein anfangen" - das war das berühmte Brett vorm Kopf.

    Jetzt sind aber trotzdem noch ein paar Fragen offen:
    Wie finde ich raus, ob eine ODBC Datenquelle schon mit den korrekten Parametern existiert?
    Oder ist es allgemein üblich, die brutal zu löschen?

    Der Rest ist dann wohl eher direktes MS-SQL Kram, da ich noch herausfinden muss, ob meine DB schon existiert.
    Und erstellen/löschen muss ich auch noch irgendwie hinbekommen. 🙄

    Edit: Wie kriege ich die Fehlermeldungen vom ODBC-Treiber auf Deutsch?



  • also brutales löschen geht! Hab es selbst noch nicht gemacht sollte aber so gehen:

    //nicht getestet
    void DEINE::DeleteDSN()
    {
        SQLConfigDataSource(NULL,
        ODBC_REMOVE_SYS_DSN, 
        "SQL Server",
        "DSN=audiodactic\0"
        );
    }
    

    Wie du die meldung auf deutsch bekommst kann ich dir leider nicht sage, weiß ich nicht!
    Dementsprechen ginge auch configurieren mit
    ODBC_CONFIG_SYS_DSN



  • Hast du das Projekt bekommen? Hast du auch den Linkerfehler? 😕
    Mich interessiert wirklich, wo der herkommt.

    So, falls das nochmal jemand braucht, ich habe das mittlerweile so:

    try
    	{
    		try
    		{
    			m_dbAd.OpenEx("DSN=dsn_name;UID=sa;PWD=sa-pwd", CDatabase::noOdbcDialog);
    		}
    		catch (CDBException* p)
    		{
    			CString szDriver = "SQL Server";
    
    			CSqlConfigString arrAttributes;
    			arrAttributes.Add("DSN=dsn_name");
    			arrAttributes.Add("DESCRIPTION=Meine Datenbank");
    			arrAttributes.Add("SERVER=(local)");
    	// 		arrAttributes.Add("ADDRESS=(local)");
    	// 		arrAttributes.Add("NETWORK=pc_name");
    			arrAttributes.Add("DATABASE=db_name");
    	// 		arrAttributes.Add("UID=sa");
    	// 		arrAttributes.Add("PWD=sa-pwd");
    
    			// Sicherheitshalber löschen:
    			SQLConfigDataSource(NULL, ODBC_REMOVE_DSN, szDriver, arrAttributes);
    
    			// Jetzt erstellen
    			if (SQLConfigDataSource(NULL, ODBC_ADD_DSN, szDriver, arrAttributes))
    			{
    				m_dbAd.OpenEx("DSN=dsn_name;UID=sa;PWD=sa-pwd", CDatabase::noOdbcDialog);
    			}
    			else
    			{
    				p->ReportError();
    				p->Delete();
    				AfxMessageBox(_T("Die Verbindung zur Datenbank konnte nicht erstellt werden.\nDas Programm wird beendet."));
    				return FALSE;
    			}
    			p->Delete();
    		}
    	}
    	catch (CDBException* p)
    	{
    		p->ReportError();
    		AfxMessageBox(_T("Die Verbindung zur Datenbank konnte nicht erstellt werden.\nDas Programm wird beendet."));
    		p->Delete();
    	}
    	catch (CMemoryException* p)
    	{
    		p->ReportError();
    		AfxMessageBox(_T("Die Verbindung zur Datenbank konnte nicht erstellt werden.\nDas Programm wird beendet."));
    		p->Delete();
    	}
    	catch (...)
    	{
    		AfxMessageBox(_T("Die Verbindung zur Datenbank konnte nicht erstellt werden.\nDas Programm wird beendet."));
    	}
    

    Ich versuche also, mich anzumelden, wenn das nicht geht, lösche ich eine eventuell falsche DSN und lege dann den richtigen an und verbinde mich nochmal.
    Wenn das immernoch nicht geht wird das Programm beendet.



  • Linker Fehler hatte ich dir geschrieben

    Polofreak in E-Mail schrieb:

    #include <odbcinst.h>
    denke das brauchst du noch!!

    versuchs mal ich denke da kommt es her!



  • Auf die Mail hab ich schon geantwortet - mit Projekt im Anhang.
    Den Include habe ich, den Linkerfehler trotzdem. 😕

    Include vergessen: Meckert wegen "nichtdeklarierter Bezeichner".
    Unaufgelöstes externes Symbol ist eher ein Dll/Lib Fehler.
    ...dachte ich bisher. 🙂



  • wie hast du das Project geschickt? bitte Raren wir haben hier eine sch** Firewall die nach Sicherheitsrichtlinien alles mögliche Filtert wenn ZIP dann Bitte mit PWD
    Security Policies! 🙄


Anmelden zum Antworten