Laden...

Forenbeiträge von Talon Ingesamt 67 Beiträge

09.08.2010 - 08:02 Uhr

Hallo,
warum rufst Du GetResponse auf bevor Du den Request fertig hast?
Einfacher ist es ohnehin mit einem WebClient und dessen UploadFile-Methode.
Gruß, MarsStein

GetResponse könnte ich auch weg lassen. Das ändert aber am Problem nichts, dann kommt die Fehlermeldung eben beim FileStream.
Ich konnte das Problem zwischenzeitlich als Zeitproblem identifizieren. Der Code an sich ist in Ordnung. Nur wenn ich zu schnell nach einem Upload einen neuen starten will, kommt der Fehler. Warte ich einen kleinen Moment, dann läuft es Problemlos durch. Warum das so ist, kann ich mir allerdings noch immer nicht erklären.

Wie auch immer. Vielen Dank für den Tipp mit dem WebClient. Das ist wirklich um einiges kürzer als mit der FtpWebRequest Methode. Und für meinen Zweck (Hochladen von kleinen Textdateien) mehr als ausreichend.

Hier der Code zum Upload von Dateien über WebClient. Sollten andere vor ähnlichen Problemen stehen.


        public void UploadToWEB(string filepath, string ftpAddress, string username, string password, string errorFilePath)
        {
            WebClient wc = new WebClient();
            wc.Credentials = new NetworkCredential(username, password);
            try
            {
                wc.UploadFile(ftpAddress, filepath);
                ////Den Rückgabewert der Methode kann in ein Byte Array übergeben werden
                //byte[] response = wc.UploadFile(ftpAddress, filepath);
            }
            catch (Exception e)
            {
                writeError(e.Message, errorFilePath);
            }
            wc.Dispose();
        }

Lässt man Try/Catch weg ist es ein 3 Zeiler. Kein Vergleich zur FtpWebRequest Methode. Nochmal danke an MarsStein für den Tipp.

Thread kann geschlossen werden. Danke

06.08.2010 - 08:12 Uhr

Verständnisproblem:

Die Frage wurde schon oft im Forum gestellt. Forensuche. Auch hab ich über Google schon danach gesucht. google & google. Ich werde aber einfach nicht schlau daraus. Ich sehe vermutlich den Wald vor lauter Bäumen nicht.

Ich habe eine kleine DLL (bzw. ein DLL Projekt) das ich in mein Programm eingebunden habe. Es ist im Projektverweise eingetragen und mit using eingebunden.

In der DLL steht zur Zeit nur folgendes.


using System.Net;
using System.IO;

public class ftp
    {
        public void UploadOnFTP(string filepath, string ftpAddress, string username, string password, string errorFilePath)
        { //Ein Request erstellen an den ftp Server
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpAddress);
            //Die Methode angeben um eine Datei hochzuladen
            request.Method = WebRequestMethods.Ftp.UploadFile;
            request.UsePassive = true;
            request.UseBinary = true;
            request.KeepAlive = false;
            //login Username und Passwort vom ftp Server 
            request.Credentials = new NetworkCredential(username, password);

            try
            { //Versuch eine Verbindung zu erstellen und eine Antwort zu erhalten
                WebResponse response = request.GetResponse();
                //Neuen FileStream erstellen für die Datei und in ein bytearray schreiben
                FileStream fs = new FileStream(filepath, FileMode.Open);
                byte[] fileContents = new byte[fs.Length];
                fs.Read(fileContents, 0, Convert.ToInt32(fs.Length));
                fs.Close();
                //Ein neuen Stream für den Request erstellen dem der FileStream mitgegeben wird.
                Stream requestStream = request.GetRequestStream();
                requestStream.Write(fileContents, 0, fileContents.Length);
                requestStream.Close();
            }
            catch (Exception e)
            {
                writeError(e.Message, errorFilePath);
            }
            //Verbindung abbschliessen
            request.Abort();
        }
    }

Über meine MainForm soll über ein ButtonClick Ereignis immer wieder eine einzelne Datei an den FTP übertragen werden.


        private void button1_Click(object sender, EventArgs e)
        {
            ftp f = new ftp();
            f.UploadOnFTP(filepath + "DEFAULT.RPL", ftpAddress + "/execute/DEFAULT.RPL", username, password, errorFilePath);
        }

Wie bei allen anderen habe ich auch das Problem das ich nur 1mal die Datei übertragen kann, und anschließend die Fehlermeldung: {"Auf das verworfene Objekt kann nicht zugegriffen werden.\r\nObjektname: "System.Net.Sockets.NetworkStream"."} bekomme.
Jetzt steht ja in den Meisten Threads, das nach einem Close das Object disposed wird. Aber

 ftp f = new ftp();

sollte doch bei jedem Click eine neue Instanz des Objects erzeugen. Zumal das alte Object ja nur innerhalb meines Buttonclicks existieren sollte, und mit Beenden dieses eben verschwinden sollte. Wieso also bekomme ich dann die Fehlermeldung? Ich versteh es einfach nicht. Es sollte doch so laufen.

Die Fehlermeldung kommt bei der Zeile:

WebResponse response = request.GetResponse();

02.08.2010 - 07:27 Uhr

Ich hatte ähnliche Probleme wie Du.

C# Postbuildereignis: Benutzerrechte des App-Ordner auf Vollzugriff setzen!?

Du wirst beim durchlesen merken, dass wir beide ähnliche Probleme haben. Ich habe das "neue config Model" dann wieder raus geschmissen und bediene mich der alten Anwendungskonfigurationsdatei die man im VS über "Komponenten hinzufügen" ins Projekt einfügt. Die alte Anwendungskonfigurationsdatei lässt sich nicht ganz so komfortabel nutzen wie das neue Model, aber erfüllt seinen Zweck. Zumindest meinen, da ich in der config ständig Parameter ändern muss.

28.07.2010 - 10:01 Uhr

Tastatureingaben kannst Du über die WinAPI ermitteln und dann entsprechend im Programm weiter verwenden. Ist allerdings kein leichtes Unterfangen. Wenn es das ist was Du suchst.

24.06.2010 - 15:39 Uhr

Was ist daran jetzt so schwer zu verstehen oder entspricht nicht dem, was Du meinst das es machen soll? Richtig. Ich denke wir haben die ganze Zeit einfach aneinander vorbei geredet.
Es geht mir nicht darum, dass der Benutzer persönliche Einstellungen sichern kann. Im aktuellen Fall soll und kann der Benutzer nichts am Programm verändern.
Es ging mir darum das ich (am besten von Extern) für alle Benutzer gültig unzählige Variablen möglichst flexibel anpassen und ändern kann. Das geht bis hin zur Definition von Inhalten in Gridviews. Dafür wollte ich eben dummerweise die app.config verwenden. Mein Fehler. Ja ich habe mich nicht groß darüber informiert. Ich bin einfach davon ausgegangen, dass man in einer Konfigurationsdatei sein Programm möglichs flexibel konfigurieren kann. Jetzt weis ich es besser. Für meine Zwecke ist, dank der Benutzereinschränkungen des OS, dieses Model gänzlich ungeeignet.

24.06.2010 - 14:21 Uhr

Je mehr ich darüber lese, desto nutzloser wird die app.config in der aktuellen Form wie man es nutzen sollte. Ich hab mir nun die Zeit genommen, und mit einem Admin zusammen (wegen der Rechte) die vorgeschlagenen Ordner angesehen.

Ich habe keine Ahnung wie das bei Euch ist, aber hier sind die Systeme komplett abgeriegelt. Weder unter Windows7 noch unter Vista sind die vorgeschlagenen Ordner zu gebrauchen. Alle Benutzer haben (mit Ausnahme der Admins) auf den Systemen ausschließlich Leserechte. Nur in Ihrem persönlichen Benutzerordner haben Sie Schreibrechte. Also selbst wenn ich meine Dateien in die von Euch vorgeschlagenen Ordner umlege, würde das nichts bringen. Da ich weiterhin nicht schreibend darauf zugreifen kann.

Ich frage mich wer sich so etwas ausgedacht hat.

Ich werde versuchen mein Problem mit cacls zu lösen. Wie kann man sich nur so etwas ausdenken. Ist das nach einem feucht fröhlichen Betriebsfest entstanden?

Danke nochmals für die Hilfe. Ich werde später noch eine "Lösung" nachreichen wenn ich rausgefunden habe wie ich cacls in mein Setup einbaue.

24.06.2010 - 09:43 Uhr

Es mag der falsche Weg sein.
Aber ich habe keine Lust mir einen Wolf im Programm zu schreiben und alles umzubiegen, nur weil ich keine Schreibrechte im Ordner meines eigenen Programms habe.
Ich kann auch nicht jedesmal ein Update coden wenn mal eben an einem Arbeitsplatz etwas in der Konfiguration geändert werden muss. Was an sich schon ein Wiederspruch in sich ist. Wer braucht schon eine Konfigurationsdatei die er nur zur Entwicklungszeit oder durch ein Update ändern kann. Wenn ich Variablen brauche die ich nur 1x setzen muss und die sich dann nie wieder ändern, dann kann man das auch direkt in den Code schreiben. Dafür braucht es ja wohl keine Konfigurationsdatei.
Und die Administratoren werden sich sicher freuen, wenn ich sie jedesmal rufen muss um etwas ändern zu können. Vor allem muss sowas ja dann auch zeitnah umgesetzt werden.

Dann ist es eben Quick & Dirty. Wenn ich mir dadurch Arbeit spare (und anderen) ist mir das egal. Ist ja nun nicht so dass ich einem wildfremden Code Administrationsrechte fürs System einräumen will. Die Ordner UserApp kommen nicht in Frage, da jeder User ja seinen eigenen hat. Ich kann ja kaum x Mitarbeiter antanzen lassen wenn es eine Änderung in der Konfiguration gibt. Und bei uns gibt es keinen Common Ordner. Gelöscht, versteckt, was auch immer. Der Ordner ist zumindest nicht da wo er sein sollte.

Wie auch immer. Gibt oder gibt es keinen Weg, über den Installer die Benutzerrechte einer bestimmten Gruppe neu zu setzen? Und wenn Ja, welche? Wenn ich demnächst die Zeit dazu finde werde ich mich auch gern mit Alternativen beschäftigen um in Zukunft wieder konform zu arbeiten. Versprochen. ^^

24.06.2010 - 07:13 Uhr

Guten Morgen,

danke für die Rückmeldungen. Dann verstehe ich das Thema Konfiguration wohl einfach nicht. Nach meiner Vorstellung waren Konfigurationsdateien dafür da, ein Programm zu konfigurieren. Und zwar nachdem die Software ausgerollt wurde, und nicht während der Programmierung. Sorry das ich hier wohl einfach unwissend bin.

Dann steh ich wieder dort wo ich angefangen hatte. Mit welchen Mitteln kann ich dem Installer beibringen im Zielordner die Rechte einer Benutzergruppe zu ändern? Den Aussagen im Link und hier nach muss das ja möglich sein.

PS: Elevation ist nicht was ich suche. Nicht das Programm braucht Administrationsrechte. Die Standard Benutzergruppe braucht "nur" Schreibrechte im Installationsordner der Anwendung.

23.06.2010 - 13:51 Uhr

Danke für die Links. Es ist nicht so das ich das Konfigurationsmodel nicht kenne. Auch dieses Model legt ungeniert in den Programmordner eine <name>.exe.config Datei in der sich die, über Settings im Projekt eingetragene Variablen und Werte befinden. Also nichts anderes, als das was ich bisher schon über "Komponente hinzufügen... > Anwendungskonfigurationsdatei" gemacht habe. Der user.config Teil kann hier getrost ignoriert werden, da die User nichts zu konfigurieren haben.

Ob nun händisch die app.config oder über das Konfigurationsmodel hinzugefügt. Es ist und bleibt eine <name>.exe.config Datei im Programmordner. Wie gesagt ich meine nicht die user.config.

Ich versuche nochmal mein Problem genau zu schildern:
Es geht nicht darum das der User persönliche Programmeinstellungen abspeichern kann, sondern darum, Variablen, Datenbankverbindungen usw. für alle Anwender gültige zu speichern.
Die Installation der Setup.msi kann nur von einem Administrator ausgeführt werden. Der normale Benutzer hat im Installations-/ Applikationspfad nur eingeschränkte Rechte (was an sich ja auch in Ordnung ist). Allerdings bin auch ich "nur" Benutzer in diesem Netzwerk. Ich kann also meine eigene Konfigurationsdatei, die vom Setup.msi ja in den Programmordner mit abgelegt hat nicht anpassen, da ich nur Leserechte aber keine Schreibrechte habe.

Das Programm startet natürlich Problemlos ohne Vollzugriff auf den eigenen Ordner. Bis zu dem Zeitpunkt wo es Werte aus der Konfigurationsdatei ausliest. Da ich diese nicht an den einzelnen Arbeitsplatz anpassen kann, gibt es natürlich Probleme. Falscher Datenbankpfad usw.

Ich brauche schreibenden Zugriff auf die <programmname>.exe.config. Der Installer legt diese Datei im Applikationsorder ab. Auch wenn es sich dabei um die config des Konfigurationssystem von .NET 2.0 handelt. Erstelle ich ein Setup in meinem Projekt landet die config im Programmordner.

Jetzt habe ich 3 Möglichkeiten.

  1. Ich bringe der Setup.msi bei diese app.exe.config Datei dort zu speichern wo ich, als Mitglied der Gruppe "Benutzer" schreibrechte habe. Und natürlich meinem Programm das es seine Konfigurationsdatei nicht im eigenen Programmordner findet sondern irgendwo anders.

  2. Ich bringe der Setup.msi bei dem Programmordner bzw. der Gruppe Benutzer für diesen Programmordner "Vollzugriff" einzuräumen.

  3. Ich lasse jedesmal einen Admin antanzen der mir die Konfigurationsdatei mit Administrationsrechten öffnet damit ich diese ändern kann.

Punkt 3 ist wohl kaum Praktikabel. Wir reden hier nicht von 1 oder 2 Rechnern.
Punkt 2 ist sicherlich nicht der Königsweg, würde aber seinen Zweck erfüllen und die Systemsicherheit nicht großartig gefärden (da es nur um den Programmordner geht)

Wenn jemand einen Weg zu Punkt 1 kennt nur her damit. Dann könnte ich Global fürs komplette Netzwerk eine einzige Konfigurationsdatei verwenden.

Aber aktuell suche ich noch immer nach einer Lösung zu Punkt 2. Da suche ich Hilfe und finde keine. 😃

Danke

23.06.2010 - 08:18 Uhr

Nein, und das ist auch gut so.
Die Admins werden dir auf den Kopf steigen, wenn du deren Sicherheitsmechanismen umgehen willst.

Es ist ja nicht so, das ich dem gemeinen User Vollzugriff auf das gesamte System einräumen will. Es geht hier ausschließlich um den von meinem Setup, während der Installation, erzeugten Programm Ordner inkl. Unterverzeichnisse.

Zwischenzeitlich bin ich auf den Namespace System.Security gestoßen. Allerdings finde ich auch hier nur Beispiele mit denen man aus einem laufenden Programm heraus Berechtigungen setzen, ändern oder löschen kann. Wieder nichts das sich auf die reine Installationsroutine bezieht.

Nur warum meinst Du das machen zu wollen?
Die app.settings haben einen Userpart, der nicht im App ordner sondern im Roaming Bereich steht.
Und Logfiles kann man viel besser im ProgrammData Ablegen, beides komplett legal, auch unter W7 . App.settings schön und gut. Wunderbar um Benutzerspezifische Programmeinstellungen zu speichern. Wieso gibt es die app.config über die man, ohne das Programm starten zu müssen, Datenbankpfade und grundlegende Programmvariablen (wie z.B. den Inhalt von Comboboxen) setzen kann? Wenn man dann anschließend keine Zugriffsrechte hat diese Werte auch zu setzen/ändern.

Oder ist das ganze nur ein Plagiat? Ist die app.config nur ein Schaumschläger, der nur nach Konfiguration aussieht aber nicht verwendet werden darf? Ist meine Vorstellung etwa falsch, die Applikationskonfigurationsdatei dafür zu verwenden mein Programm zu "konfigurieren"?
Das ProgrammData werde ich mir ansehen. Danke für den Hinweis.

22.06.2010 - 14:28 Uhr

Hallo zusammen,

folgende Situation.

Mein Programm wird in einem Windowsnetzwerk eingesetzt. Als Systeme sind Vista und W7 im Einsatz. Wie es in einem Netzwerk sein sollte hat der gemeine User natürlich keine Rechte Programme zu installieren. Das Programm wird automatisch über einen Server verteilt und installiert sich (mit Adminrechten) selbstständig. Soweit ist alles noch in Ordnung.
Das Programm beinhaltet eine app.config Datei in der ich Verzeichnispfade & Werte definieren kann. Desweiteren schreibt das Programm Logfiles in den Installationsordner.

