From 9de6fbcb623feb6b3efefb3e6f30049c2510fb02 Mon Sep 17 00:00:00 2001
From: Arda Eren <70160402+DeCEll-1@users.noreply.github.com>
Date: Thu, 6 Mar 2025 05:44:00 +0300
Subject: [PATCH 01/11] Fix wildcard & confirm override CreateSymLinkFile.ps1
---
CreateSymLinkFile.ps1 | 86 ++++++++++++++++++++++++++++++++++---------
1 file changed, 69 insertions(+), 17 deletions(-)
diff --git a/CreateSymLinkFile.ps1 b/CreateSymLinkFile.ps1
index 9bbb73e..80e46c8 100644
--- a/CreateSymLinkFile.ps1
+++ b/CreateSymLinkFile.ps1
@@ -1,17 +1,55 @@
+Add-Type -AssemblyName PresentationFramework
# Function to check for elevated privileges
function Test-Admin {
$currentUser = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
return $currentUser.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
+function Confirm-Overwrite {
+ param ($linkPath)
+
+ # Presume that it's not a folder
+ $isDirectory = $false
+
+ if (-not [string]::IsNullOrWhiteSpace($linkPath)) {
+ # If the input box isn't empty, check if it's a valid path
+ if (Test-Path $linkPath -PathType Leaf) {
+ # if the path points to a file, it is not a folder
+ $isDirectory = $false
+ }
+ elseif (Test-Path $linkPath -PathType Container) {
+ # if the path points to a folder, it is a folder
+ $isDirectory = $true
+ }
+ }
+
+ $message = "A $(if ($isDirectory) { 'folder' } else { 'file' }) with the name '$(Split-Path $linkPath -Leaf)' already exists. Overwrite?"
+ $result = [System.Windows.MessageBox]::Show(
+ $message,
+ "Confirm Overwrite",
+ [System.Windows.MessageBoxButton]::YesNoCancel,
+ [System.Windows.MessageBoxImage]::Warning
+ )
+ return $result
+}
+
+function Escape-WildcardCharacters {
+ param (
+ [string]$path
+ )
+ $escapedPath = $path -replace '([*?\[\]])', '``$1'
+ return $escapedPath
+}
+
# Save the initial working directory
-$initialWorkingDirectory = (Get-Location).Path
+$initialWorkingDirectory = [System.IO.Directory]::GetCurrentDirectory()
+$escapedInitialWorkingDirectory = Escape-WildcardCharacters -path $initialWorkingDirectory
if (-not (Test-Admin)) {
Write-Output "Please run this script as an administrator. Let's try rerunning automatically..."
# Re-run the script with elevated privileges, passing the initial working directory as an argument
- Start-Process -FilePath "powershell.exe" -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" `"$initialWorkingDirectory`"" -Verb RunAs
+ Start-Process -FilePath "powershell.exe" -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" `"$escapedInitialWorkingDirectory`"" -Verb RunAs
Exit # Exit the non-elevated instance
}
@@ -27,11 +65,14 @@ function Show-FilePickerDialog {
$dialog.Filter = "All files (*.*)|*.*"
if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
return $dialog.FileName
- } else {
+ }
+ else {
return $null
}
}
+# Function to escape wildcard characters in a path
+
# Main script
$selectedPath = Show-FilePickerDialog
@@ -40,35 +81,46 @@ if ($selectedPath) {
$linkName = Split-Path -Leaf $selectedPath
$linkPath = Join-Path -Path $currentDir -ChildPath $linkName
+ # Escape wildcard characters in the paths
+ $escapedLinkPath = Escape-WildcardCharacters -path $linkPath
+ $escapedSelectedPath = Escape-WildcardCharacters -path $selectedPath
+
Write-Output "Original Working Directory: $originalWorkingDirectory"
Write-Output "Current Directory: $currentDir"
Write-Output "Selected Path: $selectedPath"
+ Write-Output "Escaped Selected Path: $escapedSelectedPath"
Write-Output "Link Path: $linkPath"
+ Write-Output "Escaped Link Path: $escapedLinkPath"
- # Check if selected item is a file, and then check if we already have a file with that name and offer to overwrite if we do
- if (Test-Path -Path $selectedPath -PathType Leaf) {
- if (Test-Path -Path $linkPath) {
- $choice = Confirm-Overwrite -linkPath $linkPath
+ # Check if selected item is a file, and then check if we already have a file with that name and offer to overwrite if we do
+ if (Test-Path -Path $escapedSelectedPath -PathType Leaf) {
+ if (Test-Path -Path $escapedLinkPath) {
+ $choice = Confirm-Overwrite -linkPath $escapedLinkPath
if ($choice -eq 'Yes') {
# Remove the existing symlink
- Remove-Item -Path $linkPath -Force
+ Remove-Item -Path $escapedLinkPath -Force
# Create a new file symbolic link
- New-Item -ItemType SymbolicLink -Path $linkPath -Target $selectedPath -ErrorAction Stop
- Write-Output "Overwritten file symbolic link: $linkPath -> $selectedPath"
- } elseif ($choice -eq 'No') {
+ New-Item -ItemType SymbolicLink -Path $linkPath -Target $escapedSelectedPath -ErrorAction Stop
+ Write-Output "Overwritten file symbolic link: $escapedLinkPath -> $escapedSelectedPath"
+ }
+ elseif ($choice -eq 'No') {
Write-Output "Symbolic link (or file/folder with that name) already existed! Operation canceled by user by not overwriting."
- } else {
+ }
+ else {
Write-Output "Operation canceled by user."
}
- } else {
+ }
+ else {
# Create a new file symbolic link
- New-Item -ItemType SymbolicLink -Path $linkPath -Target $selectedPath -ErrorAction Stop
- Write-Output "Created file symbolic link: $linkPath -> $selectedPath"
+ New-Item -ItemType SymbolicLink -Path $linkPath -Target $escapedSelectedPath -ErrorAction Stop
+ Write-Output "Created file symbolic link: $escapedLinkPath -> $escapedSelectedPath"
}
- } else {
+ }
+ else {
Write-Output "The selected path is not a file."
}
-} else {
+}
+else {
Write-Output "No file was selected."
}
From 4f05291e83ee0499c0254e285a3ae3e49b3ef969 Mon Sep 17 00:00:00 2001
From: Arda Eren <70160402+DeCEll-1@users.noreply.github.com>
Date: Thu, 6 Mar 2025 06:45:42 +0300
Subject: [PATCH 02/11] fix for wildcard along with newer folder pickup
CreateSymLinkFolder.ps1
---
CreateSymLinkFolder.ps1 | 247 ++++++++++++++++++++++++++++++++++++----
1 file changed, 225 insertions(+), 22 deletions(-)
diff --git a/CreateSymLinkFolder.ps1 b/CreateSymLinkFolder.ps1
index 5d6366d..d3fbe59 100644
--- a/CreateSymLinkFolder.ps1
+++ b/CreateSymLinkFolder.ps1
@@ -1,17 +1,203 @@
+$source = @'
+// https://stackoverflow.com/a/66823582/21149029
+using System;
+using System.Diagnostics;
+using System.Reflection;
+using System.Windows.Forms;
+///
+/// Present the Windows Vista-style open file dialog to select a folder. Fall back for older Windows Versions
+///
+#pragma warning disable 0219, 0414, 0162
+public class FolderSelectDialog {
+ private string _initialDirectory;
+ private string _title;
+ private string _message;
+ private string _fileName = "";
+
+ public string InitialDirectory {
+ get { return string.IsNullOrEmpty(_initialDirectory) ? Environment.CurrentDirectory : _initialDirectory; }
+ set { _initialDirectory = value; }
+ }
+ public string Title {
+ get { return _title ?? "Select a folder"; }
+ set { _title = value; }
+ }
+ public string Message {
+ get { return _message ?? _title ?? "Select a folder"; }
+ set { _message = value; }
+ }
+ public string FileName { get { return _fileName; } }
+
+ public FolderSelectDialog(string defaultPath="MyComputer", string title="Select a folder", string message=""){
+ InitialDirectory = defaultPath;
+ Title = title;
+ Message = message;
+ }
+
+ public bool Show() { return Show(IntPtr.Zero); }
+
+ /// Handle of the control or window to be the parent of the file dialog
+ /// true if the user clicks OK
+ public bool Show(IntPtr? hWndOwnerNullable=null) {
+ IntPtr hWndOwner = IntPtr.Zero;
+ if(hWndOwnerNullable!=null)
+ hWndOwner = (IntPtr)hWndOwnerNullable;
+ if(Environment.OSVersion.Version.Major >= 6){
+ try{
+ var resulta = VistaDialog.Show(hWndOwner, InitialDirectory, Title, Message);
+ _fileName = resulta.FileName;
+ return resulta.Result;
+ }
+ catch(Exception){
+ var resultb = ShowXpDialog(hWndOwner, InitialDirectory, Title, Message);
+ _fileName = resultb.FileName;
+ return resultb.Result;
+ }
+ }
+ var result = ShowXpDialog(hWndOwner, InitialDirectory, Title, Message);
+ _fileName = result.FileName;
+ return result.Result;
+ }
+
+ private struct ShowDialogResult {
+ public bool Result { get; set; }
+ public string FileName { get; set; }
+ }
+
+ private static ShowDialogResult ShowXpDialog(IntPtr ownerHandle, string initialDirectory, string title, string message) {
+ var folderBrowserDialog = new FolderBrowserDialog {
+ Description = message,
+ SelectedPath = initialDirectory,
+ ShowNewFolderButton = true
+ };
+ var dialogResult = new ShowDialogResult();
+ if (folderBrowserDialog.ShowDialog(new WindowWrapper(ownerHandle)) == DialogResult.OK) {
+ dialogResult.Result = true;
+ dialogResult.FileName = folderBrowserDialog.SelectedPath;
+ }
+ return dialogResult;
+ }
+
+ private static class VistaDialog {
+ private const string c_foldersFilter = "Folders|\n";
+
+ private const BindingFlags c_flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
+ private readonly static Assembly s_windowsFormsAssembly = typeof(FileDialog).Assembly;
+ private readonly static Type s_iFileDialogType = s_windowsFormsAssembly.GetType("System.Windows.Forms.FileDialogNative+IFileDialog");
+ private readonly static MethodInfo s_createVistaDialogMethodInfo = typeof(OpenFileDialog).GetMethod("CreateVistaDialog", c_flags);
+ private readonly static MethodInfo s_onBeforeVistaDialogMethodInfo = typeof(OpenFileDialog).GetMethod("OnBeforeVistaDialog", c_flags);
+ private readonly static MethodInfo s_getOptionsMethodInfo = typeof(FileDialog).GetMethod("GetOptions", c_flags);
+ private readonly static MethodInfo s_setOptionsMethodInfo = s_iFileDialogType.GetMethod("SetOptions", c_flags);
+ private readonly static uint s_fosPickFoldersBitFlag = (uint) s_windowsFormsAssembly
+ .GetType("System.Windows.Forms.FileDialogNative+FOS")
+ .GetField("FOS_PICKFOLDERS")
+ .GetValue(null);
+ private readonly static ConstructorInfo s_vistaDialogEventsConstructorInfo = s_windowsFormsAssembly
+ .GetType("System.Windows.Forms.FileDialog+VistaDialogEvents")
+ .GetConstructor(c_flags, null, new[] { typeof(FileDialog) }, null);
+ private readonly static MethodInfo s_adviseMethodInfo = s_iFileDialogType.GetMethod("Advise");
+ private readonly static MethodInfo s_unAdviseMethodInfo = s_iFileDialogType.GetMethod("Unadvise");
+ private readonly static MethodInfo s_showMethodInfo = s_iFileDialogType.GetMethod("Show");
+
+ public static ShowDialogResult Show(IntPtr ownerHandle, string initialDirectory, string title, string description) {
+ var openFileDialog = new OpenFileDialog {
+ AddExtension = false,
+ CheckFileExists = false,
+ DereferenceLinks = true,
+ Filter = c_foldersFilter,
+ InitialDirectory = initialDirectory,
+ Multiselect = false,
+ Title = title
+ };
+
+ var iFileDialog = s_createVistaDialogMethodInfo.Invoke(openFileDialog, new object[] { });
+ s_onBeforeVistaDialogMethodInfo.Invoke(openFileDialog, new[] { iFileDialog });
+ s_setOptionsMethodInfo.Invoke(iFileDialog, new object[] { (uint) s_getOptionsMethodInfo.Invoke(openFileDialog, new object[] { }) | s_fosPickFoldersBitFlag });
+ var adviseParametersWithOutputConnectionToken = new[] { s_vistaDialogEventsConstructorInfo.Invoke(new object[] { openFileDialog }), 0U };
+ s_adviseMethodInfo.Invoke(iFileDialog, adviseParametersWithOutputConnectionToken);
+
+ try {
+ int retVal = (int) s_showMethodInfo.Invoke(iFileDialog, new object[] { ownerHandle });
+ return new ShowDialogResult {
+ Result = retVal == 0,
+ FileName = openFileDialog.FileName
+ };
+ }
+ finally {
+ s_unAdviseMethodInfo.Invoke(iFileDialog, new[] { adviseParametersWithOutputConnectionToken[1] });
+ }
+ }
+ }
+
+ // Wrap an IWin32Window around an IntPtr
+ private class WindowWrapper : IWin32Window {
+ private readonly IntPtr _handle;
+ public WindowWrapper(IntPtr handle) { _handle = handle; }
+ public IntPtr Handle { get { return _handle; } }
+ }
+
+ public string getPath(){
+ if (Show()){
+ return FileName;
+ }
+ return "";
+ }
+}
+'@
# Function to check for elevated privileges
function Test-Admin {
$currentUser = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
return $currentUser.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
+function Confirm-Overwrite {
+ param (
+ $linkPath
+ )
+ Add-Type -AssemblyName PresentationFramework
+
+ # Presume that it's not a folder
+ $isDirectory = $false
+
+ if (-not [string]::IsNullOrWhiteSpace($linkPath)) {
+ # If the input box isn't empty, check if it's a valid path
+ if (Test-Path $linkPath -PathType Leaf) {
+ # if the path points to a file, it is not a folder
+ $isDirectory = $false
+ }
+ elseif (Test-Path $linkPath -PathType Container) {
+ # if the path points to a folder, it is a folder
+ $isDirectory = $true
+ }
+ }
+
+ $message = "A $(if ($isDirectory) { 'folder' } else { 'file' }) with the name '$(Split-Path $linkPath -Leaf)' already exists. Overwrite?"
+ $result = [System.Windows.MessageBox]::Show(
+ $message,
+ "Confirm Overwrite",
+ [System.Windows.MessageBoxButton]::YesNoCancel,
+ [System.Windows.MessageBoxImage]::Warning
+ )
+ return $result
+}
+
+function Escape-WildcardCharacters {
+ param (
+ [string]$path
+ )
+ $escapedPath = $path -replace '([*?\[\]])', '``$1'
+ return $escapedPath
+}
+
# Save the initial working directory
-$initialWorkingDirectory = (Get-Location).Path
+$initialWorkingDirectory = [System.IO.Directory]::GetCurrentDirectory()
+$escapedInitialWorkingDirectory = Escape-WildcardCharacters -path $initialWorkingDirectory
if (-not (Test-Admin)) {
Write-Output "Please run this script as an administrator. Let's try rerunning automatically..."
# Re-run the script with elevated privileges, passing the initial working directory as an argument
- Start-Process -FilePath "powershell.exe" -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" `"$initialWorkingDirectory`"" -Verb RunAs
+ Start-Process -FilePath "powershell.exe" -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" `"$escapedInitialWorkingDirectory`"" -Verb RunAs
Exit # Exit the non-elevated instance
}
@@ -21,15 +207,21 @@ Set-Location -Path $originalWorkingDirectory
# Function to show folder picker dialog
function Show-FolderPickerDialog {
- Add-Type -AssemblyName System.Windows.Forms
- $dialog = New-Object System.Windows.Forms.FolderBrowserDialog
- $dialog.Description = "Select a folder to create a symbolic link"
- $dialog.SelectedPath = [System.IO.Directory]::GetCurrentDirectory()
- if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
- return $dialog.SelectedPath
- } else {
+
+ Add-Type -Language CSharp -TypeDefinition $source -ReferencedAssemblies ("System.Windows.Forms", "System.ComponentModel.Primitives")
+
+ $path = [System.IO.Directory]::GetCurrentDirectory()
+ $title = "Select Folder"
+ $description = "Select a folder to create a symbolic link"
+
+ $out = [FolderSelectDialog]::new($path, $title, $description).getPath()
+
+ if ($out -eq "") {
return $null
}
+ else {
+ return $out
+ }
}
# Main script
@@ -40,34 +232,45 @@ if ($selectedPath) {
$linkName = Split-Path -Leaf $selectedPath
$linkPath = Join-Path -Path $currentDir -ChildPath $linkName
+ # Escape wildcard characters in the paths
+ $escapedLinkPath = Escape-WildcardCharacters -path $linkPath
+ $escapedSelectedPath = Escape-WildcardCharacters -path $selectedPath
+
Write-Output "Original Working Directory: $originalWorkingDirectory"
Write-Output "Current Directory: $currentDir"
Write-Output "Selected Path: $selectedPath"
+ Write-Output "Escaped Selected Path: $escapedSelectedPath"
Write-Output "Link Path: $linkPath"
+ Write-Output "Escaped Link Path: $escapedLinkPath"
- if (Test-Path -Path $selectedPath -PathType Container) {
- if (Test-Path -Path $linkPath) {
- $choice = Confirm-Overwrite -linkPath $linkPath
+ if (Test-Path -Path $escapedSelectedPath -PathType Container) {
+ if (Test-Path -Path $escapedLinkPath) {
+ $choice = Confirm-Overwrite -linkPath $escapedLinkPath
if ($choice -eq 'Yes') {
# Remove the existing symlink
- Remove-Item -Path $linkPath -Force
+ Remove-Item -Path $escapedLinkPath -Force
# Create a new directory symbolic link
- New-Item -ItemType SymbolicLink -Path $linkPath -Target $selectedPath -ErrorAction Stop
- Write-Output "Overwritten directory symbolic link: $linkPath -> $selectedPath"
- } elseif ($choice -eq 'No') {
+ New-Item -ItemType SymbolicLink -Path $linkPath -Target $escapedSelectedPath -ErrorAction Stop
+ Write-Output "Overwritten directory symbolic link: $escapedLinkPath -> $escapedSelectedPath"
+ }
+ elseif ($choice -eq 'No') {
Write-Output "Symbolic link (or file/folder with that name) already existed! Operation canceled by user by not overwriting."
- } else {
+ }
+ else {
Write-Output "Operation canceled by user."
}
- } else {
+ }
+ else {
# Create a new directory symbolic link
- New-Item -ItemType SymbolicLink -Path $linkPath -Target $selectedPath -ErrorAction Stop
- Write-Output "Created directory symbolic link: $linkPath -> $selectedPath"
+ New-Item -ItemType SymbolicLink -Path $linkPath -Target $escapedSelectedPath -ErrorAction Stop
+ Write-Output "Created directory symbolic link: $escapedLinkPath -> $escapedSelectedPath"
}
- } else {
+ }
+ else {
Write-Output "The selected path is not a folder."
}
-} else {
+}
+else {
Write-Output "No folder was selected."
}
From 5752ddb116cb319adea297e997bc480f9c930286 Mon Sep 17 00:00:00 2001
From: Arda Eren <70160402+DeCEll-1@users.noreply.github.com>
Date: Thu, 6 Mar 2025 06:46:01 +0300
Subject: [PATCH 03/11] Syntax Update CreateSymLinkFile.ps1
---
CreateSymLinkFile.ps1 | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/CreateSymLinkFile.ps1 b/CreateSymLinkFile.ps1
index 80e46c8..798810a 100644
--- a/CreateSymLinkFile.ps1
+++ b/CreateSymLinkFile.ps1
@@ -1,4 +1,3 @@
-Add-Type -AssemblyName PresentationFramework
# Function to check for elevated privileges
function Test-Admin {
$currentUser = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
@@ -6,7 +5,10 @@ function Test-Admin {
}
function Confirm-Overwrite {
- param ($linkPath)
+ param (
+ $linkPath
+ )
+ Add-Type -AssemblyName PresentationFramework
# Presume that it's not a folder
$isDirectory = $false
From 7f96a5635425f01aaa4d699e200c52540ce319ea Mon Sep 17 00:00:00 2001
From: Arda Eren <70160402+DeCEll-1@users.noreply.github.com>
Date: Fri, 7 Mar 2025 19:28:50 +0300
Subject: [PATCH 04/11] Update CreateSymLinkFolder.ps1
---
CreateSymLinkFolder.ps1 | 206 +++-------------------------------------
1 file changed, 15 insertions(+), 191 deletions(-)
diff --git a/CreateSymLinkFolder.ps1 b/CreateSymLinkFolder.ps1
index d3fbe59..5bc614d 100644
--- a/CreateSymLinkFolder.ps1
+++ b/CreateSymLinkFolder.ps1
@@ -1,149 +1,3 @@
-$source = @'
-// https://stackoverflow.com/a/66823582/21149029
-using System;
-using System.Diagnostics;
-using System.Reflection;
-using System.Windows.Forms;
-///
-/// Present the Windows Vista-style open file dialog to select a folder. Fall back for older Windows Versions
-///
-#pragma warning disable 0219, 0414, 0162
-public class FolderSelectDialog {
- private string _initialDirectory;
- private string _title;
- private string _message;
- private string _fileName = "";
-
- public string InitialDirectory {
- get { return string.IsNullOrEmpty(_initialDirectory) ? Environment.CurrentDirectory : _initialDirectory; }
- set { _initialDirectory = value; }
- }
- public string Title {
- get { return _title ?? "Select a folder"; }
- set { _title = value; }
- }
- public string Message {
- get { return _message ?? _title ?? "Select a folder"; }
- set { _message = value; }
- }
- public string FileName { get { return _fileName; } }
-
- public FolderSelectDialog(string defaultPath="MyComputer", string title="Select a folder", string message=""){
- InitialDirectory = defaultPath;
- Title = title;
- Message = message;
- }
-
- public bool Show() { return Show(IntPtr.Zero); }
-
- /// Handle of the control or window to be the parent of the file dialog
- /// true if the user clicks OK
- public bool Show(IntPtr? hWndOwnerNullable=null) {
- IntPtr hWndOwner = IntPtr.Zero;
- if(hWndOwnerNullable!=null)
- hWndOwner = (IntPtr)hWndOwnerNullable;
- if(Environment.OSVersion.Version.Major >= 6){
- try{
- var resulta = VistaDialog.Show(hWndOwner, InitialDirectory, Title, Message);
- _fileName = resulta.FileName;
- return resulta.Result;
- }
- catch(Exception){
- var resultb = ShowXpDialog(hWndOwner, InitialDirectory, Title, Message);
- _fileName = resultb.FileName;
- return resultb.Result;
- }
- }
- var result = ShowXpDialog(hWndOwner, InitialDirectory, Title, Message);
- _fileName = result.FileName;
- return result.Result;
- }
-
- private struct ShowDialogResult {
- public bool Result { get; set; }
- public string FileName { get; set; }
- }
-
- private static ShowDialogResult ShowXpDialog(IntPtr ownerHandle, string initialDirectory, string title, string message) {
- var folderBrowserDialog = new FolderBrowserDialog {
- Description = message,
- SelectedPath = initialDirectory,
- ShowNewFolderButton = true
- };
- var dialogResult = new ShowDialogResult();
- if (folderBrowserDialog.ShowDialog(new WindowWrapper(ownerHandle)) == DialogResult.OK) {
- dialogResult.Result = true;
- dialogResult.FileName = folderBrowserDialog.SelectedPath;
- }
- return dialogResult;
- }
-
- private static class VistaDialog {
- private const string c_foldersFilter = "Folders|\n";
-
- private const BindingFlags c_flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
- private readonly static Assembly s_windowsFormsAssembly = typeof(FileDialog).Assembly;
- private readonly static Type s_iFileDialogType = s_windowsFormsAssembly.GetType("System.Windows.Forms.FileDialogNative+IFileDialog");
- private readonly static MethodInfo s_createVistaDialogMethodInfo = typeof(OpenFileDialog).GetMethod("CreateVistaDialog", c_flags);
- private readonly static MethodInfo s_onBeforeVistaDialogMethodInfo = typeof(OpenFileDialog).GetMethod("OnBeforeVistaDialog", c_flags);
- private readonly static MethodInfo s_getOptionsMethodInfo = typeof(FileDialog).GetMethod("GetOptions", c_flags);
- private readonly static MethodInfo s_setOptionsMethodInfo = s_iFileDialogType.GetMethod("SetOptions", c_flags);
- private readonly static uint s_fosPickFoldersBitFlag = (uint) s_windowsFormsAssembly
- .GetType("System.Windows.Forms.FileDialogNative+FOS")
- .GetField("FOS_PICKFOLDERS")
- .GetValue(null);
- private readonly static ConstructorInfo s_vistaDialogEventsConstructorInfo = s_windowsFormsAssembly
- .GetType("System.Windows.Forms.FileDialog+VistaDialogEvents")
- .GetConstructor(c_flags, null, new[] { typeof(FileDialog) }, null);
- private readonly static MethodInfo s_adviseMethodInfo = s_iFileDialogType.GetMethod("Advise");
- private readonly static MethodInfo s_unAdviseMethodInfo = s_iFileDialogType.GetMethod("Unadvise");
- private readonly static MethodInfo s_showMethodInfo = s_iFileDialogType.GetMethod("Show");
-
- public static ShowDialogResult Show(IntPtr ownerHandle, string initialDirectory, string title, string description) {
- var openFileDialog = new OpenFileDialog {
- AddExtension = false,
- CheckFileExists = false,
- DereferenceLinks = true,
- Filter = c_foldersFilter,
- InitialDirectory = initialDirectory,
- Multiselect = false,
- Title = title
- };
-
- var iFileDialog = s_createVistaDialogMethodInfo.Invoke(openFileDialog, new object[] { });
- s_onBeforeVistaDialogMethodInfo.Invoke(openFileDialog, new[] { iFileDialog });
- s_setOptionsMethodInfo.Invoke(iFileDialog, new object[] { (uint) s_getOptionsMethodInfo.Invoke(openFileDialog, new object[] { }) | s_fosPickFoldersBitFlag });
- var adviseParametersWithOutputConnectionToken = new[] { s_vistaDialogEventsConstructorInfo.Invoke(new object[] { openFileDialog }), 0U };
- s_adviseMethodInfo.Invoke(iFileDialog, adviseParametersWithOutputConnectionToken);
-
- try {
- int retVal = (int) s_showMethodInfo.Invoke(iFileDialog, new object[] { ownerHandle });
- return new ShowDialogResult {
- Result = retVal == 0,
- FileName = openFileDialog.FileName
- };
- }
- finally {
- s_unAdviseMethodInfo.Invoke(iFileDialog, new[] { adviseParametersWithOutputConnectionToken[1] });
- }
- }
- }
-
- // Wrap an IWin32Window around an IntPtr
- private class WindowWrapper : IWin32Window {
- private readonly IntPtr _handle;
- public WindowWrapper(IntPtr handle) { _handle = handle; }
- public IntPtr Handle { get { return _handle; } }
- }
-
- public string getPath(){
- if (Show()){
- return FileName;
- }
- return "";
- }
-}
-'@
# Function to check for elevated privileges
function Test-Admin {
$currentUser = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
@@ -151,27 +5,10 @@ function Test-Admin {
}
function Confirm-Overwrite {
- param (
- $linkPath
- )
+ param ($linkPath)
Add-Type -AssemblyName PresentationFramework
- # Presume that it's not a folder
- $isDirectory = $false
-
- if (-not [string]::IsNullOrWhiteSpace($linkPath)) {
- # If the input box isn't empty, check if it's a valid path
- if (Test-Path $linkPath -PathType Leaf) {
- # if the path points to a file, it is not a folder
- $isDirectory = $false
- }
- elseif (Test-Path $linkPath -PathType Container) {
- # if the path points to a folder, it is a folder
- $isDirectory = $true
- }
- }
-
- $message = "A $(if ($isDirectory) { 'folder' } else { 'file' }) with the name '$(Split-Path $linkPath -Leaf)' already exists. Overwrite?"
+ $message = "A folder with the name '$(Split-Path $linkPath -Leaf)' already exists. Overwrite?"
$result = [System.Windows.MessageBox]::Show(
$message,
"Confirm Overwrite",
@@ -182,9 +19,7 @@ function Confirm-Overwrite {
}
function Escape-WildcardCharacters {
- param (
- [string]$path
- )
+ param ([string]$path)
$escapedPath = $path -replace '([*?\[\]])', '``$1'
return $escapedPath
}
@@ -207,21 +42,15 @@ Set-Location -Path $originalWorkingDirectory
# Function to show folder picker dialog
function Show-FolderPickerDialog {
-
- Add-Type -Language CSharp -TypeDefinition $source -ReferencedAssemblies ("System.Windows.Forms", "System.ComponentModel.Primitives")
-
- $path = [System.IO.Directory]::GetCurrentDirectory()
- $title = "Select Folder"
- $description = "Select a folder to create a symbolic link"
-
- $out = [FolderSelectDialog]::new($path, $title, $description).getPath()
-
- if ($out -eq "") {
+ Add-Type -AssemblyName System.Windows.Forms
+ $dialog = New-Object System.Windows.Forms.FolderBrowserDialog
+ $dialog.Description = "Select a folder to create a symbolic link"
+ $dialog.SelectedPath = [System.IO.Directory]::GetCurrentDirectory()
+ if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
+ return $dialog.SelectedPath
+ } else {
return $null
}
- else {
- return $out
- }
}
# Main script
@@ -252,25 +81,20 @@ if ($selectedPath) {
# Create a new directory symbolic link
New-Item -ItemType SymbolicLink -Path $linkPath -Target $escapedSelectedPath -ErrorAction Stop
Write-Output "Overwritten directory symbolic link: $escapedLinkPath -> $escapedSelectedPath"
- }
- elseif ($choice -eq 'No') {
+ } elseif ($choice -eq 'No') {
Write-Output "Symbolic link (or file/folder with that name) already existed! Operation canceled by user by not overwriting."
- }
- else {
+ } else {
Write-Output "Operation canceled by user."
}
- }
- else {
+ } else {
# Create a new directory symbolic link
New-Item -ItemType SymbolicLink -Path $linkPath -Target $escapedSelectedPath -ErrorAction Stop
Write-Output "Created directory symbolic link: $escapedLinkPath -> $escapedSelectedPath"
}
- }
- else {
+ } else {
Write-Output "The selected path is not a folder."
}
-}
-else {
+} else {
Write-Output "No folder was selected."
}
From 52db00c66d45441105de3c656f854acdf2d5f8fb Mon Sep 17 00:00:00 2001
From: Arda Eren <70160402+DeCEll-1@users.noreply.github.com>
Date: Fri, 7 Mar 2025 19:30:17 +0300
Subject: [PATCH 05/11] Update CreateSymLinkFile.ps1
---
CreateSymLinkFile.ps1 | 48 ++++++++++---------------------------------
1 file changed, 11 insertions(+), 37 deletions(-)
diff --git a/CreateSymLinkFile.ps1 b/CreateSymLinkFile.ps1
index 798810a..e5bca9f 100644
--- a/CreateSymLinkFile.ps1
+++ b/CreateSymLinkFile.ps1
@@ -5,27 +5,10 @@ function Test-Admin {
}
function Confirm-Overwrite {
- param (
- $linkPath
- )
+ param ($linkPath)
Add-Type -AssemblyName PresentationFramework
- # Presume that it's not a folder
- $isDirectory = $false
-
- if (-not [string]::IsNullOrWhiteSpace($linkPath)) {
- # If the input box isn't empty, check if it's a valid path
- if (Test-Path $linkPath -PathType Leaf) {
- # if the path points to a file, it is not a folder
- $isDirectory = $false
- }
- elseif (Test-Path $linkPath -PathType Container) {
- # if the path points to a folder, it is a folder
- $isDirectory = $true
- }
- }
-
- $message = "A $(if ($isDirectory) { 'folder' } else { 'file' }) with the name '$(Split-Path $linkPath -Leaf)' already exists. Overwrite?"
+ $message = "A file with the name '$(Split-Path $linkPath -Leaf)' already exists. Overwrite?"
$result = [System.Windows.MessageBox]::Show(
$message,
"Confirm Overwrite",
@@ -35,10 +18,9 @@ function Confirm-Overwrite {
return $result
}
+# Function to escape wildcard characters in a path
function Escape-WildcardCharacters {
- param (
- [string]$path
- )
+ param ([string]$path)
$escapedPath = $path -replace '([*?\[\]])', '``$1'
return $escapedPath
}
@@ -67,13 +49,11 @@ function Show-FilePickerDialog {
$dialog.Filter = "All files (*.*)|*.*"
if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
return $dialog.FileName
- }
- else {
+ } else {
return $null
}
}
-# Function to escape wildcard characters in a path
# Main script
$selectedPath = Show-FilePickerDialog
@@ -94,35 +74,29 @@ if ($selectedPath) {
Write-Output "Link Path: $linkPath"
Write-Output "Escaped Link Path: $escapedLinkPath"
- # Check if selected item is a file, and then check if we already have a file with that name and offer to overwrite if we do
if (Test-Path -Path $escapedSelectedPath -PathType Leaf) {
if (Test-Path -Path $escapedLinkPath) {
- $choice = Confirm-Overwrite -linkPath $escapedLinkPath
+ $choice = Confirm-Overwrite -linkPath $linkPath
if ($choice -eq 'Yes') {
# Remove the existing symlink
Remove-Item -Path $escapedLinkPath -Force
# Create a new file symbolic link
New-Item -ItemType SymbolicLink -Path $linkPath -Target $escapedSelectedPath -ErrorAction Stop
Write-Output "Overwritten file symbolic link: $escapedLinkPath -> $escapedSelectedPath"
- }
- elseif ($choice -eq 'No') {
+ } elseif ($choice -eq 'No') {
Write-Output "Symbolic link (or file/folder with that name) already existed! Operation canceled by user by not overwriting."
- }
- else {
+ } else {
Write-Output "Operation canceled by user."
}
- }
- else {
+ } else {
# Create a new file symbolic link
New-Item -ItemType SymbolicLink -Path $linkPath -Target $escapedSelectedPath -ErrorAction Stop
Write-Output "Created file symbolic link: $escapedLinkPath -> $escapedSelectedPath"
}
- }
- else {
+ } else {
Write-Output "The selected path is not a file."
}
-}
-else {
+} else {
Write-Output "No file was selected."
}
From b87f5a148187aa8d7a149c59325a333eb03d5ee4 Mon Sep 17 00:00:00 2001
From: Arda Eren <70160402+DeCEll-1@users.noreply.github.com>
Date: Fri, 7 Mar 2025 19:38:27 +0300
Subject: [PATCH 06/11] Update CreateSymLinkFile.ps1
---
CreateSymLinkFile.ps1 | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/CreateSymLinkFile.ps1 b/CreateSymLinkFile.ps1
index e5bca9f..b60859d 100644
--- a/CreateSymLinkFile.ps1
+++ b/CreateSymLinkFile.ps1
@@ -65,24 +65,23 @@ if ($selectedPath) {
# Escape wildcard characters in the paths
$escapedLinkPath = Escape-WildcardCharacters -path $linkPath
- $escapedSelectedPath = Escape-WildcardCharacters -path $selectedPath
+ $selectedPath = Escape-WildcardCharacters -path $selectedPath
Write-Output "Original Working Directory: $originalWorkingDirectory"
Write-Output "Current Directory: $currentDir"
Write-Output "Selected Path: $selectedPath"
- Write-Output "Escaped Selected Path: $escapedSelectedPath"
Write-Output "Link Path: $linkPath"
Write-Output "Escaped Link Path: $escapedLinkPath"
- if (Test-Path -Path $escapedSelectedPath -PathType Leaf) {
+ if (Test-Path -Path $selectedPath -PathType Leaf) {
if (Test-Path -Path $escapedLinkPath) {
$choice = Confirm-Overwrite -linkPath $linkPath
if ($choice -eq 'Yes') {
# Remove the existing symlink
Remove-Item -Path $escapedLinkPath -Force
# Create a new file symbolic link
- New-Item -ItemType SymbolicLink -Path $linkPath -Target $escapedSelectedPath -ErrorAction Stop
- Write-Output "Overwritten file symbolic link: $escapedLinkPath -> $escapedSelectedPath"
+ New-Item -ItemType SymbolicLink -Path $linkPath -Target $selectedPath -ErrorAction Stop
+ Write-Output "Overwritten file symbolic link: $escapedLinkPath -> $selectedPath"
} elseif ($choice -eq 'No') {
Write-Output "Symbolic link (or file/folder with that name) already existed! Operation canceled by user by not overwriting."
} else {
@@ -90,8 +89,8 @@ if ($selectedPath) {
}
} else {
# Create a new file symbolic link
- New-Item -ItemType SymbolicLink -Path $linkPath -Target $escapedSelectedPath -ErrorAction Stop
- Write-Output "Created file symbolic link: $escapedLinkPath -> $escapedSelectedPath"
+ New-Item -ItemType SymbolicLink -Path $linkPath -Target $selectedPath -ErrorAction Stop
+ Write-Output "Created file symbolic link: $escapedLinkPath -> $selectedPath"
}
} else {
Write-Output "The selected path is not a file."
From 8d38d1631c721019db943559f3a07bb171058d2d Mon Sep 17 00:00:00 2001
From: Arda Eren <70160402+DeCEll-1@users.noreply.github.com>
Date: Fri, 7 Mar 2025 19:38:40 +0300
Subject: [PATCH 07/11] Update CreateSymLinkFolder.ps1
---
CreateSymLinkFolder.ps1 | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/CreateSymLinkFolder.ps1 b/CreateSymLinkFolder.ps1
index 5bc614d..013fd02 100644
--- a/CreateSymLinkFolder.ps1
+++ b/CreateSymLinkFolder.ps1
@@ -44,7 +44,7 @@ Set-Location -Path $originalWorkingDirectory
function Show-FolderPickerDialog {
Add-Type -AssemblyName System.Windows.Forms
$dialog = New-Object System.Windows.Forms.FolderBrowserDialog
- $dialog.Description = "Select a folder to create a symbolic link"
+ $dialog.Description = "Select a folder to create a symbolic link to"
$dialog.SelectedPath = [System.IO.Directory]::GetCurrentDirectory()
if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
return $dialog.SelectedPath
@@ -63,24 +63,23 @@ if ($selectedPath) {
# Escape wildcard characters in the paths
$escapedLinkPath = Escape-WildcardCharacters -path $linkPath
- $escapedSelectedPath = Escape-WildcardCharacters -path $selectedPath
+ $selectedPath = Escape-WildcardCharacters -path $selectedPath
Write-Output "Original Working Directory: $originalWorkingDirectory"
Write-Output "Current Directory: $currentDir"
Write-Output "Selected Path: $selectedPath"
- Write-Output "Escaped Selected Path: $escapedSelectedPath"
Write-Output "Link Path: $linkPath"
Write-Output "Escaped Link Path: $escapedLinkPath"
- if (Test-Path -Path $escapedSelectedPath -PathType Container) {
+ if (Test-Path -Path $selectedPath -PathType Container) {
if (Test-Path -Path $escapedLinkPath) {
$choice = Confirm-Overwrite -linkPath $escapedLinkPath
if ($choice -eq 'Yes') {
# Remove the existing symlink
Remove-Item -Path $escapedLinkPath -Force
# Create a new directory symbolic link
- New-Item -ItemType SymbolicLink -Path $linkPath -Target $escapedSelectedPath -ErrorAction Stop
- Write-Output "Overwritten directory symbolic link: $escapedLinkPath -> $escapedSelectedPath"
+ New-Item -ItemType SymbolicLink -Path $linkPath -Target $selectedPath -ErrorAction Stop
+ Write-Output "Overwritten directory symbolic link: $escapedLinkPath -> $selectedPath"
} elseif ($choice -eq 'No') {
Write-Output "Symbolic link (or file/folder with that name) already existed! Operation canceled by user by not overwriting."
} else {
@@ -88,8 +87,8 @@ if ($selectedPath) {
}
} else {
# Create a new directory symbolic link
- New-Item -ItemType SymbolicLink -Path $linkPath -Target $escapedSelectedPath -ErrorAction Stop
- Write-Output "Created directory symbolic link: $escapedLinkPath -> $escapedSelectedPath"
+ New-Item -ItemType SymbolicLink -Path $linkPath -Target $selectedPath -ErrorAction Stop
+ Write-Output "Created directory symbolic link: $escapedLinkPath -> $selectedPath"
}
} else {
Write-Output "The selected path is not a folder."
From 01b1a2a3b052a2baf3e822dcd169e53072365d67 Mon Sep 17 00:00:00 2001
From: Arda Eren <70160402+DeCEll-1@users.noreply.github.com>
Date: Fri, 7 Mar 2025 23:22:12 +0300
Subject: [PATCH 08/11] Update CreateSymLinkFile.ps1
---
CreateSymLinkFile.ps1 | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/CreateSymLinkFile.ps1 b/CreateSymLinkFile.ps1
index b60859d..24cb060 100644
--- a/CreateSymLinkFile.ps1
+++ b/CreateSymLinkFile.ps1
@@ -27,13 +27,13 @@ function Escape-WildcardCharacters {
# Save the initial working directory
$initialWorkingDirectory = [System.IO.Directory]::GetCurrentDirectory()
-$escapedInitialWorkingDirectory = Escape-WildcardCharacters -path $initialWorkingDirectory
+$initialWorkingDirectory = Escape-WildcardCharacters -path $initialWorkingDirectory
if (-not (Test-Admin)) {
Write-Output "Please run this script as an administrator. Let's try rerunning automatically..."
# Re-run the script with elevated privileges, passing the initial working directory as an argument
- Start-Process -FilePath "powershell.exe" -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" `"$escapedInitialWorkingDirectory`"" -Verb RunAs
+ Start-Process -FilePath "powershell.exe" -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" `"$initialWorkingDirectory`"" -Verb RunAs
Exit # Exit the non-elevated instance
}
From 1ddb19521c915727148e3e58bdbba71f36112af6 Mon Sep 17 00:00:00 2001
From: Arda Eren <70160402+DeCEll-1@users.noreply.github.com>
Date: Fri, 7 Mar 2025 23:22:20 +0300
Subject: [PATCH 09/11] Update CreateSymLinkFolder.ps1
---
CreateSymLinkFolder.ps1 | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/CreateSymLinkFolder.ps1 b/CreateSymLinkFolder.ps1
index 013fd02..58e278d 100644
--- a/CreateSymLinkFolder.ps1
+++ b/CreateSymLinkFolder.ps1
@@ -26,13 +26,13 @@ function Escape-WildcardCharacters {
# Save the initial working directory
$initialWorkingDirectory = [System.IO.Directory]::GetCurrentDirectory()
-$escapedInitialWorkingDirectory = Escape-WildcardCharacters -path $initialWorkingDirectory
+$initialWorkingDirectory = Escape-WildcardCharacters -path $initialWorkingDirectory
if (-not (Test-Admin)) {
Write-Output "Please run this script as an administrator. Let's try rerunning automatically..."
# Re-run the script with elevated privileges, passing the initial working directory as an argument
- Start-Process -FilePath "powershell.exe" -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" `"$escapedInitialWorkingDirectory`"" -Verb RunAs
+ Start-Process -FilePath "powershell.exe" -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" `"$initialWorkingDirectory`"" -Verb RunAs
Exit # Exit the non-elevated instance
}
From 899b96a777d7dc063acd27fe0a93b0085eb251c8 Mon Sep 17 00:00:00 2001
From: Arda Eren <70160402+DeCEll-1@users.noreply.github.com>
Date: Fri, 7 Mar 2025 23:31:47 +0300
Subject: [PATCH 10/11] Update CreateSymLinkFile.ps1
---
CreateSymLinkFile.ps1 | 1 -
1 file changed, 1 deletion(-)
diff --git a/CreateSymLinkFile.ps1 b/CreateSymLinkFile.ps1
index 24cb060..dfb54bd 100644
--- a/CreateSymLinkFile.ps1
+++ b/CreateSymLinkFile.ps1
@@ -54,7 +54,6 @@ function Show-FilePickerDialog {
}
}
-
# Main script
$selectedPath = Show-FilePickerDialog
From 30c692f6ca55068eefba5d07f82cdcff9bb8fd44 Mon Sep 17 00:00:00 2001
From: Arda Eren
Date: Sat, 17 May 2025 11:50:41 +0300
Subject: [PATCH 11/11] d
---
CreateSymLink.reg | Bin 2378 -> 2138 bytes
CreateSymLinkFile.ps1 | 8 ++--
CreateSymLinkFolder.ps1 | 104 +++++++++++++++++++++++++++++++++-------
3 files changed, 92 insertions(+), 20 deletions(-)
diff --git a/CreateSymLink.reg b/CreateSymLink.reg
index 5ec920383de57917ae484e8c77504a52359a1ca8..41caba57c8a757da089028988435f0fc281438a9 100644
GIT binary patch
delta 89
zcmX>lbW32vB4%M11}labC@f+~Wk_czp4`Z$yjg?g8zVN!&5dk|OxPrVx>P4?aVh`+
D+v^m^
delta 329
zcmca5a7t*yBIe{^1}labDD-CtVF+MwWN=|nV2A?J3Jk$OkuV@Dh`|%C%9$Y)Ebhf`bu@O
H6^8-<6-_yU
diff --git a/CreateSymLinkFile.ps1 b/CreateSymLinkFile.ps1
index dfb54bd..dfc2b30 100644
--- a/CreateSymLinkFile.ps1
+++ b/CreateSymLinkFile.ps1
@@ -26,8 +26,8 @@ function Escape-WildcardCharacters {
}
# Save the initial working directory
-$initialWorkingDirectory = [System.IO.Directory]::GetCurrentDirectory()
-$initialWorkingDirectory = Escape-WildcardCharacters -path $initialWorkingDirectory
+# $initialWorkingDirectory = [System.IO.Directory]::GetCurrentDirectory()
+$initialWorkingDirectory = (Get-Location).Path
if (-not (Test-Admin)) {
Write-Output "Please run this script as an administrator. Let's try rerunning automatically..."
@@ -36,6 +36,7 @@ if (-not (Test-Admin)) {
Start-Process -FilePath "powershell.exe" -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" `"$initialWorkingDirectory`"" -Verb RunAs
Exit # Exit the non-elevated instance
}
+$initialWorkingDirectory = Escape-WildcardCharacters -path $initialWorkingDirectory
# Retrieve the working directory from arguments
$originalWorkingDirectory = $args[0]
@@ -66,6 +67,7 @@ if ($selectedPath) {
$escapedLinkPath = Escape-WildcardCharacters -path $linkPath
$selectedPath = Escape-WildcardCharacters -path $selectedPath
+ Write-Output "Initial Working Directory: $initialWorkingDirectory"
Write-Output "Original Working Directory: $originalWorkingDirectory"
Write-Output "Current Directory: $currentDir"
Write-Output "Selected Path: $selectedPath"
@@ -101,4 +103,4 @@ if ($selectedPath) {
# Keep the window open
#Read-Host -Prompt "Press Enter to exit"
Write-Output "`n`nThis window will autoclose soon"
-Start-Sleep -Seconds 1
+Start-Sleep -Seconds 1
\ No newline at end of file
diff --git a/CreateSymLinkFolder.ps1 b/CreateSymLinkFolder.ps1
index 58e278d..f1b1078 100644
--- a/CreateSymLinkFolder.ps1
+++ b/CreateSymLinkFolder.ps1
@@ -1,3 +1,53 @@
+$source = @'
+using System;
+using System.Reflection;
+using System.Windows.Forms;
+public class MyFolderSelector
+{
+ public string DefaultPath, Title, Message;
+ public MyFolderSelector(string defaultPath = "MyComputer", string title = "Select a folder", string message = "")
+ {
+ DefaultPath = defaultPath;
+ Title = title;
+ Message = message;
+ }
+ public string GetPath()
+ {
+ // filter for which methods we want to get
+ BindingFlags c_flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
+ // get the assembly of the file dialog so we can access its internal types
+ var fileDialogAssembly = typeof(FileDialog).Assembly;
+ // get the iFile so we can use its functions to put our settings and show our dialog
+ var iFileDialog = fileDialogAssembly.GetType("System.Windows.Forms.FileDialogNative+IFileDialog");
+ var openFileDialog = new OpenFileDialog
+ { // our dialog options
+ AddExtension = false,
+ CheckFileExists = false,
+ DereferenceLinks = true,
+ Filter = "Folders|\n",
+ InitialDirectory = DefaultPath,
+ Multiselect = false,
+ Title = Title
+ };
+ // create vista dialog
+ var ourDialog = (typeof(OpenFileDialog).GetMethod("CreateVistaDialog", c_flags)).Invoke(openFileDialog, new object[] { });
+ // attatch our options
+ typeof(OpenFileDialog).GetMethod("OnBeforeVistaDialog", c_flags).Invoke(openFileDialog, new[] { ourDialog });
+ iFileDialog.GetMethod("SetOptions", c_flags).Invoke(ourDialog, new object[] { (uint)(0x20000840 | 0x00000020 /*defaultOptions | folderPickerOption*/) });
+ // generate update event constructor so the file name updates after selection
+ var vistaDialogEventsConstructorInfo = fileDialogAssembly
+ .GetType("System.Windows.Forms.FileDialog+VistaDialogEvents")
+ .GetConstructor(c_flags, null, new[] { typeof(FileDialog) }, null);
+ var adviseParametersWithOutputConnectionToken = new[] { vistaDialogEventsConstructorInfo.Invoke(new object[] { openFileDialog }), 0U };
+ // add the event to the dialog
+ iFileDialog.GetMethod("Advise").Invoke(ourDialog, adviseParametersWithOutputConnectionToken);
+ // show the dialog to user and get response
+ int retVal = (int)iFileDialog.GetMethod("Show").Invoke(ourDialog, new object[] { IntPtr.Zero });
+ // returns the file name if the user made a selection
+ return retVal == 0 ? openFileDialog.FileName : "";
+ }
+}
+'@
# Function to check for elevated privileges
function Test-Admin {
$currentUser = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
@@ -8,7 +58,21 @@ function Confirm-Overwrite {
param ($linkPath)
Add-Type -AssemblyName PresentationFramework
- $message = "A folder with the name '$(Split-Path $linkPath -Leaf)' already exists. Overwrite?"
+ # Presume that it's not a folder
+ $isDirectory = $false
+
+ if (-not [string]::IsNullOrWhiteSpace($linkPath)) {
+ # If the input box isn't empty, check if it's a valid path
+ if (Test-Path $linkPath -PathType Leaf) {
+ # if the path points to a file, it is not a folder
+ $isDirectory = $false
+ } elseif (Test-Path $linkPath -PathType Container) {
+ # if the path points to a folder, it is a folder
+ $isDirectory = $true
+ }
+ }
+
+ $message = "A $(if ($isDirectory) { 'folder' } else { 'file' }) with the name '$(Split-Path $linkPath -Leaf)' already exists. Overwrite?"
$result = [System.Windows.MessageBox]::Show(
$message,
"Confirm Overwrite",
@@ -26,13 +90,13 @@ function Escape-WildcardCharacters {
# Save the initial working directory
$initialWorkingDirectory = [System.IO.Directory]::GetCurrentDirectory()
-$initialWorkingDirectory = Escape-WildcardCharacters -path $initialWorkingDirectory
+$escapedInitialWorkingDirectory = Escape-WildcardCharacters -path $initialWorkingDirectory
if (-not (Test-Admin)) {
Write-Output "Please run this script as an administrator. Let's try rerunning automatically..."
# Re-run the script with elevated privileges, passing the initial working directory as an argument
- Start-Process -FilePath "powershell.exe" -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" `"$initialWorkingDirectory`"" -Verb RunAs
+ Start-Process -FilePath "powershell.exe" -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" `"$escapedInitialWorkingDirectory`"" -Verb RunAs
Exit # Exit the non-elevated instance
}
@@ -42,14 +106,19 @@ Set-Location -Path $originalWorkingDirectory
# Function to show folder picker dialog
function Show-FolderPickerDialog {
- Add-Type -AssemblyName System.Windows.Forms
- $dialog = New-Object System.Windows.Forms.FolderBrowserDialog
- $dialog.Description = "Select a folder to create a symbolic link to"
- $dialog.SelectedPath = [System.IO.Directory]::GetCurrentDirectory()
- if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
- return $dialog.SelectedPath
- } else {
+
+ Add-Type -Language CSharp -TypeDefinition $source -ReferencedAssemblies ("System.Windows.Forms")
+
+ $path = $originalWorkingDirectory
+ $title = "Select Folder"
+ $description = "Select a folder to create a symbolic link"
+
+ $out = [MyFolderSelector]::new($path, $title, $description).GetPath()
+
+ if ($out -eq "") {
return $null
+ } else {
+ return $out
}
}
@@ -63,23 +132,24 @@ if ($selectedPath) {
# Escape wildcard characters in the paths
$escapedLinkPath = Escape-WildcardCharacters -path $linkPath
- $selectedPath = Escape-WildcardCharacters -path $selectedPath
+ $escapedSelectedPath = Escape-WildcardCharacters -path $selectedPath
Write-Output "Original Working Directory: $originalWorkingDirectory"
Write-Output "Current Directory: $currentDir"
Write-Output "Selected Path: $selectedPath"
+ Write-Output "Escaped Selected Path: $escapedSelectedPath"
Write-Output "Link Path: $linkPath"
Write-Output "Escaped Link Path: $escapedLinkPath"
- if (Test-Path -Path $selectedPath -PathType Container) {
+ if (Test-Path -Path $escapedSelectedPath -PathType Container) {
if (Test-Path -Path $escapedLinkPath) {
$choice = Confirm-Overwrite -linkPath $escapedLinkPath
if ($choice -eq 'Yes') {
# Remove the existing symlink
Remove-Item -Path $escapedLinkPath -Force
# Create a new directory symbolic link
- New-Item -ItemType SymbolicLink -Path $linkPath -Target $selectedPath -ErrorAction Stop
- Write-Output "Overwritten directory symbolic link: $escapedLinkPath -> $selectedPath"
+ New-Item -ItemType SymbolicLink -Path $linkPath -Target $escapedSelectedPath -ErrorAction Stop
+ Write-Output "Overwritten directory symbolic link: $escapedLinkPath -> $escapedSelectedPath"
} elseif ($choice -eq 'No') {
Write-Output "Symbolic link (or file/folder with that name) already existed! Operation canceled by user by not overwriting."
} else {
@@ -87,8 +157,8 @@ if ($selectedPath) {
}
} else {
# Create a new directory symbolic link
- New-Item -ItemType SymbolicLink -Path $linkPath -Target $selectedPath -ErrorAction Stop
- Write-Output "Created directory symbolic link: $escapedLinkPath -> $selectedPath"
+ New-Item -ItemType SymbolicLink -Path $linkPath -Target $escapedSelectedPath -ErrorAction Stop
+ Write-Output "Created directory symbolic link: $escapedLinkPath -> $escapedSelectedPath"
}
} else {
Write-Output "The selected path is not a folder."
@@ -100,4 +170,4 @@ if ($selectedPath) {
# Keep the window open
#Read-Host -Prompt "Press Enter to exit"
Write-Output "`n`nThis window will autoclose soon"
-Start-Sleep -Seconds 1
+Start-Sleep -Seconds 1
\ No newline at end of file