Click here to Skip to main content
15,884,836 members
Articles / Desktop Programming / MFC

IntelliFile - An Alternative Windows Version to the Famous Total Commander

Rate me:
Please Sign up or sign in to vote.
4.90/5 (44 votes)
30 Mar 2024GPL36 min read 117.1K   86   40
This article is about the IntelliFile application which is a free alternative Windows version to Total Commander and uses many components that have been published on CodeProject.

IntelliFile

Feature List

The application is free as in free speech/free beer, and the final version will have the following features:

  • File handling
    • Extended copying, moving, renaming and deleting of entire trees
    • Compare files by content, with built-in text editor
    • Encode/Decode files in base64 format
    • Show/select files with specific search pattern, size, date or contents
    • Enhanced search function with full text search in any files across multiple drives, even inside archives
    • Supports Drag & Drop with Explorer/the Desktop
  • FTP client
    • Built-in FTP client supports most public FTP servers
    • Secure FTP over SSL/TLS, enter the URL as follows: ftps://ftp.servername.com
    • Download in the background (separate thread)
  • Archive handling
    • Archives are handled like subdirectories. You can easily copy files to and from archives.
    • Built-in ZIP-compatible packer, supports long filenames! This packer is based on ZLIB by Info-Zip.
    • Pack archives in the background (separate thread)

For now, only the basic file operations are implemented: edit, copy, move, rename, and delete!
Some of the above features are still under development!

The Architecture

Each file definition is contained in a CFileData class, with the following interface:

  • DWORD GetFileAttributes(); - returns file's attributes
  • void SetFileAttributes(DWORD dwFileAttributes); - sets file's attributes
  • COleDateTime GetCreationTime(); - return file's creation date/time
  • void SetCreationTime(COleDateTime ftCreationTime); - sets file's creation date/time
  • COleDateTime GetLastAccessTime(); - return file's last read date/time
  • void SetLastAccessTime(COleDateTime ftLastAccessTime); - sets file's last read date/time
  • COleDateTime GetLastWriteTime(); - returns file's last write date/time
  • void SetLastWriteTime(COleDateTime ftLastWriteTime); - sets file's last write date/time
  • ULONGLONG GetFileSize(); - returns file's size
  • void SetFileSize(ULONGLONG nFileSize); - sets file's size
  • CString GetFileName(); - returns file's name
  • void SetFileName(CString strFileName); - sets file's name
  • CString GetAlternate(); - returns file's alternate name
  • void SetAlternate(CString strAlternateFileName); - sets file's alternate name

Then, we define CFileList as typedef CArray<cfiledata*> CFileList;

This list is managed inside the CFileSystem class, with the following interface:

  • BOOL RemoveAll(); - removes all files from list
  • int GetSize(); - returns the count of files in list
  • CFileData* GetAt(int nIndex); - returns a file definition from list
  • int GetSystemType(); - returns file system type (FAT, FTP, ZIP)
  • void SetSystemType(int nSystemType); - sets file system type (FAT, FTP, ZIP)
  • CString GetFolder(); - returns current folder path
  • BOOL SetFolder(CString strFolder); - sets current folder path
  • BOOL Refresh(); - updates the file definitions from list
  • BOOL ViewFile(CString strFilePath); - allows viewing the selected file
  • BOOL EditFile(CString strFilePath); - allows editing the selected file
  • BOOL CopyFile(CFileSystem* pDestination, CFileList* arrSelection); - copies the selected files and folders
  • BOOL MoveFile(CFileSystem* pDestination, CFileList* arrSelection); - moves the selected files and folders
  • BOOL NewFolder(CFileSystem* pDestination, CFileList* arrSelection); - creates a new folder
  • BOOL DeleteFile(CFileSystem* pDestination, CFileList* arrSelection); - deletes the selected files and folders

How to Edit Files in Windows?

C++
BOOL CFileSystem::EditFile(CString strFilePath)
{
    const int nDot = strFilePath.ReverseFind(_T('.'));
    if ((nDot != -1) && !IsApplication(strFilePath))
    {
        CString strExtension = strFilePath.Mid(nDot);

        CString strApplication;
        TCHAR lpszBuffer[0x1000] = { 0 };
        DWORD cbLength = sizeof(lpszBuffer);
        if (SUCCEEDED(AssocQueryString(0, ASSOCSTR_COMMAND, 
                      strExtension, _T("open"), lpszBuffer, &cbLength)))
        {
            lpszBuffer[cbLength] = 0;
            strApplication = lpszBuffer;
        }

        if (strApplication.IsEmpty())
        {
            MessageBox(m_hWndParent, _T("There is no application associated with 
            this type of file."), _T("IntelliFile"), MB_OK | MB_ICONEXCLAMATION);
            return FALSE;
        }

        if (strApplication.Find(_T("%1")) != -1)
        {
            strApplication.Replace(_T("\"%1\""), (_T("\"") + strFilePath + _T("\"")));
            strApplication.Replace(_T("%1"), (_T("\"") + strFilePath + _T("\"")));
        }
        else
        {
            strApplication += _T(" ") + (_T("\"") + strFilePath + _T("\""));
        }

        CString strExe;
        CString strParam;
        if (strApplication.Find(_T("rundll32.exe")) != -1)
        {
            if ((int) ShellExecute(m_hWndParent, _T("open"), 
                      strFilePath, NULL, NULL, SW_SHOWNORMAL) <= 32)
            {
                DisplayErrorBox(m_wndCaptionBar, _T("ShellExecute"), GetLastError());
                return FALSE;
            }
        }
        else
        {
            if (strApplication[0] == _T('"'))
            {
                int nPos = strApplication.Find('"', 1);
                if (nPos != -1)
                {
                    strExe = strApplication.Left(nPos+1);
                    strParam = strApplication.Mid(nPos+1);
                }
                else
                {
                    ASSERT(0);
                }
            }
            else
            {
                int nPos = strApplication.Find(' ', 1);
                if (nPos != -1)
                {
                    strExe = strApplication.Left(nPos+1);
                    strParam = strApplication.Mid(nPos+1);
                }
                else
                {
                    ASSERT(0);
                }
            }

            strExe.Trim(_T(" \r\n\t"));
            strParam.Trim(_T(" \r\n\t"));

            SHELLEXECUTEINFO pShellExecuteInfo;
            pShellExecuteInfo.cbSize = sizeof(SHELLEXECUTEINFO);
            pShellExecuteInfo.fMask = SEE_MASK_FLAG_DDEWAIT | 
            SEE_MASK_NOCLOSEPROCESS | SEE_MASK_DOENVSUBST;
            pShellExecuteInfo.hwnd = m_hWndParent;
            pShellExecuteInfo.lpVerb = NULL;
            pShellExecuteInfo.lpFile = (LPCWSTR)(strExe);
            pShellExecuteInfo.lpParameters = (LPCWSTR)(strParam);
            pShellExecuteInfo.lpDirectory = NULL;
            pShellExecuteInfo.nShow = SW_SHOWNORMAL;

            if (!ShellExecuteEx(&pShellExecuteInfo))
            {
                DisplayErrorBox(m_wndCaptionBar, _T("ShellExecute"), GetLastError());
                return FALSE;
            }
        }
        return TRUE;
    }

    return FALSE;
}

How to Copy Files in Windows?

C++
bool CFileSystem::CopyFile(CFileSystem* pDestination, CFileList* arrSelection)
{
	bool bRetVal = false;
	HRESULT hResult = S_OK;
	IFileOperation* pFileOperation = nullptr;
	IShellItem* pFolderItem = nullptr;
	IShellItem* pShellItem = nullptr;
	IShellItemArray* pShellItemArray = nullptr;
	CString strDestination = pDestination->GetCurrentFolder();

	ASSERT(pDestination != nullptr);
	ASSERT(arrSelection != nullptr);
	if ((SUCCEEDED(hResult = CoCreateInstance(CLSID_FileOperation, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&pFileOperation)))) &&
		(SUCCEEDED(hResult = pFileOperation->SetOwnerWindow(m_hWndParent))) &&
		(SUCCEEDED(hResult = pFileOperation->SetOperationFlags(FOF_NOCONFIRMMKDIR | FOF_NOERRORUI | FOFX_SHOWELEVATIONPROMPT))) &&
		(SUCCEEDED(hResult = SHCreateItemFromParsingName(strDestination, nullptr, IID_PPV_ARGS(&pFolderItem)))))
	{
		if (arrSelection->GetCount() == 1)
		{
			CFileData* pFileData = arrSelection->GetAt(0);
			ASSERT_VALID(pFileData);
			CString strFileName = pFileData->GetFileName();
			CString strFolder = GetCurrentFolder();
			CString strFilePath = strFolder + strFileName;

			if ((SUCCEEDED(hResult = SHCreateItemFromParsingName(strFilePath, nullptr, IID_PPV_ARGS(&pShellItem)))) &&
				(SUCCEEDED(hResult = pFileOperation->CopyItem(pShellItem, pFolderItem, nullptr, nullptr))) &&
				(SUCCEEDED(hResult = pFileOperation->PerformOperations())))
			{
				bRetVal = true;
			}
			else
			{
				DisplayErrorBox(m_wndCaptionBar, _T("CFileSystem::CopyFile"), hResult);
			}
		}
		else
		{
			const int nCount = (int)arrSelection->GetCount();
			LPCITEMIDLIST* arrItemIDList = new LPCITEMIDLIST[nCount];
			for (int nIndex = 0; nIndex < nCount; nIndex++)
			{
				CFileData* pFileData = arrSelection->GetAt(nIndex);
				ASSERT_VALID(pFileData);
				CString strFileName = pFileData->GetFileName();
				CString strFolder = GetCurrentFolder();
				CString strFilePath = strFolder + strFileName;

				arrItemIDList[nIndex] = ILCreateFromPath(strFilePath);
			}

			if ((SUCCEEDED(hResult = SHCreateShellItemArrayFromIDLists(nCount, arrItemIDList, &pShellItemArray))) &&
				(SUCCEEDED(hResult = pFileOperation->CopyItems(pShellItemArray, pFolderItem))) &&
				(SUCCEEDED(hResult = pFileOperation->PerformOperations())))
			{
				bRetVal = true;
			}
			else
			{
				DisplayErrorBox(m_wndCaptionBar, _T("CFileSystem::CopyFile"), hResult);
			}

			for (int nIndex = 0; nIndex < nCount; nIndex++)
			{
				ILFree((LPITEMIDLIST)arrItemIDList[nIndex]);
			}
			delete arrItemIDList;
			arrItemIDList = nullptr;
		}
	}
	else
	{
		DisplayErrorBox(m_wndCaptionBar, _T("CFileSystem::CopyFile"), hResult);
	}

	if (pShellItemArray != nullptr)
	{
		pShellItemArray->Release();
		pShellItemArray = nullptr;
	}

	if (pShellItem != nullptr)
	{
		pShellItem->Release();
		pShellItem = nullptr;
	}

	if (pFolderItem != nullptr)
	{
		pFolderItem->Release();
		pFolderItem = nullptr;
	}

	if (pFileOperation != nullptr)
	{
		pFileOperation->Release();
		pFileOperation = nullptr;
	}

	return bRetVal;
}

How to Move/Rename Files in Windows?

C++
bool CFileSystem::MoveFile(CFileSystem* pDestination, CFileList* arrSelection)
{
	bool bRetVal = false;
	HRESULT hResult = S_OK;
	IFileOperation* pFileOperation = nullptr;
	IShellItem* pFolderItem = nullptr;
	IShellItem* pShellItem = nullptr;
	IShellItemArray* pShellItemArray = nullptr;
	CString strDestination = pDestination->GetCurrentFolder();

	ASSERT(pDestination != nullptr);
	ASSERT(arrSelection != nullptr);
	if ((SUCCEEDED(hResult = CoCreateInstance(CLSID_FileOperation, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&pFileOperation)))) &&
		(SUCCEEDED(hResult = pFileOperation->SetOwnerWindow(m_hWndParent))) &&
		(SUCCEEDED(hResult = pFileOperation->SetOperationFlags(FOF_NOCONFIRMMKDIR | FOF_NOERRORUI | FOFX_SHOWELEVATIONPROMPT))) &&
		(SUCCEEDED(hResult = SHCreateItemFromParsingName(strDestination, nullptr, IID_PPV_ARGS(&pFolderItem)))))
	{
		if (arrSelection->GetCount() == 1)
		{
			CFileData* pFileData = arrSelection->GetAt(0);
			ASSERT_VALID(pFileData);
			CString strFileName = pFileData->GetFileName();
			CString strFolder = GetCurrentFolder();
			CString strFilePath = strFolder + strFileName;

			if ((SUCCEEDED(hResult = SHCreateItemFromParsingName(strFilePath, nullptr, IID_PPV_ARGS(&pShellItem)))) &&
				(SUCCEEDED(hResult = pFileOperation->MoveItem(pShellItem, pFolderItem, nullptr, nullptr))) &&
				(SUCCEEDED(hResult = pFileOperation->PerformOperations())))
			{
				bRetVal = true;

			}
			else
			{
				DisplayErrorBox(m_wndCaptionBar, _T("CFileSystem::MoveFile"), hResult);
			}
		}
		else
		{
			const int nCount = (int)arrSelection->GetCount();
			LPCITEMIDLIST* arrItemIDList = new LPCITEMIDLIST[nCount];
			for (int nIndex = 0; nIndex < nCount; nIndex++)
			{
				CFileData* pFileData = arrSelection->GetAt(nIndex);
				ASSERT_VALID(pFileData);
				CString strFileName = pFileData->GetFileName();
				CString strFolder = GetCurrentFolder();
				CString strFilePath = strFolder + strFileName;

				arrItemIDList[nIndex] = ILCreateFromPath(strFilePath);
			}

			if ((SUCCEEDED(hResult = SHCreateShellItemArrayFromIDLists(nCount, arrItemIDList, &pShellItemArray))) &&
				(SUCCEEDED(hResult = pFileOperation->MoveItems(pShellItemArray, pFolderItem))) &&
				(SUCCEEDED(hResult = pFileOperation->PerformOperations())))
			{
				bRetVal = true;
			}
			else
			{
				DisplayErrorBox(m_wndCaptionBar, _T("CFileSystem::MoveFile"), hResult);
			}

			for (int nIndex = 0; nIndex < nCount; nIndex++)
			{
				ILFree((LPITEMIDLIST)arrItemIDList[nIndex]);
			}
			delete arrItemIDList;
			arrItemIDList = nullptr;
		}
	}
	else
	{
		DisplayErrorBox(m_wndCaptionBar, _T("CFileSystem::MoveFile"), hResult);
	}

	if (pShellItemArray != nullptr)
	{
		pShellItemArray->Release();
		pShellItemArray = nullptr;
	}

	if (pShellItem != nullptr)
	{
		pShellItem->Release();
		pShellItem = nullptr;
	}

	if (pFolderItem != nullptr)
	{
		pFolderItem->Release();
		pFolderItem = nullptr;
	}

	if (pFileOperation != nullptr)
	{
		pFileOperation->Release();
		pFileOperation = nullptr;
	}

	return bRetVal;
}

How to Delete Files in Windows?

C++
bool CFileSystem::DeleteFile(CFileSystem* pDestination, CFileList* arrSelection)
{
	bool bRetVal = false;
	HRESULT hResult = S_OK;
	IFileOperation* pFileOperation = nullptr;
	IShellItem* pShellItem = nullptr;
	IShellItemArray* pShellItemArray = nullptr;
	CString strDestination = pDestination->GetCurrentFolder();

	ASSERT(pDestination != nullptr);
	ASSERT(arrSelection != nullptr);
	if ((SUCCEEDED(hResult = CoCreateInstance(CLSID_FileOperation, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&pFileOperation)))) &&
		(SUCCEEDED(hResult = pFileOperation->SetOwnerWindow(m_hWndParent))) &&
		(SUCCEEDED(hResult = pFileOperation->SetOperationFlags(FOF_NOCONFIRMMKDIR | FOF_NOERRORUI | FOFX_SHOWELEVATIONPROMPT))))
	{
		if (arrSelection->GetCount() == 1)
		{
			CFileData* pFileData = arrSelection->GetAt(0);
			ASSERT_VALID(pFileData);
			CString strFileName = pFileData->GetFileName();
			CString strFolder = GetCurrentFolder();
			CString strFilePath = strFolder + strFileName;

			if ((SUCCEEDED(hResult = SHCreateItemFromParsingName(strFilePath, nullptr, IID_PPV_ARGS(&pShellItem)))) &&
				(SUCCEEDED(hResult = pFileOperation->DeleteItem(pShellItem, nullptr))) &&
				(SUCCEEDED(hResult = pFileOperation->PerformOperations())))
			{
				bRetVal = true;

			}
			else
			{
				DisplayErrorBox(m_wndCaptionBar, _T("CFileSystem::DeleteFile"), hResult);
			}
		}
		else
		{
			const int nCount = (int)arrSelection->GetCount();
			LPCITEMIDLIST* arrItemIDList = new LPCITEMIDLIST[nCount];
			for (int nIndex = 0; nIndex < nCount; nIndex++)
			{
				CFileData* pFileData = arrSelection->GetAt(nIndex);
				ASSERT_VALID(pFileData);
				CString strFileName = pFileData->GetFileName();
				CString strFolder = GetCurrentFolder();
				CString strFilePath = strFolder + strFileName;

				arrItemIDList[nIndex] = ILCreateFromPath(strFilePath);
			}

			if ((SUCCEEDED(hResult = SHCreateShellItemArrayFromIDLists(nCount, arrItemIDList, &pShellItemArray))) &&
				(SUCCEEDED(hResult = pFileOperation->DeleteItems(pShellItemArray))) &&
				(SUCCEEDED(hResult = pFileOperation->PerformOperations())))
			{
				bRetVal = true;
			}
			else
			{
				DisplayErrorBox(m_wndCaptionBar, _T("CFileSystem::DeleteFile"), hResult);
			}

			for (int nIndex = 0; nIndex < nCount; nIndex++)
			{
				ILFree((LPITEMIDLIST)arrItemIDList[nIndex]);
			}
			delete arrItemIDList;
			arrItemIDList = nullptr;
		}
	}
	else
	{
		DisplayErrorBox(m_wndCaptionBar, _T("CFileSystem::DeleteFile"), hResult);
	}

	if (pShellItemArray != nullptr)
	{
		pShellItemArray->Release();
		pShellItemArray = nullptr;
	}

	if (pShellItem != nullptr)
	{
		pShellItem->Release();
		pShellItem = nullptr;
	}

	if (pFileOperation != nullptr)
	{
		pFileOperation->Release();
		pFileOperation = nullptr;
	}

	return bRetVal;
}

Final Words

IntelliFile application uses many components that have been published on CodeProject. Many thanks to:

  • My CMFCListView form view (see source code)
  • Armen Hakobyan for his CFolderDialog class
  • Paul DiLascia for his CHtmlCtrl class
  • PJ Naughter for his CInstanceChecker class
  • PJ Naughter for his CVersionInfo class
  • Mizan Rahman for his CWndResizer class

History

  • Version 1.01 (May 13th, 2022): Initial release
  • Version 1.02 (May 20th, 2022): Implemented "New folder" functionality
  • Version 1.03 (May 23rd, 2022): Implemented "Change drive" functionality
  • Version 1.04 (May 24th, 2022): Implemented "View text file" functionality
  • Version 1.05 (May 27th, 2022):
    • Implemented "View RTF file" functionality
    • Implemented "View XML file" functionality
    • Implemented "Context menu" functionality
  • Version 1.06 (August 21st, 2022): Added "Change drive..." icon
  • Version 1.07 (September 9th, 2022): Added Contributors hyperlink to AboutBox dialog
  • Version 1.08 (January 23rd, 2023): Updated PJ Naughter's CVersionInfo library to the latest version available
    Updated the code to use C++ uniform initialization for all variable declarations
  • Version 1.09 (January 24rd, 2023): Updated PJ Naughter's CInstanceChecker library to the latest version available
    Updated the code to use C++ uniform initialization for all variable declarations
  • Replaced NULL throughout the codebase with nullptr
    Replaced BOOL throughout the codebase with bool
    This means that the minimum requirement for the application is now Microsoft Visual C++ 2010.
  • Version 1.10 (April 25th, 2023): Added base64 encode/decode functions
  • Version 1.11 (May 13th, 2023): Added new changes suggested by Rick Dishman: Reset View, and save last folder
  • Version 1.12 (May 15th, 2023): Added rename of file name on clicking its label in MFC ListView
  • Version 1.13 (May 18th, 2023): Fixed an issue regarding editing image files reported by Rick Dishman
  • Version 1.14 (May 19th, 2023): Fixed an issue regarding statusbar reported by Rick Dishman
  • Version 1.15 (May 21st, 2023): Changed the double click implementation to open a file in EDIT mode
  • Version 1.16 (May 27th, 2023): Updated About dialog with GPLv3 notice
  • Version 1.17 (June 17th, 2023): Added quick access dialog for favorite folders
  • Version 1.18 (June 25th, 2023):
    • Implemented "Command prompt" functionality
    • Replaced old CHyperlinkStatic class with PJ Naughter's CHLinkCtrl library
  • Version 1.19 (August 17th, 2023):
    • Implemented "Switch views" functionality (Switches source view with target view)
    • Added social media links: Twitter, LinkedIn, Facebook, and Instagram
    • Added shortcuts to GitHub repository's Issues, Discussions, and Wiki
  • Version 1.20 (August 26th, 2023):
    • Refactored CopyFile, MoveFile and DeleteFile functions
    • Changed article's download link. Updated the About dialog (email & website)
  • Version 1.21 (September 22nd, 2023): Switched to Visual Studio Enterprise 2022 (some changes were made in the source code of the project)
  • Version 1.22 (September 30th, 2023): Added SCINTILLA control to view source code with syntax highlighting
  • Version 1.23 (December 10th, 2023): Updated PJ Naughter's CScintillaCtrl library to the latest version available
    Removed the SetCallDirect & GetCallDirect methods. Instead, now the CScintillaCtrl class will call the m_DirectStatusFunction if the calling thread is the same as the thread on which the Scintilla control was created. Thanks to Markus Nissl for this update.
  • Version 1.24 (December 29th, 2023): Updated PJ Naughter's CScintillaCtrl library to the latest version available
    Updated class to work with Scintilla v5.4.1. New messages wrapped include: SCI_CHANGESELECTIONMODE, SCI_SETMOVEEXTENDSSELECTION & SCI_SELECTIONFROMPOINT. Also updated the signatures of the following methods: GetDocPointer, SetDocPointer, CreateDocument, AddRefDocument and ReleaseDocument.
  • Version 1.25 (January 28th, 2024):
    • Added ReleaseNotes.html and SoftwareContentRegister.html to GitHub repo
    • Replaced old CFileDialogST class with Armen Hakobyan's CFolderDialog library
  • Version 1.26 (February 21st, 2024): Switched MFC application' theme back to native Windows.
  • Version 1.27.1 (March 31st, 2024):
    • Updated LEXILLA library to version 5.3.1 and SCINTILLA library to version 5.4.3.
    • Updated PJ Naughter's CScintillaCtrl library to the latest version available.
      Updated class to work with Scintilla v5.4.3. New messages wrapped include: SCI_GETUNDOACTIONS, SCI_GETUNDOSAVEPOINT, SCI_SETUNDODETACH, SCI_SETUNDOTENTATIVE, SCI_SETUNDOCURRENT, SCI_PUSHUNDOACTIONTYPE, SCI_CHANGELASTUNDOACTIONTEXT, SCI_GETUNDOACTIONTYPE, SCI_GETUNDOACTIONPOSITION & SCI_GETUNDOACTIONTEXT.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)


Written By
Software Developer NXP Semiconductors
Romania Romania
My professional background includes knowledge of analyst programmer for Microsoft Visual C++, Microsoft Visual C#, Microsoft Visual Basic, Sun Java, assembly for Intel 80x86 microprocessors, assembly for PIC microcontrollers (produced by Microchip Inc.), relational databases (MySQL, Oracle, SQL Server), concurrent version systems, bug tracking systems, web design (HTML5, CSS3, XML, PHP/MySQL, JavaScript).

Comments and Discussions

 
AnswerRe: Rethink your approach to your posted projects Pin
Midnight48913-Oct-23 10:46
Midnight48913-Oct-23 10:46 
GeneralRe: Rethink your approach to your posted projects Pin
Stacy Dudovitz18-Oct-23 13:53
professionalStacy Dudovitz18-Oct-23 13:53 
GeneralRe: Rethink your approach to your posted projects Pin
AdrianGonzalez21-Feb-24 10:09
AdrianGonzalez21-Feb-24 10:09 
GeneralMy vote of 5 Pin
Igor Ladnik7-Jun-22 1:41
professionalIgor Ladnik7-Jun-22 1:41 
GeneralRe: My vote of 5 Pin
Ștefan-Mihai MOGA7-Jun-22 1:52
professionalȘtefan-Mihai MOGA7-Jun-22 1:52 
GeneralMy vote of 5 Pin
Member 1370414323-May-22 22:38
Member 1370414323-May-22 22:38 
GeneralRe: My vote of 5 Pin
Ștefan-Mihai MOGA23-May-22 23:26
professionalȘtefan-Mihai MOGA23-May-22 23:26 
SuggestionHandling Links Pin
Member 1172312416-May-22 2:38
Member 1172312416-May-22 2:38 
There probably should be ways to: create links, list hard link siblings, and show symlink and junction targets.
GeneralRe: Handling Links Pin
Sergey Alexandrovich Kryukov17-Jun-23 8:49
mvaSergey Alexandrovich Kryukov17-Jun-23 8:49 
GeneralMy vote of 3 Pin
Rudolf Jan15-May-22 22:39
Rudolf Jan15-May-22 22:39 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.