Und hier beginnen meine Probleme.
Da normale Benutzer nur leserechte haben, kann ich ohne einen Administrator die Konfigurationsdatei nicht ändern. Auch das Programm selbst kann in seinem eigenen Installationspfad keine Logdateien erstellen. Erst wenn der Administrator der Benutzergruppe Vollzugriff auf den Installationsordner einräumt klappt das.

Jetzt muss das ganze doch irgendwie möglich sein, das ich während der Installation die Benutzerrechte auf Vollzugriff setze. Ich bin im Setup Projekt über das Prä- und Postbuildereignis gestolpert. Nun suche ich seit 2 Tagen nach einer Möglichkeit wie ich die Zugriffsrechte eines Ordners nach der Installation setzen kann. Ich finde aber nur Infos und Beispiele mit Dateien kopieren, Merge usw. Leider aber nicht zum Thema Benutzerrechte.

Meine Frage, ist es überhaupt möglich das Problem über das Buildereignis zu lösen? Gibt es andere Möglichkeiten so etwas umzusetzen?

Danke für eure Rückmeldungen.

27.05.2010 - 06:54 Uhr

Nochmals vielen Dank an alle für die Tipps und Hilfen.
Bisher habe ich das Problem noch nicht lösen können. Spy++ zeigt mir keine verwertbaren Schnittstellen an, die ich ansprechen könnte. Sollte ich noch eine Lösung finden werde ich diese nachreichen.

17.05.2010 - 12:25 Uhr

Vielen Dank JAck30lena, das bringt mich schon ein ganzes Stück weiter.

Ich hab nun etwas mit der User32.dll herum gespielt. FindWindow & MoveWindow Funktioniert soweit schon ganz gut. Das lässt mich hoffen, das ich das irgendwie doch noch umsetzen kann.

Jetzt stehe ich vor der Herausforderung, meine Werte dort hinzuschreiben wo sie hin gehören. Gibt es einen "Trick" herauszufinden, wie der Hersteller der Fremdsoftware seine Felder und Buttons benannt hat, und ob überhaupt die Möglichkeit besteht diese von extern anzusprechen?

Ich werde jetzt erst mal ein wenig weiter tüfteln, mal sehen ob ich meine Werte testweise in Excel und Word schreiben kann.

17.05.2010 - 10:09 Uhr

Hallo zusammen,
ich habe folgendes Problem:

Ich möchte aus meiner Anwendung heraus Werte (Zahlen und/oder Text) automatisch an eine Anwendung (beliebige) übergeben, ohne das der User mit der Zwischenablage arbeiten muss.

Er soll in meiner Anwendung einen Button drücken, woraufhin dann in eine 2te beliebige Anwendung (Fremdsoftware) automatisch der Wert in ein frei zu definierendes Feld eingetragen wird. Unter Umständen sollen auch noch andere Aktionen ausgeführt werden, wie z.B. ein Mausklick usw.

Ich möchte dem User damit Arbeit abnehmen. Das er nicht jedesmal in meiner Anwendung auf den Button klicken muss, anschließend in die andere Anwendung wechseln muss um über <STRG> + <V> den Wert dort "Manuel“ einzufügen.

Gibt es eine Möglichkeit so etwas umzusetzen?
Danke für die Antworten.

04.05.2010 - 09:28 Uhr

Vielen Dank noch mal für die Hilfe. Ich konnte damit mein Problem lösen.
Hier noch mein Aufruf für alle die vielleicht mal mit ähnlichen Problemen kämpfen und Hilfe suchen. Ich kann nicht sagen ob es eine elegante Lösung ist, aber zumindest bei mir funktioniert es so.

Aufruf der API

        
        //Methode zum auslesen des Gerätenamens
        public string USBGeräteName()
        {
            StringBuilder sbStr = new StringBuilder();
            // Get List of all USB Devices
            int intGerät = API.ListAllDeviceNames(sbStr, 254);
            if (intGerät == 0)  // 0 = Fehler
            {
                Error er = new Error();
                er.GetLastError(); 
            }
            return sbStr.ToString();
        }

