Avatar billede zuran Nybegynder
14. juni 2009 - 01:04 Der er 29 kommentarer og
1 løsning

Adgang til mappe nægtet

Hej.

Jeg anvender en mindre søgefunktion i min applikation, for at lede efter nogle filer, men der opstår et problem en gang imellem.

Problemet er, at når der bliver så søgt, så stødes der pludselig på en mappe (F.eks en nødvendig en fra Microsoft), hvorefter adgangen bliver nægtet (UnauthorizedAccessException).

Til at søge, bruger jeg en DirectoryInfo klasse, samt en FileInfo klasse, begge fra System.IO. Og så nedenstående:

GetFiles("*.*", SearchOption.AllDirectories);

Jeg har så prøvet, at give adgang, ved at oprette en DirectorySecurity klasse (Så indsætte de nuvæende rettigheder til klassen), så tilføje en ny rettighed (Har prøvet med lidt forskellige, og gik til sidst over til FullControl, for at se om det gjorde nogen forskel):

AddAccessRule(new FileSystemAccessRule(System.Security.Principal.WindowsIdentity.GetCurrent().Name, FileSystemRights.FullControl, AccessControlType.Allow));

Til sidst sætter jeg så min DirectoryInfo klasse's AccessContol til DirectorySecurity klassen.

Det gør dog ikke rigtig nogen forskel - adgangen bliver stadig nægtet ved forskellige mapper.

Håber på noget hjælp, tak på forhånd.
Avatar billede Syska Mester
14. juni 2009 - 01:36 #1
Har din egen bruger som kører din app reelt adgang til den mappe ?

Hvad er det for en nødvendig mappe fra microsoft ?
Avatar billede thesurfer Nybegynder
14. juni 2009 - 01:40 #2
Hvis det f.eks. er "C:\System Volume Information" (eller andre dreve), får du nok aldrig adgang til mappen (eller lignende mapper)..
Avatar billede zuran Nybegynder
14. juni 2009 - 13:32 #3
Hej med jer.

Nej, jeg har ikke adgang til mappen, hvis jeg selv prøver at tilgå den.

Som jeg kan høre på dig thesurfer, så vil det måske ikke kunne lade sig gøre, at skabe adgang til mappen.

Ligger en af jer, så muligvis inde med en ide til, hvordan man kan springe alle de mapper over, som man ikke har adgang til?

// Lige et side spørgsmål, som jeg gerne giver ekstra point for: Når der nu søges, med den metode jeg har skrevet ovenfor, så foregår det hele i et stort (Alt efter søgeplaceringens antal filer) "lag", hvorefter resultaterne kommer frem. Det må være muligt, at søge gennem en fil ad gangen (Om det tager lidt længere tid generer mig ikke), hvorved dette lag ikke vil opstå? Det ses f.eks. ved antivira når der scannes (Så har man mulighed for at følge med i, hvilken fil den er nået til)

Tak på forhånd.
Avatar billede thesurfer Nybegynder
14. juni 2009 - 15:03 #4
Angående fejl / spring mapper og filer over:

Hvis du f.eks. bruger Try/Catch, kan du undgå at dit program crasher.

Eksempel med C#, som også findes til VB.NET, hvor jeg ikke har gjort så meget ud af case (store/små bogstaver, hvilket man skal huske):

try
{
int a = int.parse("dette er en streng som vil fejle da den forventer et tal");
} catch(Exception ex) {
messagebox.show("Der opstod en fejl: " + ex.message);
}

I det eksempel vil du få at vide, at "Der opstod en fejl: " samt selve fejlmeddelelsen, som er noget i stil med "et tal var forventet men den angivne værdi er en streng"..


Angående "lag" / programmet fryser:

Problemet er at du afvikler din søgefunktion direkte fra din form.
Det vil automatisk optage hele formen/applikationen.
Løsningen er at smide søgefunktionen i en separat tråd.

Noget i stil med

public void soeg()
{
  ... din søge kode her
}

og i din søge-knap:

publi...
{
Thread t = new Thread(new ThreadStarter(soeg);
t.isBackground = true;
t.start();
}

Husk at tilføje namespacet "System.Threading".


Konklusion:

Lav en søgning på:
1) try catch
2) c# thread
Avatar billede thesurfer Nybegynder
14. juni 2009 - 15:06 #5
Jeg kan se at der mangler en slut ")" i Thread-linien, som skal se sådan ud:

Thread t = new Thread(new ThreadStarter(soeg));

Med hensyn til "isBackground = true", så betyder det at tråden skal afsluttes, hvis man lukke programmet (så den ikke hænger).

Og "t.start()" starter/aktiverer tråden..
Avatar billede zuran Nybegynder
14. juni 2009 - 16:11 #6
Jeg har nu prøvet med try og catch, hvilket umiddelbart virker korrekt, men pga. der altid stødes på en eller flere mapper, der ikke kan skabes adgang til, så springes hele GetFiles... funktionen over, således at ingen filer bliver hentet.

Mht. til Threading, for at programmet ikke giver et "lag", når der søges, så får jeg nu følgende fejlmeddelse:

Handling på tværs af tråde er ugyldig: Objektet 'searchProgress' blev åbnet fra en anden tråd end den tråd, det blev oprettet i.
Avatar billede zuran Nybegynder
14. juni 2009 - 16:13 #7
Mit Thread:

public void search()
{
// Søge koder her osv...
}

public void button1_Click(object sender, EventArgs e)
{
Thread searchThread = new Thread(new ThreadStart(search));
searchThread.IsBackground = true;
searchThread.Start();
}
Avatar billede thesurfer Nybegynder
14. juni 2009 - 16:27 #8
Angående try/catch:

Så har du nok smidt hele din kode i try/catch.. det skal man ikke.. :-)

Du skal kun smide det kritiske i din try/catch..

eksempel:

for...
{

  try
  {

    noget-der-kan-fejle-her

  } catch (Exception ex) {

    fejlhåndtering-indsættes-her

  } finally { // ny!

    hvis du opretter objekter i "TRY"-delen, som skal nedlægges,
    gøres det her, da "FINALLY" ALTID bliver afviklet,
    når man bruger en try/catch

  }

}



Angående "Handling på tværs af tråde"

Fra Visual Studio 2005 og opefter, kan tråde ikke få adgang til hinandens objekter.

Derfor skal man "invoke"..

Søg derfor efter: InvokeRequired

Der burde være mange løsninger her på eksperten.dk

Ellers kan Google give dig svaret.. :-)
Avatar billede zuran Nybegynder
14. juni 2009 - 17:36 #9
Nej, jeg har ikke smidt hele koden i try.

try
{
..........GetFiles("*.*", SearchOption.AllDirectories);
}

Pga. af det indenfor try { } fejler, så får den ikke fat i nogle filer. Meningen er jo, at den skal få fat i alle de filer, hvor den ikke fejler, men her får den slet ikke fat i nogle.

Jeg prøver lige at søge lidt rundt og kigge på Invoke :)
Avatar billede zuran Nybegynder
14. juni 2009 - 18:28 #10
Så skulle det med lag (Invoke) ihvertfald være på plads :)

Så er det blot det med at springe over de filer og mappe der ikke er adgang til
Avatar billede windcape Praktikant
14. juni 2009 - 22:21 #11
"Fra Visual Studio 2005 og opefter, kan tråde ikke få adgang til hinandens objekter."

-- Hvad er det for en omgang fis? Din version af et IDE har intet med C# at gøre!

Og jeg tvivler på at .NET 1.0 ikke havde nogen form for thread-safety.
Avatar billede thesurfer Nybegynder
15. juni 2009 - 01:43 #12
zuran> Hvis GetFiles er den funktion/metode der henter alle filerne, så har du "smidt hele koden inde i TRY"..

Det er ikke GetFiles der skal i TRY. Det er det inde i GetFiles, der kan gå galt, der skal inde i TRY..

Eksempel

public double GetFiles(double a, double b)
{

  double r = 0.0;

  try
  {

    r = a / b;

  } catch (Exception ex) {

    messagebox.show("Der opstod en fejl.. du dividerer vel ikke med 0??");

  }

  return r;

}

Det her går godt:
double resultat = GetFiles(10.0, 5.0);

Det her går skidt, da man ikke må dividere med 0:
double resultat = GetFiles(10.0, 0.0);

Læg mærke til at det kun er det kritiske, der skal i TRY, og ikke kaldet, da hele koden så ender i TRY.

Det var godt nok et meget simpelt eksempel, men jeg håber at du forstår det..

Pointen er den linie der opretter en forbindelse til mappen, skal i TRY. Det samme skal alt andet der er kritisk, for at man kan oprette forbindelse til mappen.

Hvis det stadigvæk ikke giver mening, vis mig din kode fra GetFiles, og jeg skal smide den korrekte kode ind i TRY.
Skriv evt hvilken linie den normalt crasher ved.. det vil hjælpe.




windcape> Fra VS 2005 og opefter, skal man invoke den grafiske brugergrænseflade (formens controls), fra den seperate tråd, hvis tråden skal opdaterer controlen.

Dette var (som standard) ikke påkrævet i VS 2003 (men kunne slåes til), da jeg arbejde med VS 2003.

Jeg manglede ordet "direkte" i min tidligere forklaring.. så giver det mere mening.

PS: Jeg nævnte ikke C#.. :-)
Avatar billede zuran Nybegynder
15. juni 2009 - 17:00 #13
Jeg forstår godt konceptet i at anvende TRY osv, men jeg kan ikke se, hvordan man skulle kunne gøre det, i netop det her tilfælde.

// Get all files
FileInfo[] fileList = folder.GetFiles("*.*", SearchOption.AllDirectories);

Overstående er den linje, der enter alle filerne, og også den linje der crasher.

Jeg har prøvet at smide den i en TRY, men det vil ikke hjælpe, da linjen så blot springes over, hvis den vil crashe, hvorved der ingen filer bliver hentet.

Du må hellere end gerne, vise mig hvordan det lige gøres i dette tilfælde, tak :)
Avatar billede thesurfer Nybegynder
15. juni 2009 - 21:51 #14
Ahh... jeg troede at "GetFiles" var en funktion du selv havde lavet.. :-)

Du må have mere koden end bare lige de her 2 linier:

// Get all files
FileInfo[] fileList = folder.GetFiles("*.*", SearchOption.AllDirectories);


Jo mere du overlader til .NET/systemet, jo mindre kontrol har du over koden.

Hvis det ikke kan løses med "folder.GetFiles", skal du selv programmere "løb mapperne igennem og check filerne"-koden.

Her vil du så kunne implementere TryCatch, uden problemer.
Avatar billede zuran Nybegynder
15. juni 2009 - 21:58 #15
Hm, så tror jeg umiddelbart ikke, at det ville kunne lade sig gøre med GetFiles metoden.

Fra start ledte jeg dog også efter en metode, til at få fat i en enkel fil i en mappe, og så kunne der blot smides en løkke på en lign, men jeg fandt aldrig andet en GetFiles metoden.

Måske du kender en metode, til at hente en enkel fil, og så via et loop kunne gå videre?

Ellers har jeg følgende kode:

// Get location
                DirectoryInfo folder = new DirectoryInfo(location.Text);

                // Set the maximum of searchProgress to the total number of files in the specified directory
                searchProgress.Maximum = folder.GetFiles("*.*", SearchOption.AllDirectories).Length;

                // Get all files
                FileInfo[] fileList = folder.GetFiles("*.*", SearchOption.AllDirectories);

Og så en foreach, der gør det muligt for mig at håndtere hver enkel fil, men det hjælper ikke meget mht. crash, når det er den anden linje der fejler.
Avatar billede windcape Praktikant
15. juni 2009 - 22:14 #16
"windcape> Fra VS 2005 og opefter, skal man invoke den grafiske brugergrænseflade (formens controls), fra den seperate tråd, hvis tråden skal opdaterer controlen.

Dette var (som standard) ikke påkrævet i VS 2003 (men kunne slåes til), da jeg arbejde med VS 2003."

Det har stadig intet med dit IDE at gøre. Og Visual Studio kan bruges til mange andre ting end Winforms ! Din forståelse af multi-threaded GUI lader til at være ikke eksisterende.
Avatar billede windcape Praktikant
15. juni 2009 - 22:19 #17
Derudover bør problemet løses ved enten ikke at benytte et AllDirectories flag, eller have en catch på UnauthorizedAccessException (catche alle exceptions for en explicit case er meget dumt).

Manuel iteration giver ikke særlig meget mening, når der er et API til formålet.

http://msdn.microsoft.com/en-us/library/ms143448.aspx
Avatar billede thesurfer Nybegynder
15. juni 2009 - 22:54 #18
windcape> Meningen er jo at man skal søge i nuværende mappe, og underliggende mapper. Den skal hente filerne ud af mapperne.

Men hvis du bruger .GetFiles (eller .GetDirectories) på "system volume information" mappen (eller en lignende mappe hvor man ikke kan få adgang), vil den crashe.

Man kommer ikke uden om dette problem, ved at bruge koden på det link du lige har smidt.

Der har man mulighederne "TopDirectoryOnly" eller "AllDirectories". Ingen af de to kan bruges i denne her situation.

Har jeg overset noget på dit link?


PS: Jeg har arbejdet på multi-threaded GUI før. Hvad mener at du at jeg "mangler" / ikke forstår?
Avatar billede thesurfer Nybegynder
15. juni 2009 - 23:03 #19
zuran>

Jeg har lavet et eksempel.. for at gøre koden så simpel som muligt, er koden ikke trådet.

Med andre ord: den låser formen indtil den er færdig med at læse/tælle filerne.

Du kan få fat i listen med filerne via "allfiles", som er et "List" fyldt med "FileInfo".

Så kan du f.eks. bruge:

foreach(FileInfo fi in allfiles)
{
noget her
}




Prøv lige det her:

1) tilføj denne linie i toppen:

using System.Collections;


2) Tilføj denne linie over din "public Form1()"-linie:

private List<FileInfo> allfiles = new List<FileInfo>();


3) Tilføj denne metode (håber ikke at Eksperten fjerner indrykningerne):

        private void dosearch(DirectoryInfo dir)
        {
            try
            {
                foreach (FileInfo fi in dir.GetFiles())
                {
                    allfiles.Add(fi);
                }
            }
            catch (Exception ex)
            {
                // skal ikke rigtigt bruges til noget
            }

            try
                {
                DirectoryInfo[] dirs = dir.GetDirectories();
                foreach (DirectoryInfo di in dirs)
                {
                    dosearch(di);
                }
            }
            catch (Exception ex)
            {
                // skal ikke rigtigt bruges til noget
            }
        }


4) Kald metoden med et DirectoryInfo som parameter:

            dosearch(new DirectoryInfo(location.Text));
            MessageBox.Show("Antal filer: " + allfiles.Count);

5) Da metoden pt ikke kører i en tråd, vil den låse din form.
Vent til den er færdig og den vil fortælle dig hvor mange filer der er, den angivne mappe inkl. undermapper.

Filerne er tilføjet til listen "allfiles", som er en liste af FileInfo.
Avatar billede thesurfer Nybegynder
15. juni 2009 - 23:30 #20
Ny kode der viser antallet af filer direkte, samt hvilken mappe den er igang med..

1) Tilføj en Label med navnet: lblPath

2) Tilføj en Label med navnet: lblCount

3) Tilføj en Button med navnet: btnSearch

4) Tilføj nedenstående kode - læg mærke til at jeg også har "List<FileInfo>"-linien med igen:


        private List<FileInfo> allfiles = new List<FileInfo>();
        private delegate void delUpdateLabelPath(string path);
        private delegate void delUpdateLabelCount(int count);

        private void btnSearch_Click(object sender, EventArgs e)
        {
            DirectoryInfo mydir = new DirectoryInfo(location.Text);
            Thread t = new Thread(new ParameterizedThreadStart(dosearch));
            t.IsBackground = true;
            t.Start(mydir);
        }

        private void dosearch(object threadDir)
        {
            Thread.Sleep(1);
            DirectoryInfo dir = (DirectoryInfo)threadDir;
            try
            {
                foreach (FileInfo fi in dir.GetFiles())
                {
                    allfiles.Add(fi);
                    updateLabelCount(allfiles.Count);
                }
            }
            catch (Exception ex)
            {
                // skal ikke rigtigt bruges til noget
            }

            try
                {
                DirectoryInfo[] dirs = dir.GetDirectories();
                foreach (DirectoryInfo di in dirs)
                {
                    updateLabelPath(di.FullName);
                    dosearch(di);
                }
            }
            catch (Exception ex)
            {
                // skal ikke rigtigt bruges til noget
            }
        }

        private void updateLabelPath(string path)
        {
            if (lblPath.InvokeRequired)
            {
                lblPath.Invoke(new delUpdateLabelPath(updateLabelPath), new object[] { path });
            }
            else
            {
                lblPath.Text = "Sti: " + path;
            }
        }

        private void updateLabelCount(int count)
        {
            if (lblCount.InvokeRequired)
            {
                lblCount.Invoke(new delUpdateLabelCount(updateLabelCount), new object[] { count });
            }
            else
            {
                lblCount.Text = "Antal: " + count.ToString();
            }
        }
Avatar billede zuran Nybegynder
15. juni 2009 - 23:39 #21
Jeg har lige taget et kig på din post 15. juni 2009 kl. 23:03:39, og den virkede ihvertfald, da jeg lige testede den.

Jeg prøver lige at rode videre med det + tage et kig på din nye post, imorgen når jeg kommer hjem fra arbejde.

Jeg er virkelig glad for alt din hjælp, og takker dig mange gange, fordi du gider bruge al den tid og skære det ud i pap for mig :)
Avatar billede windcape Praktikant
16. juni 2009 - 12:21 #22
thesurfer > At du bliver ved med at skrive fjollede ting som at ens version af et IDE har noget som helst med multi-threading af Managed Winforms at gøre.

Et IDE er et værktøj, en fornem editor. Det afhænger af hvilken version af C# og .NET du benytter, hvis der er forskel i opførsel på det samme stykke kode.
Avatar billede windcape Praktikant
16. juni 2009 - 12:21 #23
Og du skal STADIGVÆK ikke cache samtlige exceptions, det er utrolig dårlig kode!
Avatar billede windcape Praktikant
16. juni 2009 - 12:35 #24
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.IO;

namespace _878163
{
    class Program
    {
        static void Main(string[] args)
        {
            var info  = new DirectoryInfo(@"C:\");
           
            foreach(var file in GetAllFiles(info))
            {
                Console.WriteLine(file.Name);
            }
           
            Console.Read();
        }
       
        static IEnumerable<FileInfo> GetAllFiles(DirectoryInfo info)
        {
            ///
            /// Files
            ///           
           
            FileInfo[] files = new FileInfo[0];           
            try
            {
                files = info.GetFiles("*.*", SearchOption.TopDirectoryOnly);
            }
            catch(DirectoryNotFoundException) {}
            catch(UnauthorizedAccessException) {}
           
            foreach(var file in files)
            {
                yield return file;
            }
           
            ///
            /// Directories
            ///
           
            DirectoryInfo[] directories = new DirectoryInfo[0];
           
            try
            {
                directories = info.GetDirectories();
            }
            catch(DirectoryNotFoundException) {}
            catch(UnauthorizedAccessException) {}
           
            foreach(var directory in directories)
            foreach(var file in GetAllFiles(directory))
            {
                yield return file;
            }
        }
    }
}
Avatar billede windcape Praktikant
16. juni 2009 - 12:45 #25
Og simple multi-threaded udgave.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.IO;
using System.Threading;

namespace _878163
{
    class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
        }
       
        public Program()
        {
            Thread t = new Thread(new ParameterizedThreadStart(
                (object s) => GetAllFiles()
            ));
            t.Start();
        }
       
        public void GetAllFiles()
        {
            var info  = new DirectoryInfo(@"C:\");
           
            foreach(var file in GetAllFiles(info))
            {
                Console.WriteLine(file.Name);
            }           
        }
       
        public IEnumerable<FileInfo> GetAllFiles(DirectoryInfo info)
        {
            ///
            /// Files
            ///           
           
            FileInfo[] files = new FileInfo[0];           
            try
            {
                files = info.GetFiles("*.*", SearchOption.TopDirectoryOnly);
            }
            catch(DirectoryNotFoundException) {}
            catch(UnauthorizedAccessException) {}
           
            foreach(var file in files)
            {
                yield return file;
            }
           
            ///
            /// Directories
            ///
           
            DirectoryInfo[] directories = new DirectoryInfo[0];
           
            try
            {
                directories = info.GetDirectories();
            }
            catch(DirectoryNotFoundException) {}
            catch(UnauthorizedAccessException) {}
           
            foreach(var directory in directories)
            foreach(var file in GetAllFiles(directory))
            {
                yield return file;
            }
        }
    }
}
Avatar billede windcape Praktikant
16. juni 2009 - 13:03 #26
GUI version:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.IO;
using System.Threading;

namespace _878163_W
{
    public partial class Form1 : Form
    {
        private Delegate UIDelegate;
       
        public Form1()
        {
            InitializeComponent();
        }

        private void StartButton_Click(object sender, EventArgs e)
        {
            Thread t = new Thread(new ParameterizedThreadStart(
                (object s) => GetAllFiles()
            ));
            t.Start();
        }
       
        private void GetAllFiles()
        {
            var files = GetAllFiles(new DirectoryInfo(@"D:\Test\"));
           
            Invoke((Action)(() =>
            {
                resultTextBox.Text = string.Format(
                    @"{0} filer i D:\Test\ samt undermapper", files.Count()
                );                   
            }));
        }
       
        private IEnumerable<FileInfo> GetAllFiles(DirectoryInfo info)
        {
            ///
            /// Files
            ///           
           
            FileInfo[] files = new FileInfo[0];           
            try
            {
                files = info.GetFiles("*.*", SearchOption.TopDirectoryOnly);
            }
            catch(DirectoryNotFoundException) {}
            catch(UnauthorizedAccessException) {}
           
            foreach(var file in files)
            {
                yield return file;
            }
           
            ///
            /// Directories
            ///
           
            DirectoryInfo[] directories = new DirectoryInfo[0];
           
            try
            {
                directories = info.GetDirectories();
            }
            catch(DirectoryNotFoundException) {}
            catch(UnauthorizedAccessException) {}
           
            foreach(var directory in directories)
            foreach(var file in GetAllFiles(directory))
            {
                yield return file;
            }
        }
    }
}
Avatar billede zuran Nybegynder
16. juni 2009 - 22:01 #27
Jeg har afprøvet din seneste post, thesurfer, og den virker, så vil du smide et svar ;) ?

Jeg har også afprøvet din kode (Windcape), hvilken tilsyneladende også virker. _Jeg_ kan dog ikke konkludere hvem der har mest ret af jer, men jeg holder gerne øje med tråden, og så går jeg udfra i må kunne finde ud af sammen, hvis kode jeg bør benytte.

Mange tak på for hjælpen ihvertfald!
Avatar billede thesurfer Nybegynder
17. juni 2009 - 01:27 #28
zuran> Her er et svar.


windcape> Hvad mener du forskellen skulle være, på at fange alle exceptions vs fange specifikke exceptions?

Hvis man fanger specifikke exceptions, skal man have listet samtlig muligheder for de exceptions der kan opstå, ellers kan man "misse" en exception..

Ved at fange alle exceptions, har man en chance for at rapportere fejlen, selv om den er "ukendt"..
Avatar billede windcape Praktikant
17. juni 2009 - 14:34 #29
@thesurfer:

Det er jo netop pointen. Du kan jo ikke debugge din kode hvis du fanger samtlige exceptions over det hele!

Og du bør ikke fange ukendte fejl mere end eet sted, og da slet ikke i en funktion som retunere data!

@zuran:

Min version med iterators er nok mest politisk korrekt, og bedst fra et performance synspunkt. Du bør ihvertfald lære at forstå den kode jeg har postet, hvis du agter at udbygge dit program.
Avatar billede windcape Praktikant
17. juni 2009 - 14:36 #30
Og derudover glemte thesurfer at vise hvordan man håndterer cross-thread GUI invokes, da han ikke selv har forstået konceptet i det endnu ;-)
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