Laden...

Forenbeiträge von Mai08 Ingesamt 11 Beiträge

29.08.2007 - 10:50 Uhr

Hallo liebe Leute,

ich nutze auch das Windows Scripting Host zum erstellen einer Verknüpfung.
Jedoch kann ich es überhaupt nicht leiden, ständig die DLL's mit zu schleppen.
Also habe ich die Verknüpfung zur DLL über LateBinding realisiert.
Es sind hier also keinerlei Com-Verweise nötig:

// Erstellen einer Verknüpfung
string PfadVK = "...", NameVK = "...";
string OriginalDateiMitPfad = "...";
object oWS = Activator.CreateInstance(Type.GetTypeFromProgID("WScript.Shell"));                    
object oLink = oWS.GetType().InvokeMember("CreateShortcut", BindingFlags.InvokeMethod, null, oWS, new object[] { PfadVK + NameVK + ".lnk" });
oLink.GetType().InvokeMember("TargetPath", BindingFlags.SetProperty, null, oLink, new object[] { OriginalDateiMitPfad });
oLink.GetType().InvokeMember("Save", BindingFlags.InvokeMethod, null, oLink, new object[] { });

Viele Grüße

29.08.2007 - 10:28 Uhr

Hallo liebe Leute,

leider konnte mir bei diesem Problem niemand helfen.
Ich denke jedoch, dass ich dennoch eine halbwegs brauchbare Lösung gefunden habe, die ich hier posten möchte.

Also anstatt den Menübefehl "Senden/ Empfangen" aufzurufen, schnappe ich mir jetzt den Postausgang, suche nach der Mail, die gerade erstellt wurde und sende diese einfach ab. Und alles über LateBinding:

// Zeit beim Anlegen der E-Mail
DateTime MailCreated = DateTime.Now;

// .... Anlegen der E-Mail

// Versenden falls im Postausgang
//// Postausgang laden                       
object Postausgang = oNameSpace.GetType().InvokeMember("GetDefaultFolder", BindingFlags.InvokeMethod, null, oNameSpace, new object[] { 4 });
//// Anzahl Elemente im Postausgang
object Items = Postausgang.GetType().InvokeMember("Items", BindingFlags.GetProperty, null, Postausgang, new object[] { });
object ItCount = Items.GetType().InvokeMember("Count", BindingFlags.GetProperty, null, Items, new object[] { });
int hi = (int)ItCount;
object AktItem = null, CT = null;
DateTime Created;
TimeSpan TS;

// Versuch des Sendens aller kürzlich erzeugten Objekte im Postausgang
for (int i = 0; i < hi; i++)
{
    try
    {
         AktItem = Items.GetType().InvokeMember("Item", BindingFlags.InvokeMethod, null, Items, new object[] { i + 1 });
         CT = AktItem.GetType().InvokeMember("CreationTime", BindingFlags.GetProperty, null, AktItem, new object[] { });
         Created = (DateTime)CT;
         TS = MailCreated.TimeOfDay - Created.TimeOfDay;
         if (Math.Abs(TS.Seconds) < 5)
             AktItem.GetType().InvokeMember("Send", BindingFlags.InvokeMethod, null, AktItem, new object[] { });
    }
    catch { }
}

Wie ich die E-Mail (mit Anhängen) über LateBinding erzeuge steht schon in folgendem Thread:
DLL's verwenden und Outlook via Reflections

Mich würde interessieren, was Ihr von der obigen Lösung haltet.

Viele Grüße

14.06.2007 - 09:38 Uhr

Hallo liebe Leute,

ich habe mal wieder ein kleineres Problem.

Vor einiger Zeit habe ich schon einmal eine Frage gepostet. Es ging damals darum Outlook überhaupt erst einmal über Late Binding zu integrieren.

Eigentlich funktioniert alles ganz super.

Eine Outlook Application wird instanziert, die E-Mail erstellt und angezeigt.
Hatte der Nutzer Outlook vorher bereits geöffnet funktioniert alles noch besser, denn dann wird die E-Mail beim klicken auf "Senden" auch direkt gesendet.

Musste Outlook aber ganz neu geöffnet werden, bleibt Outlook wie es scheint nicht genügend Zeit die E-Mail auch wirklich zu versenden.
Die E-Mail wird dann "nur" in den Ordner Postausgang verschoben und wird erst versendet, wenn Outlook dann mal wieder richtig geöffnet.
Das finde ich sehr ungünstig.

Daher wollte ich gern vor dem bereinigen der Outlook-Instanz das Senden/Empfangen ausführen lassen.

Ich habe dazu aber nur gefunden, wie es geht, wenn man die Verweise vorher hinzufügt:

// If you use the Microsoft Outlook 11.0 Object Library
Office.CommandBarControl oSendReceiveAll = (Office.CommandBarControl)oBarCrls["Send/Receive All"];
				
// Do the action.
oSendReceiveAll.Execute();

Nun weiß ich gar nicht wie ich das über Late Binding angehen soll, da ja das CommandBarControl nicht über Outlook, sondern über Office zu laufen scheint.

Ich hoffe Ihr versteht mein Problem.

Vielen Dank

25.05.2007 - 08:21 Uhr

Vielen Dank für die vielen Hinweise.

Ich werde die NotePad-Einstellungen also lieber dem Nutzer überlassen und in der Software-Dokumentation angeben welche Schriftart günstig ist.

23.05.2007 - 15:12 Uhr

Hallo allerseits,

ich habe ein kleines Problem und hoffe ihr könnt mir helfen.
Mein C# Programm schreibt einige Daten in eine *.txt-Datei.
Diese wird bei allen Nutzern standardmäßig von NotePad geöffnet.

Leider stehen die Daten nicht schön untereinander, wenn der Nutzer nicht die Schriftart Courier New gewählt hat.

Gibt es nun eine Möglichkeit die NotePad-Einstellungen eines jeden Nutzers beim Programmstart zu ändern?

Vielen Dank.

08.05.2007 - 07:57 Uhr

Vielen Dank, hat bei mir auch super funktioniert!

27.04.2007 - 14:41 Uhr

Hallo, ich habe mittlerweile einige Fortschritte bei der Interop.JRO.dll gemacht.

Ich kann diese jetzt wie folgt aus einem vom Benutzer angegebenen Pfad (z.B. Installationspfad) zur Laufzeit laden und verwenden (um die Datenbank zu komprimieren und zu reparieren):

// Laden der DLL
 Assembly JRO = Assembly.LoadFile(PfadInstall + @"\Interop.JRO.dll");
 object MyJetEngine = Activator.CreateInstance(JRO.GetType("JRO.JetEngineClass"));
// Aufrufen der Methode zum komprimieren und reparieren
 MyJetEngine.GetType().InvokeMember("CompactDatabase", BindingFlags.InvokeMethod, null, MyJetEngine, new string[2] { strQuelle, strZiel });

Soweit so gut.

Das einzige was ich mir jetzt wünschen würde ist, dass ich die DLL nun nicht als Pfad angeben muss, sondern diese direkt aus der Solution laden kann.
Ich kann doch die DLL mit "Vorhandenes Element hinzufügen" zur Solution hinzufügen (und habe dann die Buildvorgangseigenschaft auf eingebettete Ressource gestellt).
Jetzt muss ich nur noch rausfinden, wie ich die Assembly von dort lade und nicht von dem Pfad. Oder geht das einfach nicht???

Über jeden Hinweis wäre ich sehr dankbar!

27.04.2007 - 14:30 Uhr

Hallo Dispulse,

wenn ich dich richtig verstanden habe befinden sich die DLL's immer im selben verzeichnis, habe die selben Methoden und heissen nur anders.

Dann würde ich vielleicht versuchen die DLL so zu laden:

// Laden der DLL
Assembly MyDLL = Assembly.LoadFile(FesterPfad + @"\VorherGefundenerName.dll");
// Erstellen einer Klasse der DLL
object MyDLLClass = MyDLL.Activator.CreateInstance("DLLClass");
// Aufrufen des Einstiegspunktes
MyDLLClass.GetType().InvokeMember("RunIntelligence", BindingFlags.InvokeMethod, null, MyDLLClass, parameter);
27.04.2007 - 11:04 Uhr

Vielen Dank nocheinmal für den Tip mit dem Late Binding.
Für Outlook auf jeden Fall mal der richtige Gedanke. ZUmal noch hinzu kommt, dass ich via Reflections Versionsunabhängig bin.

Ich habe mir aus verschiedenen Foren, Hilfen und eigenen Basteleien einiges herausgesucht und ich bin nun in der lage in Outlook eine E-Mail mit Anhang via Reflections zu versenden. Den Code möchte ich mal posten.

Solltet ihr der Meinung sein das gibts schon, dann löscht es halt weg.

Zunächst zwei wichtige Verweise:

using System.Reflection;
// Für die Marshal-Klasse
using System.Runtime.InteropServices;

Und hier der Code für die Inzeraktion mit Outlook

// Text der E-Mail als HTML-Code
string HTML = "........(HTML-Code halt).....";

// E-Mail öffnen
// Outlook Klasse laden
Type oType = Type.GetTypeFromProgID("Outlook.Application");
object oApp = Activator.CreateInstance(oType);
object oNameSpace = oApp.GetType().InvokeMember("GetNamespace", BindingFlags.GetProperty, null, oApp, new object[1] { "MAPI" });

// Anmelden des aktuellen Benutzers
oNameSpace.GetType().InvokeMember("Logon", BindingFlags.InvokeMethod, null, oNameSpace, new object[4] { "default", null, true, true });
                                
// Neues E-Mailobjekt
object oMailItem = oApp.GetType().InvokeMember("CreateItem", BindingFlags.InvokeMethod, null, oApp, new object[] { 0 });
                
// Betreff
oMailItem.GetType().InvokeMember("Subject", BindingFlags.SetProperty, null, oMailItem, new object[] { "Test" });

// Text zuweisen
oMailItem.GetType().InvokeMember("HTMLBody", BindingFlags.SetProperty, null, oMailItem, new object[] { HTML });
                 