Und der Aufruf der VC++ 6.0 DLL


        //Seriennummer/Gerätename USB Geräte
        [DllImport("hardware.dll")]
        public static extern int ListAllDeviceNames([Out][MarshalAs(UnmanagedType.LPStr)]StringBuilder NamenListe, int BufferSize);

Thema erledigt !!

26.04.2010 - 10:24 Uhr

Vielen Dank für die schnellen Antworten. Ich werde mich heute in das Thema einlesen und versuchen das umzusetzen.

22.04.2010 - 16:03 Uhr

Hallo zusammen, bin neu hier im Forum und komme gleich mit einer vermutlich dummen Frage. Seit 2 Tagen suche ich nun erfolglos nach einer Lösung für mein Problem.

Ausgangssituation:
Ich habe am Rechner ein Lese/Schreibgerät via USB angeschlossen. Dazu habe ich vom Hersteller eine DLL (geschrieben in VC++ 6) und ein paar Codebeispiele (VC++ 6 & VB 6). Es gibt auch eine lauffähige Software, die allerdings nicht meinen Anforderungen entspricht.

Nun wollte ich mit C# (VS2008) ein eigenes Programm schreiben mit dem ich das Lese/Schreibgerät ansteuern kann.

Problemstellung:

Den DLL Aufruf hab ich in eine Klasse im Projekt gepackt.
Das ganze Funktioniert auch soweit mit anderen aufrufen wie z.B.

// Port öffnen/auslesen
[DllImport("hardware.dll")]
public static extern int OpenPort(string strInterfaceName, int Baudrate, int Timeout);

An den Interface Namen, den man für den Aufruf benötigt, bin ich "manuell" über die Software des Herstellers gekommen. Und hier beginnen auch meine Probleme. Laut DLL soll der folgende Aufruf mir den Namen des Angeschlossenen Gerätes liefern.

//Seriennummer/Gerätename USB Geräte
[DllImport("hardware.dll")]
public static extern unsafe int ListAllDeviceNames(char* NamenListe, int BufferSize);

Laut C++ Beispielcode soll man damit den Gerätenamen auslesen können.

int nMaxSize = 255;
char * USBNamesBuffer = new char[nMaxSize];
CStringList USBListe;
CString strName;
int nLen = ListAllDeviceNames(USBNamesBuffer,nMaxSize);
int nStrLen = 0;
do
{
strName = USBNamesBuffer + nStrLen;
nStrLen += strName.GetLength() + 1;
if(strName.GetLength() != 0)
USBListe.AddTail(strName);
}while(strName.GetLength() != 0);
delete USBNamesBuffer;

Ich hab nun versucht das irgendwie in C# unterzubringen. Der CountAllDevices Aufruf funktioniert noch und liefert mir als Wert eine 1.

private string USBName()
{
int iAnzahl = USBclass.CountAllDevices();
int iBufferSize = iAnzahl * 9 + 1;
// Get List of all USB Devices
unsafe
{
int nMaxSize = 255;
char* USBNamesBuffer = new char[nMaxSize];
string USBListe;
string strName;
USBclass.ListAllDeviceNames(USBNamesBuffer, iBufferSize);
      //rest erst einmal weg gelassen weil der Debugger überhaupt nicht so weit kommt.
return iBufferSize.toString();

Was mir der Debugger meldet:

Eine implizite Konvertierung vom Typ "char[]" in "char*" ist nicht möglich.

char* USBNamesBuffer = new char[nMaxSize];

Ändere ich das ganze ab, bleibt der Debugger beim Aufruf hängen.
1-Argument: kann nicht von "char[]" in "char*" konvertiert werden.

char[] USBNamesBuffer = new char[nMaxSize];

Ich habe keine Ahnung wie ich das abfangen kann. Ich hab mich nun 2 Tage lang bis hier hin durchgehangelt und komme nun einfach nicht mehr weiter. Ich habe was mit "Reflections" gefunden, aber nicht wirklich verstanden. Ich bin noch nicht dahinter gestiegen wie ich das umsetzen soll und ob mir das überhaupt hilft.

Entschuldigt meine dumme Frage. Ich hoffe das mir bei meinem Problem jemand helfen kann. Vielen Dank schon mal.