Autor Beitrag
Kelrycor
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Do 17.02.11 09:51 
Hallo,

bin relativ neu in C#, habe allerdings Kenntnisse einiger anderer Programmier-/Codesprachen (PHP, C, Perl, VBA, etc.), und tue mich zwar noch schwer, bin aber weit gekommen und ein soweit gut lauffähiges Programm zu schreiben.

Ich stehe nun mit SharpDevelop 2.2 vor einem für mich scheinabr unlösbaren Problem und brauche unedingt Hilfe oder gute Tipps.

Ich habe ein Windows-Form Projekt generiert, in dem ich eine Formular öffne, dabei werden diverse Fehlersituation beim Starten abgefangen, ein Datenbankzugriff geöffnet und letztlich dem Anwender eine Suchmaske für die Datenbank angeboten. Das einzelne Suchergebnis wird im Ausgabeteil des Formulars (MainForm) ausgegeben. Technisch funktioniert es einwandfrei - wenn ich die kompilierte .EXE jedoch auf einem anderen PC, unter einem anderen Profil/Benutzerkonto ausführe, startet die .EXE einfach nicht (ist rund 1-2 Sekunden im Prozessmanager, und schliesst sich sang und klanglos). Als Anwender bekomme ich keinerlei Rückmeldung, warum.

Ich konnte den Fehler auf die Klasse für die Fehlerprüfung eingrenzen (wird beim öffnen der MainForm automatisch ausgeführt), befindet sich eine Funktion, in der ich 2 Schlüssel in der Windows-Registry prüfe. Kommentiere ich den Zugriff via "RegistryKey" aus, und kompiliere es, dann funktioniert das Programm auf anderen PCs - ich brauche den Zugriff auf die Windows-Registrierung allerdings zwingend. Die anderen PCs in unserem Netzwerk haben alle "Framework 4.0 Client" installiert und laufen alle auch auf WinXP x32.

Ich habe hier einmal den grundlegenden Code (reduziert auf des Pudels-Kern):

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
using System;
using System.Collections;        // ArrayList verwenden
using System.Drawing;          
using System.IO;          // Dateizugriffe verwenden
using System.Text.RegularExpressions;           // RegEx Funktionalitäten einbinden
using System.Windows.Forms;               // Formulare verwenden
using Microsoft.Win32;        // Windows-Registry-Zugriff

namespace Suchprogramm
{
  public partial class MainForm : Form
  {
    public MainForm()
    {
      InitializeComponent();
      Ladebildschirm();
    }
    
    private void Ladebildschirm()
    {
      // Initialisiere KeyPress-Event für tb-Box um Enter-Taste zu finden
      this.tb_searchfield.KeyPress += new System.Windows.Forms.KeyPressEventHandler(keyPress);
      
      // Programmladebildschirm

      // Variablen deklarieren
      string db_version_client_path;
      string db_version_notebook_path;
      string db_version_client;
      string db_version_notebook;
      string szSrcLine;
      bool failure=false;
      ArrayList database = new ArrayList();
          
      // Initialisieren
      db_version_client_path = "\\\\PC0001\\HSdbC\\";
      db_version_notebook_path = "\\\\PC0001\\HSdbM\\";
      this.lb_db_count.Text="0";
      this.lb_version.Text=GlobalClass.Version;
      
      Application.DoEvents(); 
      
      [...]
      
      // Lese Arbeitsort des Anwenders aus Registry
      RegistryKey pathKey = Registry.CurrentUser.OpenSubKey("Firma").OpenSubKey("Zweigstelle");
      string check = pathKey.GetValue("Bezeichnung").ToString();
      pathKey.Close();
      
      // Prüfe MitAgliedschaft in Sicherheitsgruppe Administratoren? 
      RegistryKey pathKey2 = Registry.CurrentUser.OpenSubKey("Firma").OpenSubKey("Gruppen");
      string check2 = pathKey2.GetValue("SubAdmins").ToString();
      pathKey2.Close();
      
      [...]
} } }


Nehme ich den Teil zwischen denn beiden [...] raus, dann geht das Programm auf anderen Rechnern. -.-
Die Registry-Schlüssel sind aber ach auf anderen PCs da.

Mir ist klar, dass C# Referenzen und so manche DLL braucht. Ich habe allerdigns keine Ahnung, ob für "Microsoft.Win32" eine extra Referenz benötigt wird, oder wenn eine DLL, welche das sein soll. Habe nichts dazu im Netz gefunden. Im Release-Ordner generiert er mir lediglich eine .EXE (keine zusätzlichen DLLs oder andere Dateien, die ich mitverteilen müsste - Debugdateien hab ich generell ausgeschalten).
Die "mscorlib.dll" lasse ich mitreferenzieren. Ich habe auch schon probiert dasselbe Projekt auf Framework .NET 4.0 (+Clients) mit SharpDevelop 4.0 zu konvertieren und zu kompilieren - ohne Erfolg. Es bleibt beim selben Erscheinungsbild, dass die Anwendung einfach nicht startet, bzw. ohne das Formular anzuzeigen sich beendet.

Es muss höchstwahrscheinlich an einer fehlenden Referenz oder DLL liegen - ich hab aber leider keinen blassen Schimmer, welche.

hat jemand von euch eine Idee dazu?

Schonmal Danke für die Mühen und fürs Lesen ;)
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4799
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Do 17.02.11 11:51 
Hallo,

ich tippe eher auf fehlende Berechtigungen (Lesen/Schreiben der Registry) o.ä.

Wenn eine DLL fehlen würde, so würde der Prozess gar nicht erst gestartet werden (außer die DLLs sind per "Late Binding" hinzugefügt, aber du verwendest ja die automatischen Verweise).

Wie sieht denn deine Main()-Methode aus? Unterdrückst du dort irgendwelche Exceptions?

Ansonsten lass dir einfach mal die Exception ausgeben:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
try
{
  // ...
}
catch(Exception ex)
{
  MessageBox.Show(ex.Message); // bzw. wenn du mehr Infos (mit CallStack) haben willst: ex.ToString()
}

Für diesen Beitrag haben gedankt: Kelrycor
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 17.02.11 12:02 
Ich würde dir empfehlen den ganzen Code nicht im Constructor auszuführen sondern das in einen Event der nach der Formanzeige stattfindet zu verschieben also z.b. in den Shown Event.
Erstens wird mir ganz komisch wenn ich ein Application.DoEvents() sehe der im Constructor aufgerufen wird der sollte dann unnötig sein(wofür der bisher auch immer gut war) und zweitens zieht dann das standardmäßige Exceptionhandling von Winforms das dir im Constructor der Mainform noch entgeht.

Für diesen Beitrag haben gedankt: Kelrycor
Kelrycor Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Do 17.02.11 13:20 
@Ralf Jansen:
Die Application.DoEvents(); kamen ursprünglich aus meinem versuche einen Art Ladebalken bei den "Vorchecks" anzuzeigen. Geht aber nicht, weil er erst nach Abschluss der Initialisierung das Formular scheinbar erstmalig aufbaut - ist mir aber auch im Moment nicht so wichtig. Mit deinem Hinweis aber könnte dies aber wohl funktionieren? Muss ich im Nachhinein mal in Angriff nehmen. Danke :)

@TH69:
Danke - die Sache mit dem "Try" hatte ich schon irgendwo gelesen, aber garnicht realisiert, dass es hier wohl sehr nützlich sein könnte. Ich habe das mal eingebaut - und, ich bekomme jetzt endlich mal ein Feedback vom Programm:

"System.NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt. bei Programm.MainForm.Ladebildschirm()"

Zugriff auf die Windows-Registry habe ich definitiv, da ich mit Administratorkennungen arbeite. Die Schlüssel, die ich aufrufe, sind vorhanden. Und wenn nicht, hatte ich eigentlich ein ExceptionHandling eingebaut, welches dann zumindest das Weiterlaufen des Programmes sichern müsste, und eine entsprechende Meldung generieren sollte. Im Test auf dem eigenen Rechenr hat dies auch einwandfrei funtkioniert -.-

Wie bekomme ich heruas, welchen "Objektverweis" er meint?
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19326
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 17.02.11 14:43 
Indem du sauber arbeitest und den Rückgabewert von z.B. OpenSubKey prüfst bevor du ihn verwendest...
Der kann ja auch NULL sein...

Für diesen Beitrag haben gedankt: Kelrycor
Kelrycor Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Mo 21.02.11 14:36 
@Jaenicke:
Klasse - genau das war's. OpenSubKey scheint nicht wie GetValue mit nicht vorhandenen Objekten klar zu kommen. Das war mein Denkfehler. Ich hatte das zwar vermutet, da ich zu GetValue gelesen habe, dass anscheinend imemr ein Rückgabeweret errfolgt (und durch löschen des Schlüssels hatte ich das auch mal getestet, aber bei OpenSubKey leider nicht :roll:

Jetzt habe ich mit Try und Catch nen ordentlichen ExceptionHandling eingebaut und hab das Programm zum laufen bekommen, wie es soll. :rofl:

Vielen Dank an alle, die ihr mir hier geholfen habt - ihr seit meine Helden :flehan: