New programmer here.
I've written an application to filter out password protected files from a large collection. It is working so far...
My problem is that I am trying to get the resulting paths what happened to them to write out into a text box. Maybe I am missing something completely obvious here, but I am getting the error:
CS0120 An object reference is required for the non-static field, method, or property
MainWindow.SearchRunOutputBox
when attempting to assign values inside an updater method I wrote.
I am very confused as I had assumed that a rich text box, already present on the form, would be it's own object? Again, maybe I am just missing something obvious here...
Code below:
using Microsoft.VisualStudio.Services.CircuitBreaker;
using Spire.Pdf.Exporting.XPS.Schema;
using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
namespace Find_Move_PWP_PDF_s
{
public partial class MainWindow : Form
{
public MainWindow()
{
InitializeComponent();
}
public static void OutputBoxUpdater(string message, Color color)
{
SearchRunOutputBox.SuspendLayout();
SearchRunOutputBox.SelectionColor = color;
SearchRunOutputBox.AppendText(message);
SearchRunOutputBox.AppendText(Environment.NewLine);
SearchRunOutputBox.ScrollToCaret();
SearchRunOutputBox.ResumeLayout();
}
Is the text box object not created when InitializeComonent()
is called as the MainWindow
starts?
Included designer.cs below:
partial class MainWindow
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.Windows.Forms.Label DirectoryPathLabel;
System.Windows.Forms.Label CreateSubFoldersLabel;
this.DirectoryPathInput = new System.Windows.Forms.TextBox();
this.SearchStartButton = new System.Windows.Forms.Button();
this.SearchProgressBar = new System.Windows.Forms.ProgressBar();
this.MovePDFsButton = new System.Windows.Forms.Button();
this.MovePDFsRunOutputBox = new System.Windows.Forms.RichTextBox();
this.MovesProgressBar = new System.Windows.Forms.ProgressBar();
this.SearchRunOutputBox = new System.Windows.Forms.RichTextBox();
DirectoryPathLabel = new System.Windows.Forms.Label();
CreateSubFoldersLabel = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// DirectoryPathLabel
//
DirectoryPathLabel.AccessibleDescription = "DirectoryPathLabel";
DirectoryPathLabel.AutoSize = true;
DirectoryPathLabel.BackColor = System.Drawing.SystemColors.Window;
DirectoryPathLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
DirectoryPathLabel.Location = new System.Drawing.Point(14, 23);
DirectoryPathLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
DirectoryPathLabel.Name = "DirectoryPathLabel";
DirectoryPathLabel.Size = new System.Drawing.Size(370, 25);
DirectoryPathLabel.TabIndex = 0;
DirectoryPathLabel.Text = "Please enter the desired search directory.";
//
// CreateSubFoldersLabel
//
CreateSubFoldersLabel.AccessibleDescription = "CreateSubFoldersLabel";
CreateSubFoldersLabel.AccessibleName = "CreateSubFoldersLabel";
CreateSubFoldersLabel.AutoSize = true;
CreateSubFoldersLabel.BackColor = System.Drawing.SystemColors.Window;
CreateSubFoldersLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
CreateSubFoldersLabel.Location = new System.Drawing.Point(14, 453);
CreateSubFoldersLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
CreateSubFoldersLabel.Name = "CreateSubFoldersLabel";
CreateSubFoldersLabel.Size = new System.Drawing.Size(725, 25);
CreateSubFoldersLabel.TabIndex = 5;
CreateSubFoldersLabel.Text = "Click here to move the password protected PDFs into subfolders labelled \"Locked\"."
"";
//
// DirectoryPathInput
//
this.DirectoryPathInput.AccessibleDescription = "DirectoryPathInput";
this.DirectoryPathInput.Location = new System.Drawing.Point(424, 30);
this.DirectoryPathInput.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.DirectoryPathInput.Name = "DirectoryPathInput";
this.DirectoryPathInput.Size = new System.Drawing.Size(822, 23);
this.DirectoryPathInput.TabIndex = 1;
//
// SearchStartButton
//
this.SearchStartButton.AccessibleDescription = "SearchStartButton";
this.SearchStartButton.Location = new System.Drawing.Point(1278, 23);
this.SearchStartButton.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.SearchStartButton.Name = "SearchStartButton";
this.SearchStartButton.Size = new System.Drawing.Size(248, 30);
this.SearchStartButton.TabIndex = 2;
this.SearchStartButton.Text = "Start Search";
this.SearchStartButton.UseVisualStyleBackColor = true;
this.SearchStartButton.Click = new System.EventHandler(this.SearchStartButton_Click);
//
// SearchProgressBar
//
this.SearchProgressBar.AccessibleDescription = "SearchProgressBar";
this.SearchProgressBar.AccessibleName = "SearchProgressBar";
this.SearchProgressBar.Location = new System.Drawing.Point(14, 257);
this.SearchProgressBar.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.SearchProgressBar.Name = "SearchProgressBar";
this.SearchProgressBar.Size = new System.Drawing.Size(1512, 15);
this.SearchProgressBar.TabIndex = 3;
//
// MovePDFsButton
//
this.MovePDFsButton.AccessibleDescription = "MovePDFsButton";
this.MovePDFsButton.AccessibleName = "MovePDFsButton";
this.MovePDFsButton.Location = new System.Drawing.Point(767, 453);
this.MovePDFsButton.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.MovePDFsButton.Name = "MovePDFsButton";
this.MovePDFsButton.Size = new System.Drawing.Size(237, 25);
this.MovePDFsButton.TabIndex = 6;
this.MovePDFsButton.Text = "Move PDFs";
this.MovePDFsButton.UseVisualStyleBackColor = true;
//
// MovePDFsRunOutputBox
//
this.MovePDFsRunOutputBox.AccessibleDescription = "MovePDFsRunOutputBox";
this.MovePDFsRunOutputBox.AccessibleName = "MovePDFsRunOutputBox";
this.MovePDFsRunOutputBox.BackColor = System.Drawing.Color.WhiteSmoke;
this.MovePDFsRunOutputBox.Location = new System.Drawing.Point(14, 489);
this.MovePDFsRunOutputBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.MovePDFsRunOutputBox.Name = "MovePDFsRunOutputBox";
this.MovePDFsRunOutputBox.ReadOnly = true;
this.MovePDFsRunOutputBox.Size = new System.Drawing.Size(1511, 190);
this.MovePDFsRunOutputBox.TabIndex = 7;
this.MovePDFsRunOutputBox.Text = "";
//
// MovesProgressBar
//
this.MovesProgressBar.AccessibleDescription = "MovesProgressBar";
this.MovesProgressBar.AccessibleName = "MovesProgressBar";
this.MovesProgressBar.Location = new System.Drawing.Point(14, 687);
this.MovesProgressBar.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.MovesProgressBar.Name = "MovesProgressBar";
this.MovesProgressBar.Size = new System.Drawing.Size(1512, 15);
this.MovesProgressBar.TabIndex = 8;
//
// SearchRunOutputBox
//
this.SearchRunOutputBox.AccessibleDescription = "SearchRunOutputBox";
this.SearchRunOutputBox.AccessibleName = "SearchRunOutputBox";
this.SearchRunOutputBox.BackColor = System.Drawing.Color.WhiteSmoke;
this.SearchRunOutputBox.CausesValidation = false;
this.SearchRunOutputBox.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.SearchRunOutputBox.Location = new System.Drawing.Point(14, 60);
this.SearchRunOutputBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.SearchRunOutputBox.Name = "SearchRunOutputBox";
this.SearchRunOutputBox.ReadOnly = true;
this.SearchRunOutputBox.Size = new System.Drawing.Size(1511, 190);
this.SearchRunOutputBox.TabIndex = 4;
this.SearchRunOutputBox.Text = "";
//
// MainWindow
//
this.AccessibleDescription = "MainWindow";
this.AccessibleName = "MainWindow";
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.ClientSize = new System.Drawing.Size(1540, 726);
this.Controls.Add(this.MovesProgressBar);
this.Controls.Add(this.MovePDFsRunOutputBox);
this.Controls.Add(this.MovePDFsButton);
this.Controls.Add(CreateSubFoldersLabel);
this.Controls.Add(this.SearchRunOutputBox);
this.Controls.Add(this.SearchProgressBar);
this.Controls.Add(this.SearchStartButton);
this.Controls.Add(this.DirectoryPathInput);
this.Controls.Add(DirectoryPathLabel);
this.DoubleBuffered = true;
this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.Name = "MainWindow";
this.Text = "Find and Move Password Protected PDF\'s";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox DirectoryPathInput;
private System.Windows.Forms.Button SearchStartButton;
private System.Windows.Forms.ProgressBar SearchProgressBar;
private System.Windows.Forms.Button MovePDFsButton;
private System.Windows.Forms.ProgressBar MovesProgressBar;
private System.Windows.Forms.RichTextBox MovePDFsRunOutputBox;
public System.Windows.Forms.RichTextBox SearchRunOutputBox;
}
}
I am wondering if there is a way to make the text box a static item? Or should I bet using something else to display the log?
I've tried initiating a new text box inside the OutBoxUpdater(), which got rid of the error, but doesn't seem to do anything. Or it did something, but not what I wanted lol.
public static void OutputBoxUpdater(string message, Color color)
{
RichTextBox SearchRunOutputBox = new();
SearchRunOutputBox.SuspendLayout();
SearchRunOutputBox.SelectionColor = color;
SearchRunOutputBox.AppendText(message);
SearchRunOutputBox.AppendText(Environment.NewLine);
SearchRunOutputBox.ScrollToCaret();
SearchRunOutputBox.ResumeLayout();
}
Edit:
As per the first comment from Steve, and sorry I didn't mention that I had tried this before, when I remove static from the method, it pushes the error down to where I am trying to call the method from.
using Spire.Pdf;
using System;
using System.Drawing;
using System.IO;
namespace Find_Move_PWP_PDF_s
{
public class PDFOpenToCheck
{
/// <summary>
/// Takes in a file path and attempts to open the file, throwing an error if it cannot, then saying it's password protected, and logging the filepath.
/// Also checks that the file is not empty, and if it is, logs the filepath to a different log.
/// </summary>
/// <param name="filePath">Current file path from stack.</param>
public void TryToOpenPDF(string filePath)
{
PdfDocument pdf = new();
FileInfo fi = new(filePath);
try
{
pdf.LoadFromFile(filePath);
MainWindow.OutputBoxUpdater(filePath " successfully opened!", Color.Black);
}
catch (Exception)
{
//Not empty and is a PDF
if (fi.Length > 0 && filePath.EndsWith(".pdf"))
{
MainWindow.OutputBoxUpdater(filePath " is password protected!", Color.Red);
LogWriters.WritePWPPDFLog(filePath);
}
//Is an empty file
else if (fi.Length <= 0)
{
MainWindow.OutputBoxUpdater(filePath " is an empty file!", Color.Blue);
LogWriters.WriteEmptyFileLog(filePath);
}
//Is not empty and is not a PDF
else
{
MainWindow.OutputBoxUpdater(filePath " is not a PDF!", Color.Green);
}
}
}
}
}
EDIT: To show where TryToOpenPDF() is being called from.
namespace Find_Move_PWP_PDF_s
{
public static class TraverseDirectoryTree
{
/// <summary>
/// Recursive method to iterate through the directory structure below the provided start point.
/// In this application, will also perform PDF checking with Spire as it iterates (Line 74).
/// Uses stack based iteration.
/// </summary>
/// <param name="root">Starting parent directory.</param>
public static void TraverseTree(string root)
{
// Data structure to hold names of subfolders to be examined for files
// "Stack<T>" works by "first in last out" and could take a long time to build the initial stack before iteration begins
Stack<string> dirs = new();
if (!System.IO.Directory.Exists(root))
{
ArgumentException argumentException = new();
throw argumentException;
}
dirs.Push(root);
while (dirs.Count > 0)
{
string currentDir = dirs.Pop();
string[] subDirs;
try
{
subDirs = System.IO.Directory.GetDirectories(currentDir);
}
// "Unauthorized Access Exception" will be thrown if we do not have discovery permission on a folder or file.
catch (UnauthorizedAccessException e)
{
System.Diagnostics.Trace.WriteLine(e.Message);
//Console.WriteLine(e.Message);
continue;
}
//"Directory Not Found Exception" will be thrown if currentDir has been deleted by another application or thread after our call to Directory
catch (System.IO.DirectoryNotFoundException e)
{
System.Diagnostics.Trace.WriteLine(e.Message);
//Console.WriteLine(e.Message);
continue;
}
string[]? files;
try
{
files = System.IO.Directory.GetFiles(currentDir);
}
catch (UnauthorizedAccessException e)
{
System.Diagnostics.Trace.WriteLine(e.Message);
//Console.WriteLine(e.Message);
continue;
}
catch (System.IO.DirectoryNotFoundException e)
{
System.Diagnostics.Trace.WriteLine(e.Message);
//Console.WriteLine(e.Message);
continue;
}
// Perform the required action on each file here
foreach (string file in files)
{
try
{
PDFOpenToCheck.TryToOpenPDF(file);
}
catch (System.IO.FileNotFoundException e)
{
// If file was deleted by a separate application or thread since the call to "TraverseTree()", then just continue.
System.Diagnostics.Trace.WriteLine(e.Message);
//Console.WriteLine(e.Message);
continue;
}
catch (Exception e)
{
System.Diagnostics.Trace.WriteLine(e.Message);
//Console.WriteLine(e.Message);
}
}
// Push the subdirectories onto the stack for traversal
foreach (string str in subDirs)
dirs.Push(str);
}
}
}
}
CodePudding user response:
Change OutputBoxUpdater()
so it is NOT static:
public void OutputBoxUpdater(string message, Color color)
{
SearchRunOutputBox.SuspendLayout();
SearchRunOutputBox.SelectionColor = color;
SearchRunOutputBox.AppendText(message);
SearchRunOutputBox.AppendText(Environment.NewLine);
SearchRunOutputBox.ScrollToCaret();
SearchRunOutputBox.ResumeLayout();
}
Then change the signature of TryToOpenPDF()
to receive MainForm
as a parameter so you can use it:
public void TryToOpenPDF(string filePath, MainForm mf) {
// ... code ...
mf.OutputBoxUpdater(filePath " successfully opened!", Color.Black);
// ... code ...
}
Note that I'm using the parameter name mf
, and not the name of the Form itself.
Somewhere in MainForm
, you are presumably calling TryToOpenPDF()
but you haven't shown that yet.
It'd look something like:
// ... within MainForm code ...
PDFOpenToCheck pdf = new PDFOpenToCheck();
pdf.TryToOpenPDF("some file path", this);
Note we are passing the current instance of MainForm
, the one that is already visible, via this
!
--- Edit ---
So you now you have to make a choice, pass the reference first to TraverseTree()
, which then passes it on to TryToOpenPDF()
, or CHEAT with:
MainForm mf = Application.OpenForms.Cast<MainForm>().Where(x => (x is MainForm)).FirstOrDefault();
if (mf != null)
{
// ... do something with "mf" ...
}
Note that this assumes there will only ever be ONE instance of MainForm. This approach is generally frowned upon, though...