// Anhänge
object Att = oMailItem.GetType().InvokeMember("Attachments", BindingFlags.GetProperty, null, oMailItem, new object[] { Missing.Value });
for (int i = 0; i < Anhang.Count; i++)
Att.GetType().InvokeMember("Add", BindingFlags.InvokeMethod, null, Att, new object[] { DateiPfad, 1, i + 1, AnhangName });
                
// Anzeigen der E-Mail
oMailItem.GetType().InvokeMember("Display", BindingFlags.InvokeMethod, null, oMailItem, new object[] { true });

// COM-Verweise freigeben und Variablen  nullen             
Marshal.ReleaseComObject(Att); Att = null;
Marshal.ReleaseComObject(oMailItem); oMailItem = null;
Marshal.ReleaseComObject(oNameSpace); oNameSpace = null;
Marshal.ReleaseComObject(oApp); oApp = null;
oType = null;

Ich hoffe das hilft auch anderen.

26.04.2007 - 16:19 Uhr

Dank, für die Antwort!

Ich weiß jetzt, dass die Outlook-DLL im Windows-Verzeichnis liegt, das tut sie bei mir ja auch.

Ich habe versucht mich einmal durch das Late-Binding zu wurschteln.

Dabei ist unter anderem folgendes herausgekommen:

Type Klasse;
Klasse = Type.GetTypeFromProgID("Interop.JRO.dll");
object ObjKlasse = Activator.CreateInstance(Klasse);     

Das Problem was ich habe, ist die DLL.
In allen Beispielen steht für die ProgID sowas wie "Excel.Application" oder so.
Aber wie greife ich denn auf eine DLL zu?
Wie lautet deren ProgID?

Vielen Dank brereits im Voraus.

26.04.2007 - 14:28 Uhr

Hallo liebe Entwickler,

dies ist mein erster Beitrag in diesem Forum, bei eventuell auftretenden Fehlern (falsches Forum, bereits existierender Beitrag trotz intensiver Suche, etc.) bitte ich höflichst mich darauf aufmerksam zu machen und mich nicht zu verhauen 😉

Hier kommt auch schon mein Problem:

In meinem Programm habe ich verschiedene Verweise hinzugefügt, damit ich aus meinem Programm heraus verschiedene Aktionen durchführen kann.
Dazu gehören z.B. eine ACCESS-Datenbank komprimieren und reparieren (Interop.JRO.dll) und E-Mails via Outlook (Microsoft.Office.Interop.Outlook.dll) versenden.

Wie gesagt Verweise sind hinzugefügt, die entsprechenden 'usings' sind auch eingefügt und siehe da, alles funktioniert fehlerfrei.

Leider habe ich nun das Problem, dass die entsprechenden DLL's im selben Ordner wie die EXE liegen müssen, da der Verweis dahin verweist!
Das möchte ich aber nicht, da ich zum vervielfältigen des Programms immer die entsprechenden DLL's mitgeben muss, ausserdem möchte ich dem Nutzer den Wuhst an Dateien ersparen.

Nun mein Wunsch:

  1. Ist es möglich die DLL's direkt in die Solution einzubetten, so dass die EXE um die jeweiligen DLL's größer wird und die DLL's als separate Dateien gar nicht mehr benötigt werden? Ich habe bereits versucht die DLL's als Resourcen hinzuzufügen, habe die "Buildvorgang"-Eigenschaft auf "eingebettete Resource" gestellt und die EXE ist um die DLL größer geworden, nur weiß ich jetzt nicht wie es weiter gehen soll. Ich meine muss dann auch ein "using" hin, wenn ja wie sieht das aus? Ich weiß einfach nicht wie ich auf diese Resource zugreifen kann und deren Datentypen bzw. Methoden verwenden kann.

  2. Wenn sich 1. nicht realisieren lässt wäre ich auch damit zufrieden, dass ich dem Programm über eine Art .ini-Datei den Pfad der DLL's übergeben könnte.
    Auf diese Weise könnte ich die DLL's einmal irgendwo ablegen. Die Verweispfade sollen also variabel und laufzeitgesteuert sein.

Unten mal ein Code-Schnipsel wie ich über den normalen Verweis und using die DLL nutze:


using JRO;

namespace XXX
{

     public class Funktionen
     {
          private Funktionen() { }

          // Komprimieren und Reparieren der Datenbank
          public static void KomprimiereDB()
          {
               string Datei1 = IrgendeinPfad + @"\Name1.mdb";
               string Datei2 = IrgendeinPfad + @"\Name2.mdb";
               JetEngine objJetEngine = new JetEngine();
               string strQuelle = "Provider=Microsoft.Jet.OLEDB.4.0;Jet OLEDB:Database Password=1234;Data Source=" + Datei1 + ";";
               string strZiel = "Provider=Microsoft.Jet.OLEDB.4.0;Jet OLEDB:Database Password=1234;Data Source=" + Datei2 + ";";

               objJetEngine.CompactDatabase(strQuelle, strZiel);

               File.Replace(Datei2, Datei1, Datei1 + "x");
               File.Delete(Datei1 + "x");
          }
     }
}

Ich hoffe Ihr versteht was ich meine.
Vielen Dank für die Geduld