• 0

An error occurring during compiling


Question

i'm building an Hide and seek game using csharp here is the code, it has 2 interfaces , 2 independent classes, 6 other classes which inherit from the interface and the other 2 classes, the code has zero errors and runs when pressed start. But some times during execution the code starts running and give me this error it pints to the line currentLocation.Exits.Name

 

So hears the cod for the entire program

  interface IHasExteriorDoor
    {
        string DoorDescription { get; }
        Location DoorLocation { get; set; }
    }
 interface IHidingPlace
    {
        string HidingPlaceName { get; }
    }
abstract class Location
    {
        public Location(string name)
        {
            this.name = name;
        }
        public Location[] Exits;
        private string name;
        public string Name
        {
            get { return name; }
        }
        public virtual string Description
        {
            get
            {
                string description = " You're standing in the " + name + ". You see exits to the following places:";

                for (int i = 0; i < Exits.Length; i++)
                {
                    description += "" + Exits[i].Name;
                    if (i != Exits.Length - 1)
                        description += ",";
                }
                description += ".";
                return description;
            }
        }
    }
class Opponent
    {
        private Random random;
        private Location myLocation;
        public Opponent(Location startingLocation)
        {
            myLocation = startingLocation;
            random = new Random();
        }
        public void Move()
        {
            if (myLocation is IHasExteriorDoor)
            {
                IHasExteriorDoor LocationWithDoor = myLocation as IHasExteriorDoor;
            
            if (random.Next(2) == 1)
                myLocation = LocationWithDoor.DoorLocation;
        }
        bool hidden = false;
        while(!hidden)
            {
            int rand = random.Next(myLocation.Exits.Length);
            myLocation = myLocation.Exits[rand];
            if(myLocation is IHidingPlace)
            hidden = true;
            }
        }
        public bool Check(Location locationToCheck)
        {
            if (locationToCheck != myLocation)
                return false;
            else
                return true;
        } 
    }
 class OutsideWithDoor : Outside, IHasExteriorDoor
    {
        public OutsideWithDoor(string name, bool hot, string doorDescription): base(name, hot)
            {
            this.doorDescription = doorDescription;
            }
        private string doorDescription;
        public string DoorDescription
        {
            get { return doorDescription; }
        }
        private Location doorLocation;
        public Location DoorLocation
        {
            get { return doorLocation; }
            set { doorLocation = value; }
        }
        public override string Description
        {
            get
            {
                return base.Description + "You see " + doorDescription + ".";
            }
        }
    }
 class Outside : Location
    {
        private bool hot;
        public bool Hot { get { return hot; } }

        public Outside(string name, bool hot) : base(name)
        {
            this.hot = hot;
        }
        public override string Description
        {
            get
            {
                string NewDescription = base.Description;
                if (hot)
                    NewDescription += "It's very hot.";
                return NewDescription;
            }
        }
    }
 class OutsideWithHidingPlace : Outside, IHidingPlace
    {
        public OutsideWithHidingPlace(string name, bool hot, string hidingPlaceName) : base(name, hot)
        { this.hidingPlaceName = hidingPlaceName; }

        private string hidingPlaceName;
        public string HidingPlaceName
        {
            get { return hidingPlaceName; }
        }
        public override string Description
        {
            get { return base.Description + "Someone could hide" + hidingPlaceName + "."; }
        }
    }
class RoomwithDoor: RoomWithHidingPlace, IHasExteriorDoor
    {
        public RoomwithDoor(string name, string decoration, string hidingPlaceName, string doorDescription):base(name, decoration, hidingPlaceName)
        { this.doorDescription = doorDescription; }
        private string doorDescription;
        public string DoorDescription
        {
            get { return doorDescription; }
        }
        private Location doorLocation;
        public Location DoorLocation
        {
            get { return doorLocation; }
            set { doorLocation = value; }
        }
    }
class Room: Location
    {
        private string decoration;

        public Room(string name, string decoration):base(name)
        {
            this.decoration = decoration;
        }
        public override string Description
        {
            get
            {
                return base.Description+"You see " + decoration + ".";
            }
        }
    }
 class RoomWithHidingPlace : Room, IHidingPlace
    {
        public RoomWithHidingPlace (string name, string decoration, string hidingPlaceName): base(name, decoration)
        {
            this.hidingPlaceName = hidingPlaceName;
        }
        private string hidingPlaceName;
        public string HidingPlaceName
        {
            get { return hidingPlaceName; }
        }
        public override string Description
        {
         get { return base.Description + "Someone could hide" + hidingPlaceName + "."; }
        }
    }
public partial class Form1 : Form
    {
        int Moves;
        Location currentLocation;

        RoomwithDoor livingRoom;
        RoomWithHidingPlace diningRoom;
        RoomwithDoor kitchen;
        Room stairs;
        RoomWithHidingPlace hallway;
        RoomWithHidingPlace bathroom;
        RoomWithHidingPlace masterBedroom;
        RoomWithHidingPlace secondBedroom;

        OutsideWithDoor frontYard;
        OutsideWithDoor backYard;
        OutsideWithHidingPlace garden;
        OutsideWithHidingPlace driveway;

        Opponent opponent;

        public Form1()
        {
            InitializeComponent();
            CreateObjects();
            opponent = new Opponent(frontYard);
            ResetGame(false);
            MoveToANewLocation(livingRoom);
        }
        private void MoveToANewLocation(Location newLocation)
        {
            Moves++;
            currentLocation = newLocation;
            RedrawForm();
        }
        private void RedrawForm()
        {
            exits.Items.Clear();
            for (int i = 0; i < currentLocation.Exits.Length; i++)
                exits.Items.Add(currentLocation.Exits[i].Name);
            exits.SelectedIndex = 0;
            description.Text = currentLocation.Description + "\r\n(move #" + Moves + ")";
            if(currentLocation is IHidingPlace)
            {
                IHidingPlace hidingPlace = currentLocation as IHidingPlace;
                exits.Text = "Check" + hidingPlace.HidingPlaceName;
                exits.Visible = true;
            }
            else
                exits.Visible = false;
                if (currentLocation is IHasExteriorDoor)
                    goThroughTheDoor.Visible = true;
                else
                    goThroughTheDoor.Visible = false;
        }
        private void CreateObjects()
        {
            livingRoom = new RoomwithDoor("Living Room", "an antique carpet","inside the closet", "an oak door with a brassknob");
            diningRoom = new RoomWithHidingPlace("Dining Room", "a crystal chandelier", "in the tall armorie");
            kitchen = new RoomwithDoor("Kitchen", "stainless steel appliances","in the cabinet", "a screen door");
            stairs = new RoomwithDoor("Kitchen", "stainless steel appliances", "in teh cabinet", "a screen door");
            hallway = new RoomWithHidingPlace("Upstairs Hallway", "a picture of a dog", "in the closet");
            bathroom = new RoomWithHidingPlace("Bathjroom", "a sink and a toilet", "in the shower");
            masterBedroom = new RoomWithHidingPlace("Master Bedroom", "a large bed", "under the bed");
            secondBedroom = new RoomWithHidingPlace("Second Bedroom", "a small bed", " under the bed");

            frontYard =new OutsideWithDoor("Front Yard", false, "a heavy-looking oak door ");
            backYard = new OutsideWithDoor("Back Yard", true, " a screen door");
            garden = new OutsideWithHidingPlace("Garden", false,"inside the shed");
            driveway = new OutsideWithHidingPlace("Driveway", true, "in the garage");

            diningRoom.Exits = new Location[] { livingRoom, kitchen };
            livingRoom.Exits = new Location[] { diningRoom, stairs };
            kitchen.Exits = new Location[] { diningRoom };
            stairs.Exits = new Location[] { livingRoom, hallway };
            hallway.Exits = new Location[] { stairs, bathroom, masterBedroom, secondBedroom };
            bathroom.Exits = new Location[] { hallway };
            masterBedroom.Exits = new Location[] { hallway };
            secondBedroom.Exits = new Location[] { hallway };
            frontYard.Exits = new Location[] { backYard, garden, driveway };
            backYard.Exits = new Location[] { frontYard, garden, driveway };
            garden.Exits = new Location[] { backYard, frontYard };
            driveway.Exits = new Location[] { backYard, frontYard };

            livingRoom.DoorLocation = frontYard;
            frontYard.DoorLocation = livingRoom;

            kitchen.DoorLocation = backYard;
            backYard.DoorLocation = kitchen;
        }
         private void ResetGame (bool displayMessage)
        {
            if (displayMessage)
            {
                MessageBox.Show("you found me in" + Moves + "moves!");
                IHidingPlace foundLocation = currentLocation as IHidingPlace;
                description.Text = "you found your opponent in " + Moves + "moves! He was hiding" + foundLocation.HidingPlaceName + ".";
            }
            Moves = 0;
            hide.Visible = true;
            goHere.Visible = false;
            check.Visible = false;
            goThroughTheDoor.Visible = false;
            exits.Visible = false;
        }

    

        private void goHere_Click(object sender, EventArgs e)
        {
            MoveToANewLocation(currentLocation.Exits[exits.SelectedIndex]);
        }

        private void goThroughTheDoor_Click(object sender, EventArgs e)
        {
            IHasExteriorDoor hasDoor = currentLocation as IHasExteriorDoor;
            MoveToANewLocation(hasDoor.DoorLocation);
        }

        private void check_Click(object sender, EventArgs e)
        {
            Moves++;
            if (opponent.Check(currentLocation))
                ResetGame(true);
            else
                RedrawForm();
        }

        private void Hide_Click(object sender, EventArgs e)
        {
            hide.Visible = false;
            for (int i = 1; i <= 10; i++)
            {
                opponent.Move();
                description.Text = i + "...";
                Application.DoEvents();
                System.Threading.Thread.Sleep(200);
            }
            description.Text = "Ready or not, here i come!";
            Application.DoEvents();
            System.Threading.Thread.Sleep(500);

            goHere.Visible = true;
            exits.Visible = true;
            MoveToANewLocation(livingRoom);
        }
    }

Although this program contains 0 errors the program stops compiling sometimes and points towards the line current.Exit.Name and give a pop up saying Null reference  exception was handled.

 

Here's how the form looks like FORM

Link to comment
https://www.neowin.net/forum/topic/1323070-an-error-occurring-during-compiling/
Share on other sites

7 answers to this question

Recommended Posts

  • 0
Location currentLocation = null;
// Or
Location currentLocation.Exits = null;

The error is caused because the value is null, this can be caused by either the whole currentLocation to be null or the Exits attribute to be null.

 

If I would have to guess:

 

You start at Location A which has exits B, C and D.

Then you go to exit Location C which has no exits, the attribute "exits" is null, this causes an error in the for loop which expects at least an empty array instead of null.

 

The NullReferenceException is the most common exception I've ever seen in a C# application :p

 

TL;DR

 

Always initialize your arrays/lists or check if they aren't null before using a loop.

 

Also this is not an compilation but an execution error, which means that the code will compile fine and can be distributed to the users which will see their application crash. Therefore it's always recommended to test all scenarios (0, 1 or multiple exits) for bugs before shipping the code.
 

This can be done manually or automated (recommended) with unit tests: https://www.youtube.com/watch?v=rW6LvPP4VvA

 

 

  • 0
  On 21/02/2017 at 12:51, Ch33f said:

Although this program contains 0 errors the program stops compiling sometimes and points towards the line current.Exit.Name and give a pop up saying Null reference  exception was handled.

Expand  

First, this is not a compile-time error! It does not happen while the program is compiling, it happens while the program is running, i.e. after compilation. If you have any confusion about compile- vs run-time you need to clear that up ASAP. The compiler turns your text files (*.cs) into executable files (*.dll, *.exe), which can then run inside an operating system process. Exceptions happen at run-time when your program is legal C# so it compiles, but it still manages to do something wrong (like in this case, dereferencing a null).

 

As @Seahorsepip mentions, if `currentLocation.Exits.Name` throws NullReferenceException then either currentLocation is null or currentLocation.Exits is null. Why are they null? What could you do to make them not null? That's yours to figure out.

 

 

  • Like 1
  • 0

After reading the code, it appears to me your problem is very simple...

 

abstract class Location
    {
        public Location(string name)
        {
            this.name = name;
        }
        public Location[] Exits;

you did not initialize Exits in the base constructor, nor did you initialize it in the inherited constructors as well.

Seems to me somewhere you should have this line somewhere in your constructors.

Exits = new Location[ExitCount];  //Where ExitCount is an integer

 

  • 0
  On 21/02/2017 at 18:19, Seahorsepip said:

The NullReferenceException is the most common exception I've ever seen in a C# application :p

Expand  

For me it's the "Object reference not set to an instance of an object" error (I've caused this in my apps forgetting to set it correctly), and the division by zero errors. I'm working on a C# GTA soundboard, and when I'm tired the object reference error happens a lot :) Caffeine normally helps :)

  • Like 1
  • 0
  On 21/02/2017 at 23:08, sao123 said:

After reading the code, it appears to me your problem is very simple...

Expand  

The exits are given a value in CreateObjects():

See Form1 constructor:

MoveToANewLocation(livingRoom);

Which sets currentLocation to livingRoom (which is generated by CreateObjects() and has the exits value diningRoom and stairs).

So exits don't need to be initialized in the Locations class itself to work but imagine what happens when the following method is called:

MoveToANewLocation(stairs);

And the stairs exits array attribute is not initialized in CreateObjects()?

 

Then it tries to for loop trough null instead of an array and we end up with a NullReferenceException :)

 

So initializing every array in the classes is a quick fix that does indeed solve the NullReferenceException issue in most cases but might not solve the underlying issue, maybe a Location should always have at least 1 exit as example.

 

As I said before it's saves a lot of work when unit tests are made for all use case scenarios(values, actions etc). Then it's directly clear when something stopped working that worked before.

 

  On 21/02/2017 at 23:33, Tidosho said:

For me it's the "Object reference not set to an instance of an object" error (I've caused this in my apps forgetting to set it correctly), and the division by zero errors. I'm working on a C# GTA soundboard, and when I'm tired the object reference error happens a lot :) Caffeine normally helps :)

Expand  

I always get StackOverflowExceptions since I have a habit to write a lot of recursion logic lately :p 

  • 0
  On 21/02/2017 at 23:33, Tidosho said:

For me it's the "Object reference not set to an instance of an object" error (I've caused this in my apps forgetting to set it correctly), and the division by zero errors. I'm working on a C# GTA soundboard, and when I'm tired the object reference error happens a lot :) Caffeine normally helps :)

Expand  

Try F# - no nulls (mostly) among other benefits ;)

  • 0

Thank You for the feedback, i got the program working, exits is the name given to the combo box and its has been initialized in Location class here is the edited version of form.

public partial class Form1 : Form
    {
        int Moves;
        Location currentLocation;

        RoomwithDoor livingRoom;
        RoomWithHidingPlace diningRoom;
        RoomwithDoor kitchen;
        Room stairs;
        RoomWithHidingPlace hallway;
        RoomWithHidingPlace bathroom;
        RoomWithHidingPlace masterBedroom;
        RoomWithHidingPlace secondBedroom;

        OutsideWithDoor frontYard;
        OutsideWithDoor backYard;
        OutsideWithHidingPlace garden;
        OutsideWithHidingPlace driveway;

        Opponent opponent;

        public Form1()
        {
            InitializeComponent();
            CreateObjects();
            opponent = new Opponent(frontYard);
            ResetGame(false);
            MoveToANewLocation(livingRoom);
        }
        private void MoveToANewLocation(Location newLocation)
        {
            Moves++;
            currentLocation = newLocation;
            RedrawForm();
            
        }
        private void RedrawForm()
        {
            exits.Items.Clear();
            for (int i = 0; i < currentLocation.Exits.Length; i++)
                exits.Items.Add(currentLocation.Exits[i].Name);
            exits.SelectedIndex = 0;
            description.Text = currentLocation.Description + "\r\n(move #" + Moves + ")";
            if(currentLocation is IHidingPlace)
            {
                IHidingPlace hidingPlace = currentLocation as IHidingPlace;
                check.Text = "Check" + hidingPlace.HidingPlaceName;
                check.Visible = true;
            }
            else
                check.Visible = false;
                if (currentLocation is IHasExteriorDoor)
                    goThroughTheDoor.Visible = true;
                else
                    goThroughTheDoor.Visible = false;
        }
        private void CreateObjects()
        {
            livingRoom = new RoomwithDoor("Living Room", "an antique carpet","inside the closet", "an oak door with a brassknob");
            diningRoom = new RoomWithHidingPlace("Dining Room", "a crystal chandelier", "in the tall armorie");
            kitchen = new RoomwithDoor("Kitchen", "stainless steel appliances","in the cabinet", "a screen door");
            stairs = new Room("Stairs", "a wooden bannister");
            hallway = new RoomWithHidingPlace("Upstairs Hallway", "a picture of a dog", "in the closet");
            bathroom = new RoomWithHidingPlace("Bathjroom", "a sink and a toilet", "in the shower");
            masterBedroom = new RoomWithHidingPlace("Master Bedroom", "a large bed", "under the bed");
            secondBedroom = new RoomWithHidingPlace("Second Bedroom", "a small bed", " under the bed");

            frontYard =new OutsideWithDoor("Front Yard", false, "a heavy-looking oak door ");
            backYard = new OutsideWithDoor("Back Yard", true, " a screen door");
            garden = new OutsideWithHidingPlace("Garden", false,"inside the shed");
            driveway = new OutsideWithHidingPlace("Driveway", true, "in the garage");

            diningRoom.Exits = new Location[] { livingRoom, kitchen };
            livingRoom.Exits = new Location[] { diningRoom, stairs };
            kitchen.Exits = new Location[] { diningRoom };
            stairs.Exits = new Location[] { livingRoom, hallway };
            hallway.Exits = new Location[] { stairs, bathroom, masterBedroom, secondBedroom };
            bathroom.Exits = new Location[] { hallway };
            masterBedroom.Exits = new Location[] { hallway };
            secondBedroom.Exits = new Location[] { hallway };
            frontYard.Exits = new Location[] { backYard, garden, driveway };
            backYard.Exits = new Location[] { frontYard, garden, driveway };
            garden.Exits = new Location[] { backYard, frontYard };
            driveway.Exits = new Location[] { backYard, frontYard };

            livingRoom.DoorLocation = frontYard;
            frontYard.DoorLocation = livingRoom;

            kitchen.DoorLocation = backYard;
            backYard.DoorLocation = kitchen;
        }
         private void ResetGame (bool displayMessage)
        {
            if (displayMessage)
            {
                MessageBox.Show("you found me in" + Moves + "moves!");
                IHidingPlace foundLocation = currentLocation as IHidingPlace;
                description.Text = "you found your opponent in " + Moves + "moves! He was hiding" + foundLocation.HidingPlaceName + ".";
            }
            Moves = 0;
            hide.Visible = true;
            goHere.Visible = false;
            check.Visible = false;
            goThroughTheDoor.Visible = false;
            exits.Visible = false;
        }

      /*  private void MoveToANewLocation(Location newLocation)
        {
            currentLocation = newLocation;

            exits.Items.Clear();
            for (int i = 0; i < currentLocation.Exits.Length; i++) 
            exits.Items.Add(currentLocation.Exits[i].Name);
            exits.SelectedIndex = 0;

            description.Text = currentLocation.Description;

            if (currentLocation is IHasExteriorDoor)
                goThroughTheDoor.Visible = true;
            else
                goThroughTheDoor.Visible = false;
        }*/

        private void goHere_Click(object sender, EventArgs e)
        {
            MoveToANewLocation(currentLocation.Exits[exits.SelectedIndex]);
        }

        private void goThroughTheDoor_Click(object sender, EventArgs e)
        {
            IHasExteriorDoor hasDoor = currentLocation as IHasExteriorDoor;
            MoveToANewLocation(hasDoor.DoorLocation);
        }

        private void check_Click(object sender, EventArgs e)
        {
            Moves++;
            if (opponent.Check(currentLocation))
                ResetGame(true);
            else
                RedrawForm();
        }

        private void Hide_Click(object sender, EventArgs e)
        {
            hide.Visible = false;
            for (int i = 1; i <= 10; i++)
            {
                opponent.Move();
                description.Text = i + "...";
                Application.DoEvents();
                System.Threading.Thread.Sleep(200);
            }
            description.Text = "Ready or not, here i come!";
            Application.DoEvents();
            System.Threading.Thread.Sleep(500);

            goHere.Visible = true;
            exits.Visible = true;
            MoveToANewLocation(livingRoom);
        }
    }

 

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • I have it as an icon in the Start Menu. Close enough for when I need it.
    • Windows 11 Pro with a copy of Office 2021 Pro drops to all-time low price by Steven Parker Today's highlighted deal comes via our Apps + Software section of the Neowin Deals store, where you can save 86% on Windows 11 Pro (for 2 devices) + Microsoft Office Pro 2021. Upgrade your computing experience with Windows 11 Pro. This cutting-edge operating system boasts a sleek new design and advanced tools to help you work faster and smarter. From creative projects to gaming and beyond, Windows 11 delivers the power and flexibility you need to achieve your goals. With a focus on productivity, the new features are easy to learn and use, enhancing your workflow and efficiency. Whether you're a student, professional, gamer, or creative, Windows 11 Home has everything you need to take your productivity to the next level. New interface. easier on the eyes & easier to use Biometrics login*.Encrypted authentication & advanced antivirus defenses DirectX 12 Ultimate. Play the latest games with graphics that rival reality. DirectX 12 Ultimate comes ready to maximize your hardware* Screen space. Snap layouts, desktops & seamless redocking Widgets. Stay up-to-date with the content you love & the new you care about Microsoft Teams. Stay in touch with friends and family with Microsoft Teams, which can be seamlessly integrated into your taskbar** Wake & lock. Automatically wake up when you approach and lock when you leave Smart App Control. Provides a layer of security by only permitting apps with good reputations to be installed Windows Studio Effects. Designed with Background Blur, Eye Contact, Voice Focus, & Automatic Framing Touchscreen. For a true mouse-less or keyboard-less experience TPM 2.0. Helps prevent unwanted tampering Windows 11 Pro also includes a number of productivity-focused features, such as the ability to snap multiple windows together and create custom layouts, improved voice typing, and a new, more powerful search experience. Personal and professional users will enjoy a modern and secure computing experience, with improved performance and productivity features to help users get more done. Only on Windows 11 Pro If you require enterprise-oriented features for your daily professional tasks, then Windows 11 Pro is a better option. Set up with a local account (only when set up for work or school) Join Active Directory/Azure AD Hyper-V Windows Sandbox Microsoft Remote Desktop BitLocker device encryption Windows Information Protection Mobile device management (MDM) Group Policy Enterprise State Roaming with Azure Assigned Access Dynamic Provisioning Windows Update for Business Kiosk mode Maximum RAM: 2TB Maximum no. of CPUs: 2 Maximum no. of CPU cores: 128 Good to know: Length of access: lifetime Redemption deadline: redeem your code within 30 days of purchase Access options: desktop Max number of device(s): 2 (Use one activation key for up to 2 devices) Version: Windows 11 Pro Updates included Click here to verify Microsoft partnership For Windows 10 or Newer! Get All Essential Microsoft Apps for Your PC with This One-Time Purchase This is intended for families and small businesses who want classic Office apps and email. It includes Word, Excel, PowerPoint, Outlook, Teams, and OneNote. A one-time purchase installed on 1 Windows PC for use at home or work. Lifetime license for MS Word, Excel, PowerPoint, Outlook, Teams, & OneNote One-time purchase installed on 1 Windows PC for use at home or work Instant Delivery & Download – access your software license keys and download links instantly Free customer service – only the best support! Microsoft Office Professional 2021 (for Windows) includes: Microsoft Office Word Microsoft Office Excel Microsoft Office PowerPoint Microsoft Office Outlook Microsoft Office Teams Microsoft Office OneNote Microsoft Office Publisher Microsoft Office Access Good to know: ONE-TIME PURCHASE INSTALLED ON 1 DEVICE Redemption deadline: redeem your code within 30 days of purchase Access options: desktop Full versions No subscriptions – no monthly/annual fees Version: 2021 Updates included Here's the deal: This Microsoft Office Pro 2021 + Windows 11 Pro normally costs $438, but this deal can be yours from just $54.97, that's a saving of $383. For full terms, specifications, and license info please click the link below. Use MSO5 when checking out for additional $5 off. Coupon Expires June 29. Get Microsoft Office Pro 2021 + Windows 11 Pro for just $49.97, or learn more Although priced in U.S. dollars, this deal is available for digital purchase worldwide. We post these because we earn commission on each sale so as not to rely solely on advertising, which many of our readers block. It all helps toward paying staff reporters, servers and hosting costs. Other ways to support Neowin Whitelist Neowin by not blocking our ads Create a free member account to see fewer ads Make a donation to support our day to day running costs Subscribe to Neowin - for $14 a year, or $28 a year for an ad-free experience Disclosure: Neowin benefits from revenue of each sale made through our branded deals site powered by StackCommerce.
    • I'm not a fan of the HP "Smart" app either, but it does work. I just wish I didn't have to log in to use it. HP Color LaserJet Pro MFP 4301
    • FocusOn Image Viewer 1.32 by Razvan Serea FocusOn Image Viewer is a fast, lightweight, and user-friendly photo viewer for Windows. It supports various image formats, offers basic editing tools, EXIF data display, and batch renaming. With a clean interface, slideshow mode, and easy navigation, it’s ideal for quickly viewing and organizing photos without unnecessary complexity or system resource usage. FocusOn Image Viewer key features: Auto Organize: Automatically sorts photos by date using your chosen template. Explorer View: Browse and manage images with thumbnails; includes basic edits like resize and rotate. Photo Editing: Crop, apply filters, correct colors, add borders or text. Non-Destructive Edits: Original images remain untouched. Photo Sharing: Post directly to blogs, Twitter, and Facebook. Email Support: Send selected images via email. Print Options: Print to fit paper size, preserve aspect ratio, or fit multiple images per page. Slideshow: View selected photos in a slideshow. EXIF Tools: View or remove EXIF data. Scanning: Import from TWAIN or WIA-compatible scanners. Set as Background: Quickly set any image as desktop wallpaper. Batch Rename: Rename images in bulk using templates. Resize Images: Resize with optimized or custom resampling methods, including multi-step resizing. Thumbnail Sizes: Choose from thumbnail sizes between 32–256 pixels. Format Support: Compatible with over 100 image formats. FocusOn Image Viewer 1.32 changelog: Added Ghostscript(AI, PDF) DPI option Fixed transparency issue when saving PDF document as image Other improvements and bug fixes Download: FocusOn Image Viewer 64-bit | Portable 64-bit | ~7.0 MB (Freeware) Download: FocusOn Image Viewer 32-bit | Portable 32-bit View: FocusOn Image Viewer Website | Screenshot Get alerted to all of our Software updates on Twitter at @NeowinSoftware
    • Wall cabinet: Fiber connection (1Gbps) Patch panel 2.5Gbps Router A mini PC with Ryzen 5800H CPU and 32GB DDR4 RAM, for network related tools (Portainer, Pi-Hole, Cloudflared, Tailscale, Uptime Kuma, Wetty) A headless server running Proxmox: AMD Ryzen 9 9950X CPU, 96GB DDR5, RTX 3090 24GB GPU, 10Gbps NIC, and a bunch of NVMs, SATA SSDs, HDDs A VM with TrueNAS for backups and media server via Jellyfin, passing through the SATA storage controller A VM with an Ubuntu server acting as a web and a GPU server for AI workloads, and a TeamCity build/deploy agent for my personal projects This setup has evolved many times for the last 2 years, I have not gone completely crazy, yet (I think), but still experimenting, still learning, it is a fun and rewarding experience having a home lab!
  • Recent Achievements

    • First Post
      Johnny Mrkvička earned a badge
      First Post
    • Week One Done
      viraltui earned a badge
      Week One Done
    • One Month Later
      serfegyed earned a badge
      One Month Later
    • Dedicated
      firey earned a badge
      Dedicated
    • Dedicated
      fettermanj earned a badge
      Dedicated
  • Popular Contributors

    1. 1
      +primortal
      649
    2. 2
      Michael Scrip
      224
    3. 3
      ATLien_0
      223
    4. 4
      Xenon
      149
    5. 5
      +FloatingFatMan
      144
  • Tell a friend

    Love Neowin? Tell a friend!