Avatar billede neocron Nybegynder
03. februar 2005 - 16:38 Der er 15 kommentarer og
1 løsning

FileNotFoundException med inkluderet DLL-fil.

Hej. Jeg sidder og leger med at få et C# program og en C# dll (begge hjemmelavede) til at fungere sammen. Det virker fint og uden problemer.

Men hvis man sletter dll filen, vil programmet naturligvis fejle med en System.IO.FileNotFoundException.

Jeg har dog lidt problemer med at omskrive denne exception så der bare kommer en messagebox ala MessageBox.Show("Ingen fil!");

Jeg er kommet frem til den konklusion, at den kode, der skal til, må skulle placeres i classens constructor og at det sikkert er noget try-catch (jeg har prøvet file- altså

public Form1()
{
    // Her skal jeg gerne have noget try-catch eller lign. ind
    // som giver fejlhåndtering på indlæsningen af dll'en.
    InitializeComponent();
}

Håber, I kan hjælpe :)

- Som en ekstra note, så har jeg forsøgt mig med:

if(!File.Exists("w32mtopr.dll"))
{
    MessageBox.Show("Filen findes ikke!");
    Application.Exit();
}

... Som ikke virker - den kaster stadig en exception.
Avatar billede neocron Nybegynder
03. februar 2005 - 16:42 #1
Jeg har også just forsøgt at omkranse InitializeComponent med en try-catch, men det hjalp heller ikke.
Avatar billede arne_v Ekspert
03. februar 2005 - 16:48 #2
Du kan ikke fange den fejl med try catch i normal kode fordi der bliver
testet for tilstedeværelse af DLL inden dit program startes.

Du kan kun gøre det hvis du loader den DLL dynamisk (Assembly.Load).
Avatar billede neocron Nybegynder
03. februar 2005 - 17:19 #3
Jeg vil lige prøve at kigge på det. Har fundet en side, jeg vil dog ikke afvise at jeg kan få brug for hjælp til et konkret eksempel af Assembly.Load :)
Avatar billede neocron Nybegynder
03. februar 2005 - 17:24 #4
Okay, jeg er ret meget usikker på den.
Hvis jeg f.eks. i constructoren (Windows Application) skriver:

Assembly LoadDLL;
LoadDLL = Assembly.Load("w32mtopr.dll");

Hvorledes tilgår jeg så denne i nedenstående funktion, således at funktionen bliver kaldt:

private void button1_Click(object sender, System.EventArgs e)
{
    // udfør fiktiv funktion TalPlus() i Dll'en
}
Avatar billede arne_v Ekspert
03. februar 2005 - 17:52 #5
Object o = Assembly.Load("DinDll").CreateInstance("DinKlasse");
o.GetType().InvokeMember("DinMetode",                                      BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, o, null);

eller noget lignende - jeg har tastet det ind efter noget kode i en lidt
anden kontekst
Avatar billede arne_v Ekspert
03. februar 2005 - 18:33 #6
Følgende virker.

DinAssembly.cs
--------------

using System;

public class DinKlasse
{
    public void DinMetode()
    {
        Console.WriteLine("Det virker");
    }
}

Test.cs
--------

using System;
using System.Reflection;

public class TestKlasse
{
    public static void Main(string[] args)
    {
        Object o = Assembly.Load("DinAssembly").CreateInstance("DinKlasse");
        o.GetType().InvokeMember("DinMetode", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, o, null);
    }
}
Avatar billede neocron Nybegynder
03. februar 2005 - 18:46 #7
Jeg vil straks afprøve det - og vende tilbage om kort tid.
Avatar billede arne_v Ekspert
03. februar 2005 - 18:46 #8
Ja - jeg catcher jo ikke nogen exception, men det kan du !
Avatar billede lifo Nybegynder
03. februar 2005 - 18:47 #9
tror at du kan fange den exception i ThreadException
der kan du fange alle exceptions som ikke bliver fanget andre steder

Application.ThreadException+=new ThreadExceptionEventHandler(Application_ThreadException);

private void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
// lav et eller andet
}
Avatar billede neocron Nybegynder
03. februar 2005 - 18:54 #10
Nu har jeg så ikke lavet dll'en som en del af projektet, men som en separat dll fil - så følgende virker ikke (dll'en ligger i samme bibliotek som .exe filen):

object o = Assembly.Load("w32mtopr.dll").CreateInstance("DllClass1");
            textBox1.Text = o.GetType().InvokeMember("PrintText", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, o, null).ToString();

Som et andet spørgsmål -

o.GetType().InvokeMember("DinMetode", [...]

Hvordan gør man her, hvis ens metode tager argumenter? Mest fordi at metodenavnet er skrevet i string-quotes. F.eks. hvis metoden hed DinMetode(a, b).
Avatar billede neocron Nybegynder
03. februar 2005 - 19:00 #11
Okay, nu er jeg kommet lidt videre, jeg skal tydeligvis kalde dll-filen som "navn" istedetfor "navn.dll". Men et andet problem er så kommet - endnu en exception -

NullReferenceException.
I denne linje:

textBox1.Text = (string)o.GetType().InvokeMember("PrintText", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, o, null);

Kan ikke umiddelbart se, hvad der forårsager den.
Avatar billede arne_v Ekspert
03. februar 2005 - 19:01 #12
using System;

public class DinKlasse
{
    public void DinMetode()
    {
        Console.WriteLine("Det virker");
    }
    public void DinAndenMetode(int iv, string sv)
    {
        Console.WriteLine(iv + " " + sv);
    }
}
Avatar billede arne_v Ekspert
03. februar 2005 - 19:01 #13
using System;
using System.Reflection;

public class TestKlasse
{
    public static void Main(string[] args)
    {
        Object o = Assembly.Load("DinAssembly").CreateInstance("DinKlasse");
        o.GetType().InvokeMember("DinMetode", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, o, null);
        Object[] margs = { 123, "ABC" };
        o.GetType().InvokeMember("DinAndenMetode", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, o, margs);
    }
}
Avatar billede arne_v Ekspert
03. februar 2005 - 19:02 #14
De 2 sidste var eksempel på argumenter.

Med hensyn til din null pointer exception så skal du nok undersøge lidt nærmere
hvad der sker.

Har du verifieceret at du kan catche situationen med ingen DLL ?
Avatar billede neocron Nybegynder
03. februar 2005 - 19:34 #15
Ja, nu kan jeg fjerne den grimme standard exception boks - sådan ser det fungerende eksempel ud.

try
{
    object o = Assembly.Load("w32mtopr").CreateInstance("DllClass1");
    MessageBox.Show("DLL loadet!");
}
catch
{
    MessageBox.Show("Ingen DLL");
}

Jeg vil prøve at snuse lidt videre med den NullReference. Du kan smide et svar imens.
Avatar billede arne_v Ekspert
03. februar 2005 - 19:37 #16
svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester