Laden...

Profil von Hurby

myCSharp.de - Member Mitglied seit

Alle Beiträge

So... Die Exception hat keine InnerException. Der Vollständigkeit halber hier mal die Details der Ausnahme:

Fehlermeldung:
message: Unable to update database to match the current model because there are pending changes and automatic migration is disabled. Either write the pending model changes to a code-based migration or enable automatic migration. Set DbMigrationsConfiguration.AutomaticMigrationsEnabled to true to enable automatic migration.

stacktrace: bei System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable1 pendingMigrations, String targetMigrationId, String lastMigrationId) bei System.Data.Entity.Migrations.DbMigrator.UpdateInternal(String targetMigration) bei System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase) bei System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration) bei System.Data.Entity.MigrateDatabaseToLatestVersion2.InitializeDatabase(TContext context)
bei System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action)
bei System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization()
bei System.Data.Entity.Internal.RetryAction1.PerformAction(TInput input) bei System.Data.Entity.Internal.LazyInternalContext.InitializeDatabaseAction(Action1 action)
bei System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
bei System.Data.Entity.Internal.Linq.InternalSet1.Initialize() bei System.Data.Entity.Internal.Linq.InternalSet1.get_InternalContext()
bei System.Data.Entity.Infrastructure.DbQuery1.System.Linq.IQueryable.get_Provider() bei System.Linq.Queryable.Where[TSource](IQueryable1 source, Expression`1 predicate)

source: EntityFramework

Mittlerweile habe ich keine Idee mehr, wo ich noch ansetzen könnte.

Hallo Abt,

das Schema ist bei allen identisch. Alle greifen auf dieselbe Datenbank zu. Die Datenbank-Anmeldung ist an eine Active-Directory-Gruppe gekoppelt, in der die entsprechenden Benutzer Mitglied sind. Gegenwärtig verfüge ich nur über den entsprechenden Eintrag des Windows-Ereignisprotokolls. Ich werde mich mal um die InnerException bemühen...

Hallo,

in meiner Anwendung (basierend auf EF6 und NET4.5) verwende ich als Strategie Code-First mit Code-based Migration und MigrateDatabaseToLatestVersion als Initialisierer. Einer meiner Kunden berichtete mir nun kürzlich nach dem Einspielen eines Updates, dass beim Start eine AutomaticMigrationsDisabledException geworfen wird. Merkwürdigerweise aber nur auf 2 Arbeitsstationen. Andere Anwender haben dieses Problem nicht.

Um dem Ganzen auf die Schliche zu kommen, habe ich AutomaticMigrations aktiviert um EF ausführen zu lassen, was auch immer es ausführen möchte. Nachdem dies geschehen ist, habe ich den entsprechenden Eintrag aus der Tabelle "__MigrationHistory" genommen und aus der model-Spalte ein Entity Data Model (EDMX) generiert. Darin habe ich gesehen, dass das Entity Framework aus einer 1:1 - Beziehung (EDMX : Multiplicity="1") eine optionale Beziehung (EDMX : Multiplicity="0..1") machen will. Die Property meiner Klasse, auf welcher diese Beziehung beruht ist eine einfache GUID (nicht nullbar). Somit ergibt eine optionale Beziehung wie sie erstellt werden soll keinen sinn. Das merkwürdigste ist aber, dass das Problem lediglich auf 2 Arbeitsplätzen auftritt. Glücklicherweise sind dies die Arbeitsplätze der beiden Administratoren und werden somit auch nur zu administrativen zwecken genutzt. Dennoch muss das Problem gelöst werden. Hat jemand bereits ein ähnliches Problem gehabt oder eine Idee wo ich noch ansetzen könnte?

MfG Hurby

Erstmal Danke für eure schnellen und konstruktiven Antworten. Dass mir eine entsprechend große Abfrage nicht in die Tüte kommt war vielleicht etwas vorschnell. Wenn es tatsächlich keine anderen Lösungen gibt, welche sich mit überschaubarem Aufwand umsetzen lassen, werde ich diesen Lösungsansatz doch näher in Betracht ziehen. Zumal, wie ihr schon festgehalten habt, die Cleverness des SQL-Servers dort voll zur Geltung kommt.

Ich lasse den Thread mal noch offen. Vielleicht kommt ja doch noch Jemand mit einer völlig anderen Lösung um die Ecke.

Euch 3 wünsche ich auf jeden Fall erstmal ein schönes Wochenende

Hallo,

ich muss in einer Anwendung eine Recherche-Funktion programmieren. Diese sieht bis jetzt so aus, dass der Benutzer aus einer Liste von verfügbaren Datenfeldern mehrere auswählen kann. Zu jedem ausgewählten Datenfeld wird eine Vergleichsmethode und ein Vergleichswert angegeben.
Am Ende kommt also eine Liste von Konditionen heraus, welche durch jeden Datensatz zu erfüllen sind. Nun stehe ich vor dem Problem, diese Konditionen entsprechend zu prüfen. Aus allen Konditionen eine riesige (und dreckige) Abfrage zu basteln kommt mir nicht in die Tüte. Alle Datensätze einzulesen und dann im Programm auszuwerten halte ich aufgrund der Datenmenge auch eher für suboptimal. Ich bräuchte viel mehr eine Möglichkeit, die Konditionen in Abfragen umzuwandeln und nacheinander auszuführen. Wobei die erste den Inhalt der kompletten Tabelle auswertet und jede weitere nur das Ergebnis der vorherigen Abfrage verwenden sollte.

Ich weiß, dass es im SQL-Server sogenannte "Common Table Expressions" gibt, welche eine rekursive Abfrage erlauben. Allerdings müsste diese bei jedem Durchlauf die nächste Kondition verarbeiten. Leider weiß ich nicht, wie ich dieses Problem bewerkstelligen soll.

Hat Jemand eine zündende Idee (gerne auch in Kombination mit gespeicherten Prozeduren)? Oder vielleicht einen völlig anderen Ansatz?

Verstehe.

Dann bedanke ich mich trotzdem nochmal bei dir und den anderen beiden und schließe damit den Thread...

Wenn nun die Verlagerung der UI in die DLL unumgänglich ist, sind dann die 3 von mir genannten Schritte so korrekt? Falls nein, wie müsste der Ablauf in etwa aussehen?

So ist es, allerdings ruft die Cobol-Runtime die DLL nicht direkt auf, sondern bedient sich dazu einer C++/CLI-DLL, welche die C#-DLL wrappt. Aus (vorrangig) ästhetischen Gründen soll die Oberfläche auf WPF basieren.

Die C#-DLL ist allerdings keine Benutzersteuerelementbibliothek, sondern eine einfache DLL, welche WPF- XAML-Funktionalität besitzt. Demnach sind doch beim Einstieg noch keinerlei WPF-spezifischen Dinge (Nachrichtenschleife und UI-Thread) geladen, oder?

Okay. Da allerdings der Consumer der DLL ein Cobol-Programm hust ist, wird die UI in der DLL landen. Das Problem ist dass ich den initialen Appartement-State nicht kenne. Deswegen muss ich doch zwangsläufig einen neuen Thread nutzen um den State festzulegen, oder?

Du meinst also, dass die DLL lediglich die Validierungsfunktionalität bereitstellt und die UI in die aufrufende Anwendung verlegt werden soll?

Hallo,

der Punkt ist der, dass ich bisher nur "reine" WPF-Anwendungen erstellt habe, in denen man ja auf eine bestehende Nachrichtenschleife und UI-Thread aufsetzt. Nun habe ich aber eine reine DLL, welche mittels Verweise auf die entsprechenden WPF-Komponenten die Funktionalität quasi untergejubelt bekommt. Da muss ich zugeben, taten sich dann doch ein paar Wissenslücken auf.

Mein Ablauf sieht nun wie folgt aus:

  1. Erzeugen eines neuen UI-Threads und Dispatchers im Konstruktor mittels:

Thread uiThread = new Thread(() =>
{
    this.dispatcher = Dispatcher.CurrentDispatcher;
    Dispatcher.Run();
});

uiThread.SetApartmentState(ApartmentState.STA);
uiThread.Start();

  1. Dispatchen der GUI-Operationen an
this.dispatcher
  1. Nach getaner Arbeit mittels
this.dispatcher.InvokeShutdown();

aufräumen

Ist diese Vorgehensweise (Hauptaugenmerk sind Schritt 1 und 3) so korrekt?

Hallo,

das Fenster wird asynchron angezeigt, weil die Bibliothek letzten Endes von nativen COM-Komponenten genutzt wird. Da ich keinen Einfluss darauf habe, in welchen Apartments diese laufen, erstelle ich einen neuen Thread und setzte ihn explizit auf STA. Die nebenläufige Validierung der Daten bringt eine Zeitersparnis von 0,4 Sekunden. Ich gehe mittlerweile davon aus, dass wenn man alleine den Umfang der von der WPF zur leistenden Arbeit berücksichtigt, eine Reaktionszeit von ~ 0,7 Sekunden durchaus akzeptabel ist.

Trotzdem vielen Dank für eure Mühen.

PS: @FZelle: Die Richtlinien in den verlinkten Informationen sind mir geläufig und werden natürlich in dem fertigen Produkt zum Tragen kommen. Das Snippet ist daher lediglich als (quick and dirty) Test anzusehen...

Hallo,

ich habe eine DLL, welche Daten durch einen WCF-Dienst validieren lässt. Während des Verbindungsaufbaus und der Validierung möchte ich ein kleines "Bitte warten"-Fenster anzeigen.

Im Konstruktor der entsprechenden Klasse wird als erstes das Anzeigen des Fensters initiiert, die Methode dazu sieht wie folgt aus:


private void ShowBusyWindow(string text)
{
    Thread thread = new Thread(() =>
    {
        BusyWindow busyWindow = new BusyWindow(text);
        busyWindow.ShowDialog();
    });

    thread.SetApartmentState(ApartmentState.STA);
    thread.IsBackground = true;
    thread.Start();
}

Nach der Instanziierung wird durch den Aufrufer die eigentliche Validierung angestoßen, welche synchron erfolgt. Obwohl das Fenster, bis auf das Setzen einer DP im Konstruktor, keinerlei Logik enthält, dauert das Anzeigen dessen relativ lange, sodass es erst kurz vor Abschluss der Validierung kurz angezeigt wird.

Meine Frage ist nun, warum das Anzeigen des Fensters so (relativ) lange dauert, sowie ob und wie sich dies beschleunigen lässt?

Vielen Dank im Voraus für eure Anregungen...

04.02.2015 - 14:08 Uhr

Hallo horvi,

mittels Marshal.GetActiveObject kannst du dir bereits bestehende COM-Objekte aus der ROT rausholen.

HTH Hurby

Hallo Parso,

das war eine Punktlandung deinerseits, besten Dank.
PS: Margin und Padding braucht man beim Layout nicht zu berücksichtigen, dies berücksichtigt die WPF bereits in den an MeasureOverride und ArrangeOverride übergebenen Werten.

Nochmals vielen Dank

VG

Hallo,

ich habe mir ein eigenes FrameworkElement erstellt, welches den verfügbaren Platz zu gleichen Teilen auf einen TextBlock (links) und eine TextBox (rechts) aufteilen soll. Wenn ich nun in meine TextBox viel Text eingebe, wird der ArrangeOverride-Methode plötzlich eine größere finalSize übergeben, sodass das Layout nicht mehr stimmt. (Siehe Anhang) Leider weiß ich nicht, woran dies liegt. Habt ihr vielleicht Ideen?

Hier noch der Code zum Layout-Prozess:


protected override Size MeasureOverride(Size availableSize)
{
    Size desiredSize = new Size();

    foreach (UIElement child in this.children)
    {
        //measure child with available size
        child.Measure(availableSize);

        //add with of current child to desired width
        desiredSize.Width += child.DesiredSize.Width;

        //get maximum height
        desiredSize.Height = Math.Max(desiredSize.Height, child.DesiredSize.Height);
    }

    return desiredSize;
}    

protected override Size ArrangeOverride(Size finalSize)
{
    Rect rect = new Rect(0, 0, finalSize.Width / 2, 0);

    foreach (UIElement child in this.children)
    {
        //arrange child with half of width and desired height (textbox gets height of textblock)
        rect.Height = Math.Max(child.DesiredSize.Height, rect.Height);
        child.Arrange(rect);

        //arrange next child beside
        rect.X += child.RenderSize.Width;

        //set height of next child (textbox)
        rect.Height = child.RenderSize.Height;
    }

    return finalSize;
}

Vielen Dank im Voraus

Hallo,

ich habe eine Anwendung, welche beim Eintreten eines bestimmten Ereignisses geschlossen wird. Das Prüfen des Ereignisses geschieht asynchron, in einem separaten Thread. Entsprechend wird der EventHandler nicht auf dem Thread ausgeführt, welcher das Control erstellt hat. Die Dispose-Methode meines Hauptfensters sieht also wie folgt aus:


protected override void Dispose(bool disposing)
{
    if (base.InvokeRequired)
    {
        base.Invoke(new MethodInvoker(() => this.Dispose(disposing)));
    }

    if (disposing && (components != null))
    {
        components.Dispose();
    }
    base.Dispose(disposing);
}

Die Erstellung des Hauptfensters geschieht auf normalem Wege:


[STAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new MainForm());
}

Ein Kunde berichtet mir nun, dass sporadisch beim Beenden (durch Ereignis aus separatem Thread) der folgende Fehler auftritt:

Fehlermeldung:
invoke or begininvoke cannot be called on a control until the window handle has been created

Obwohl das Hauptfenster zur Laufzeit immer unsichtbar ist, erschließt sich mir nicht unter welchen Umständen der Handle nicht verfügbar sein soll. Habt ihr dafür eine Erklärung?

Vielen Dank im Voraus...

MfG Hurby

Hallo,

durch das Setzen von "SaveChanges = true" versucht Word die Normal.dot zu speichern. Da diese aber durch die andere Word-Session in Benutzung ist, schlägt das fehl. Da dein Programm aber keine Änderung vornimmt, welche die Speicherung der Normal.dot erfordert, kannst du SaveChanges auf false setzen. Sollte das nicht funktionieren, kannst du Word auch "vorgaukeln" dass die Normal.dot bereits gespeichert ist:


app.NormalTemplate.Saved = true;

MfG Hurby

Hallo,

ich habe in meinem Model die Properties mit DisplayAttributen versehen und setze darin die Name-Eigenschaft, um im View mittels @Html.LabelFor(model => model.PropertyName) ein Label anzuzeigen. Gerne würde ich die Name-Eigenschaft der DisplayAttribute zur laufzeit dynamisch aus einer Datenquelle laden, sodass diese einfach konfiguriert werden können. Da die Attribute ja beim Kompilieren bekannt sein müssen, können diese nicht dynamisch sein. Erste Tests mit Reflection waren erfolglos. Nun überlege ich, dafür ein zweites Model anzulegen, bzw. das Datenmodel um entsprechende Properties für die View zu ergänzen.

Nun wollte ich mal fragen wie ihr das macht / machen würdet? Kennt ihr vielleicht eine völlig andere (komfortablere) Lösung?

Vielen Dank im Voraus

MfG Hurby

Vielen Dank für eure Antworten, htbasic authentication schaue ich mir mal an.

Hurby

Hallo Leute,

ich stecke gerade in der Anfangsphase eines neuen Projektes und frage mich, ob ich in das Portal einen Adminbereich einbaue oder lieber ein separates Administrationstool dafür schreibe. Für das Tool spricht meiner Meinung nach die Sicherheit, da ein Adminbereich in der Webanwendung aus dem Internet erreichbar wäre und somit eine potenzielle Schwachstelle darstellt. Andererseits könnte man den Zugang zum Adminbereich nur für vorher festgelegte IPs erlauben. Da ich mir irgendwie unschlüssig bin, wollte ich mir mal ein paar Anregungen holen. Wie stellt ihr das an, oder würdet es anstellen wenn ihr freie Hand hättet? Welche Aspekte sollte ich noch beachten?

Vielen Dank im Voraus

Mfg Hurby

21.02.2013 - 08:43 Uhr

Hallo Abt,

natürlich habe ich alles in entsprechenden Repositories gekapselt.

Danke 👍

20.02.2013 - 13:40 Uhr

Hallo Abt,

danke für deine schnelle Antwort. MVC ist echt genial, nur eben an der Frage "was mache ich wo" scheitere ich noch manchmal und wollte deswegen mal die alten Hasen fragen. Dann werde ich ab sofort die inhaltliche Prüfung statt mit Attributen über die Controller abwickeln. Danke für die Aufklärung.

Mfg Hurby

20.02.2013 - 13:23 Uhr

Hallo,

ich arbeite mich gerade in ASP.NET MVC (4) ein und erneuere im Zuge dessen ein altes Projekt.
In diesem habe ich ein LoginModel mit eMail- und Passwort-Property. Um zu prüfen ob die eMail-Adresse existiert, habe ich mir ein CustomAttribute geschrieben und der eMail-Property entsprechend zugewiesen. Die Verifizierung des Passworts läuft ebenfalls über ein CustomAttribute, in welchem ich über Reflection die eMail-Adresse aus dem validationContext lese und dann das Passwort auf Korrektheit prüfe. Nun muss ich noch prüfen ob der Account gesperrt ist, und überlege ein weiteres CustomAttribute zu erstellen.

Meine Frage ist nun, ob ich mit den CustomAttributes etwas über das Ziel hinausschieße und die 3 Prüfungen doch lieber im Controller vornhemen sollte? Was meint ihr dazu?

MfG Hurby

Hallo,

ich versuche gerade eine Mail-Adresse in einem Model per DataAnnotation zu validieren. Klappt auch wunderbar, nur leider ist die Fehlermeldung auf Englisch. Im Internet habe ich gesehen, dass man das mittels einer Ressource-Klasse, sowie den benannten Parametern ErrorMessageResourceName und ErrorMessageResourceType lösen kann:


[Required]
[Display(Name = "eMail")]
[DataType(DataType.EmailAddress, ErrorMessageResourceName = "IncorrectMail", ErrorMessageResourceType = typeof(Resources.ModelValidation))]
public string Mail { get; set; }

leider ist die Fehlermeldung immer noch auf Englisch. Interessant ist, wenn ich die Parameter dem RequiredAttribute mitgebe und das Feld leer lasse, erscheint die Meldung welche ich in der Ressource-Klasse definiert habe. Weiss zufällig jemand warum die Parameter beim DataTypeAttribute wirkungslos sind?

Danke im Voraus
Mfg Hurby

Hallo,

bei uns in der Firma haben wir schon ASP.NET-Projekte, mit überschaubarem Aufwand, auf Mono portiert. Fallstricke gibt es hier und da natürlich immer (zum Beispiel wurde die Methode "Session_Start" in der "Global.asax" unter Ubuntu nicht ausgeführt), aber die sind meistens lösbar.

Zu erwähnen sei hier der Mono Migration Analyzer (MoMA). Dieses Tool prüft eine Assembly auf Lauffähigkeit unter Mono und gibt eine (meiner Meinung nach) brauchbare Liste von Fehlern (zum Beispiel P/Invoke-Aufrufe) aus:

Mono Migration Analyzer (MoMA)

MfG Hurby

... warum uebergibst Du nicht gleich ein echtes CLR Objekt, wenn CLI?

Eigentlich soll die C#-DLL aus Cobol (ACU) angesteuert werden. Da dass mit einer verwalteten DLL nicht geht, wollte ich einen Wrapper zwischenklemmen. Damit soll denn das Cobol-Programm die CLI-DLL aufrufen, welche den Pointer an die C#-DLL weiterreicht.

Ich habe die Arbeit nur in eine C#-DLL ausgelagert, weil ein SOAP-Request abgesetzt werden soll.
Diesen hatte ich zuvor in der CLI-DLL drin, aber die SOAP-Entries waren in komplett umgekehrter Reihenfolge (was der WebService nicht mochte). Ich vermute hier irgendein Problem mit der Aufrufkonvention cdecl oder BigEndian. Weil ich dazu keine passende Lösung gefunden habe, kam ich auf die Idee mit dem Wrapper.

edit: erledigt: ich habe jetzt einfach die Reihenfolge der Properties in der CLI-DLL vertauscht, sodass die Reihenfolge der Tags im SOAP-Request korrekt ist. Wenn trotzdem jemand weiss, warum das Marshallen aus dem nicht verwalteten Speicher nicht geklappt hat, wäre ich (und andere bestimmt auch) dankbar.

Hurby

Hallo,

ich bin gerade dabei eine DLL in C# zu schreiben, welche mit einem, aus C++/CLI übergebenen Pointer, arbeitet. Dieser Pointer (char*) zeigt auf eine Struktur:


struct Data
{
  char Version[3];
};

In der C#-DLL soll aus dem Pointer dann via Marshal.PtrToStructure eine verwaltete Struktur entstehen:


    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct Parameters
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 3)]
        public string Version;
    }

Jedoch ist die, aus dem nicht verwalteten Speicher, gelesene Struktur schrott.
Um das Ganze besser zu debuggen, habe ich mal eine Konsolenanwendung erstellt.
Schon der Inhalt des berechneten Char-Pointers weicht von dem der C++/CLI - DLL ab:


static unsafe void Main(string[] args)
{
  //beliebigen Pointer erstellen
  int x = 100; 
  int *ptr = & x;

  //offset berechnen (siehe Speicheradresse von C++/CLI im angehängten Bild)
  int offset = (int)ptr - 1310560;

  //die Adressen sind identisch, der Inhalt jedoch nicht (siehe angehängtes Bild)
  char* vptr = (char*) IntPtr.Subtract(new IntPtr((char*)ptr), offset).ToPointer();
}

Habt ihr eine Idee, woran das liegen kann?

Danke im Voraus

Hallo,

wenn du das Originaldokument geschlossen hast, hast du nur noch ein Dokument in der Sitzung und das sprichst du mittels:

app.ActiveDocument

an. Einfach ein

app.ActiveDocument.SaveAs2(compareDocFileName, ref missing ...);

und schon kommt kein Speichern-Dialog mehr.

Edit:

Ok, anscheinend ist an der Stelle 0 nichts, also habe ich die 0en durch eine 1 ersetzt. Nun speichert er mir aber das Ursprungsdokument ab und nicht das Vergleichsdokument. Kann es sein, dass er für das Vergleichsdokument eine Word.Application Instanz erstellt?

Nein, Word ist per Defualt eine Einzelinstanz-Anwendung, wenn nicht in der Registry geändert hast du alle geöffneten Dokumente in einer Instanz. Aber sichgehen kannst du nur nach einem Blick in den Taskmgr, da sollte sich zu jedem Zeitpunkt nur eine winword.exe befinden

Mfg Hurby

16.05.2012 - 12:58 Uhr

Hallo,

vielleicht ließe sich das von Darth Maim geschilderte Problem umgehen, indem du dir die aktuelle Instanz des Browsers schnappst und dort per Code die Speichern-Funktion durchführst. Machbar ist das mit Sicherheit, aber du hättest dann kein Bild sondern eine Textdatei (Webarchiv oder HTML)...

Mfg Hurby

PS: Hoffentlich arbeitest du nicht an der Entwicklung des neuen Staatstrojaners 😁 ... kleiner Spass am Rande...

Hallo,

der Speichern-Dialog kommt weil:

  1. Das Vergleichsresultat ein neues Dokument ist und Word nicht "weiss" wo dies gespeichert werden soll.

  2. Das Originaldokument ebenfalls gespeichert werden soll, aber schreibgeschützt ist

Du warst aber schon auf dem richtigen Weg, nach dem Vergleichen solltest du das Originaldokument schliessen ohne zu speichern und das Vergleichsresultat unter dem in "compareDocFileName" abgelegten Pfad speichern.

Mfg Hurby

Hallo,

vielen Dank für eure Anregungen, ich schaue mir das mal. Wahrscheinlich werde ich aber einen komplett eigenen Dialog basteln.

Hurby

11.05.2012 - 13:39 Uhr

Hallo,

also wenn der Thread deinem EventHandler nicht zur Verfügung steht, musst du wohl eine Abbruchbedingung in den Thread bauen, welche im EventHandler gesetzt wird:


        void test()
        {
            while (continueWork)
            {
                //...
            }
        }

        private void buttonStop_Click(object sender, EventArgs e)
         {
             continueWork = false;
         }

hth Hurby

Hallo,

gibt es eine Möglichkeit den OpenFileDialog so zu konfigurieren / erweitern, dass der Benutzer nur Dateien in dem übergebenen InitialDirectory auswählen kann? Dass also ein wechsel des vordefinierten Verzeichnisses nicht möglich ist.

Vielen Dank im Voraus

Hurby

Hallo,

ich war eigentlich der Meinung es gäbe eine Property / Funktion welche dir genau dies liefert, finde sie aber nicht. Dennoch habe ich mal ein kleines Makro geschrieben, welches die Aufgabe übernimmt:


Sub test()

    Dim rng As Range
    Dim sc As String
    Dim ec As String
    
    For Each rng In Selection
        If sc = "" Then
            sc = Replace(rng.Address, "$", "")
        Else
            ec = Replace(rng.Address, "$", "")
        End If
    Next rng
    
    If ec = "" Then
        MsgBox sc
    Else
        MsgBox sc & ":" & ec
    End If

End Sub


Musst denn noch nach c# portieren...

hth

Hurby

27.04.2012 - 15:58 Uhr

Hallo,

ich denke es liegt weder an Windows noch an der Ländereinstellung.
Meiner Erfahrung nach klemmt es meistens in Word selber.
Vergleiche doch mal folgende Einstellungen von deinem Office2010 und jenem des Kunden:

<Datei><Optionen><Sicherheitscenter><Einstellungen für das Sicherheitscenter><Einstellungen für Makros>

Diese dürfen natürlich nicht deaktiviert sein, zudem muss dem Zugriff auf das VBA-Projektmodell vertraut werden.

Vielleicht ergibt dich da ja schon eine Differenz in der Word.Konfiguration...

hth

mfg Hurby

So, erledigt, läuft nun auch ohne c++/CLI...

Das Tool "DllExport" war mein "Missing Piece", läuft super. Auch das DeMarshalling läuft sauber durch:


[ExportDllAttribute("Starten", CallingConvention.Cdecl)]
public unsafe static void Starten(int* Ptr)
{
    Parameters Args = (Parameters)Marshal.PtrToStructure(new IntPtr((void*)Ptr), typeof(Parameters));
}

besten Dank 👍

Moin Coder007,

Danke für den Link, hab eigentlich sehr intensiv gesucht, aber bin meistens nur auf Artikel gestoßen, wo die DLLs in TLBs konvertiert wurden. Das mit dem Konvertieren auf C++-Seite kam mir auch schon in den Sinn... Ich werde beide Varianten mal durchspielen.

Nochmals vielen Dank für deine Hilfe

Okay, ich versuche es mal, hoffentlich wird es dadurch nicht noch komplizierter.
Das Ziel ist es, ein C-Programm (ist nicht von mir, für mich also eine BlackBox) und ein C#-Programm kommunizieren zu lassen. Dabei soll das C-Programm die Verbindung zum C#-Programm herstellen, nicht andersrum (sonst könnte ich es ja über pInvoke machen). Da ich aber scheinbar zu doof bin, meine Funktionen in C# so zu exportieren, dass das C-Programm sie "sehen" kann (auch der Dependency-Walker "sieht" nix) habe ich mich entschieden, einen Wrapper um das C#-Programm zu legen. Dies ist der C-Quellcode den ich schon gepostet habe. Jetzt soll also ein fremdes Programm meinen Wrapper laden und der Funktion Starten einen int-Pointer übergeben, der auf eine Struktur zeigt die in dem C++-Programm definiert ist. Mein Wrapper soll dann den Zeiger (irgendwie) an mein C#-Programm weitergeben, und dieses dann auf die Struktur zugreifen. Die Pipe habe ich nur genommen weils mir empfohlen wurde, sie dient nur dazu den Zeiger an mein C#-Programm zu übergeben, da dies keine DLL sondern eine EXE ist.

Ich hoffe, dass ich ein wenig Licht ins Dunkel bringen konnte, wenn nicht könnt Ihr gerne nochmal nachhaken... (wobei ich gleich Feierabend habe 😃 )

MfG Hurby

Edit: Bitte lasst euch nicht von


struct Params
{
	char	Version[2];
}Args

und


  Params* pPtr = (Params*)Ptr;

  fstream f;
	f.open("c:\\test.txt", ios::out);
	f << "Adresse: " << pPtr << " Wert:" << pPtr->Version << endl;
  f.close();

ablenken, das war nur zum Testen, eigentlich siehts so aus:


#include "stdafx.h"
#include "test.h"

EXPORT void Starten(int* Ptr)
{
	NamedPipeClientStream^ PipeClient = gcnew NamedPipeClientStream("127.0.0.1", "TestPipe", PipeDirection::InOut, PipeOptions::None, TokenImpersonationLevel::Impersonation);
	PipeClient->Connect();

	IntPtr^ test = gcnew IntPtr(Ptr);

	//write the address into the stream and close the pipe
	PipeClient->Write(BitConverter::GetBytes(test->ToInt32()), 0, 4);
  PipeClient->Close();
}

Hallo,

ich habe einen kleinen Wrapper in C++/CLI geschrieben, welcher durch eine C++-DLL angesteuert wird. Dieser bekommt einen int-Pointer und übergibt diesen mittels einer benannten Pipe an ein C#-Programm.

Leider bekomme ich auf der C#-Seite eine AccessViolationException:
"Es wurde versucht, im geschützten Speicher zu lesen oder zu schreiben. Dies ist häufig ein Hinweis darauf, dass anderer Speicher beschädigt ist."

Das Einlesen der Struktur auf Wrapper-Seite funktioniert bestens, auch der Wert kommt sauber rüber, hier mal der der Code:


#include "stdafx.h"
#include "test.h"

#include <fstream>
using namespace std;

struct Params
{
	char	Version[2];
}Args;

EXPORT void Starten(int* Ptr)
{
  Params* pPtr = (Params*)Ptr;

  fstream f;
	f.open("c:\\test.txt", ios::out);
	f << "Adresse: " << pPtr << " Wert:" << pPtr->Version << endl;
  f.close();

	NamedPipeClientStream^ PipeClient = gcnew NamedPipeClientStream("127.0.0.1", "TestPipe", PipeDirection::InOut, PipeOptions::None, TokenImpersonationLevel::Impersonation);
	PipeClient->Connect();

	IntPtr^ test = gcnew IntPtr(Ptr);

	//write the address into the stream and close the pipe
	PipeClient->Write(BitConverter::GetBytes(test->ToInt32()), 0, 4);
  PipeClient->Close();
}

Der Code der Struktur in C# sieht wie folgt aus:


[StructLayout(LayoutKind.Sequential)]
public struct Parameters
{
    /// <summary>
    /// version
    /// </summary>
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2)]
    public string Version;
}

und zum Schluss noch die Methode zum Einlesen:


Parameters Args = (Parameters)Marshal.PtrToStructure((ptr), typeof(Parameters));

Die Referenz des Pointers ist auf C#-Seite die selbe wie auf Wrapper-Seite, der GC verschiebt also scheinbar nichts.

Hab schon sämtliche UnmanagedTypes die ein "Str" im Namen haben durgetestet, leider immer ohne Erfolg...

Weiss Jemdand was ich falsch mache???

Vielen Dank

Hurby

Hallo Sebastian,

das kurze Anzeigen klappt gut. Das Verschieben aus dem sichtbaren bereich is ne super Idee, danke.

PS: Ich werd demnächst mal deine LateBindingApi testen 😉

MfG Hurby

Habe gerade heraus gefunden, dass das Problem nur auftritt, wenn Word zum Zeitpunkt wo die Datenquelle geöffnet wird nicht sichtbar ist. Lasse ich es kurz vorher auf dem Bildschirm anzeigen, sind die Leisten sauber. Könnte ich irgendwie auf die nicht sichtbare Instanz eine art "Pseudo-Repaint" ausführen???

MfG Hurby

Ja, sowas hab ich bei Google auch schon gelesen. Aber mit F11 komm ich da nich raus...
Zumal ich das eh programmatisch lösen müsste...

Edit: wobei ich gerade merke, dass der Fullscreen-Mode doch etwas anders aussieht.
Wenn ich eine Taste wüsste, mit der ich die Leisten wieder zuschalte, könnte ich ja versuchen ein SendKeys abzusetzen.

Hallo,

ich habe schon seit ewigen Zeiten das Problem, wenn in meiner Datenquelle ein Seriendruckfeld fehlt und der Dialog "Ungültiges Seriendruckfeld" kommt, dass danach keine Menüleisten mehr in Word sichtbar sind. Das lustige ist, dass es nur auftritt, wenn Word automatisiert wird, erstelle ich den Serienbrief manuell ist alles im Lot...

Hier mal ein Bild, wie Word nach dem Dialog aussieht.

Kennt Jemand zufällig das Problem und evtl. die Lösung???

PS: Dokumentinhalt absichtlich entfernt...

MfG Hurby

Hallo winSharp93,

sorry dass ich erst jetzt antworte, musste mich zwangsweise von der Thematik distanzieren.
Aber Du hast recht, wenn ich im Debugger mit F5 weitergehe dann komm ich dahin wo ich hin will.
Ist wahrscheinlich sogar besser als das Attribut zu verwenden...

Trotzdem vielen Dank euch beiden und ein frohes Osterfest 😉

MfG Hurby

Hallo,

ich habe mir mal testweise eine Methode geschrieben, die es mir erlaubt den Aufwand der Word-Anbindung mittels Latebinding etwas zu senken:


private Object Invoke(String Name, BindingFlags Flags, Object Target, Object[] Parameters)
{
    Object TempObject = null;
    String[] Hierarchy = Name.Split(".".ToCharArray());

    for (Int32 i = 0; i < Hierarchy.Length; i++)
    {
        if (Hierarchy.Length == 1)
            TempObject = Target.GetType().InvokeMember(Hierarchy[i], Flags, null, Target, Parameters);
        else
        {
            if (i == 0)
                TempObject = Target.GetType().InvokeMember(Hierarchy[i], BindingFlags.GetProperty, null, Target, null);
            else
            {
                if (i == Hierarchy.Length - 1)
                    TempObject = TempObject.GetType().InvokeMember(Hierarchy[i], Flags, null, TempObject, Parameters);
                else
                    TempObject = TempObject.GetType().InvokeMember(Hierarchy[i], BindingFlags.GetProperty, null, TempObject, null);
            }
        }
    }

    return TempObject;
}

Die Benutzung sähe in etwa so aus:


Invoke("Selection.ShapeRange.TextFrame.MarginLeft", BindingFlags.SetProperty, Session, new Object[]{0});
Invoke("Selection.ShapeRange.TextFrame.MarginRight", BindingFlags.SetProperty, Session, new Object[]{0});
Invoke("Selection.ShapeRange.TextFrame.MarginBottom", BindingFlags.SetProperty, Session, new Object[]{0});
Invoke("Selection.ShapeRange.TextFrame.MarginTop", BindingFlags.SetProperty, Session, new Object[]{0});

Man übergibt also quasi den Pfad zur Methode / Eigenschaft und die "Zwischenobjekte" werden dann autom. in der Schleife gelesen.

Ich denke, gerade wenn man wie hier erst mehrere Unterobjekte auslesen muss um an die eigentliche Methode / Eigenschaft zu kommen kann die Methode schon behilflich sein. Aber genau da liegen auch meine Zweifel, denn in meinem Beispiel werden die Objekte "ShapeRange" und "TextFrame" 4 mal gelsesen, also 3 mal unnötig.

Was meint Ihr, kann man diese Tatsache vernachlässigen oder sollte ich lieber etwas mehr Schreibarbeit in Kauf nehmen und dafür auf überflüssige Schritte verzichten???

MfG Hurby

👍

ich dank Dir, genau was ich gesucht habe.
Schönes Wochenende...

MfG Hurby

Hallo MarsStein,

erstmal danke, jetzt wo ich es mal nicht im Debug-Modus getestet habe klappts.
Wenn ich die Anwendung allerdings debugge, bleibe ich beim Werfen der Exception hängen. Kann ich das irgendwie einstellen???

MfG Hurby

Hallo Leute,

ich teste gerade mit asynchronen Methoden rum und bin auf das Problem des Exception-Handlings gestoßen. In folgendem Progrämmchen wollte ich die Exception in der CallBackMethod handeln, das klappt aber nicht so recht. Wisst Ihr, was ich falsch mache???


    class Program
    {
        static void Main(string[] args)
        {
            new Program().CallingMethodAsynch();
        }

        delegate void Foo(string x);

        void CallingMethodAsynch()
        {
            Foo delegFoo = this.Method;
            delegFoo.BeginInvoke("text", CallBackMethod, delegFoo);
        }

        void CallBackMethod(IAsyncResult aRes)
        {
            if(aRes == null || aRes.AsyncState == null) return;
            
            Foo deleg = aRes.AsyncState as Foo;
            if (deleg == null) return;

            deleg.EndInvoke(aRes);
        }

        void Method(string txt)
        {
            throw new Exception("Unhandled exception never caught unless a debugger attached");
        }
    }

MfG Hurby