Create symlink without admin mode
Posted: 07 May 2025 05:22
Is there any way to create a symlink without having XY run as administrator?
Forum for XYplorer Users and Developers
https://www.xyplorer.com/xyfc2/
Thanks, I realised that when I tried to create a symlink using command prompt and found it had to be run as administrator. So, is it possible to use XY to create a script that can run the command prompt as administrator and execute mklink code?
Without knowing any context on this question, one answer might be: "By using the Link Shell Extension"
Code: Select all
$batFile = "%TEMP%\~xyplorer_mklink.bat";
$batContent = <<<>>>
@ECHO OFF
REG QUERY "HKU\S-1-5-19" >NUL 2>NUL && GOTO :ENDUAC
SET "vbsFile=%TEMP%\~getAdmin.vbs"
IF "%1" NEQ "" (FOR /F "tokens=*" %%I IN ('ECHO %*') DO SET "param=%%~I")
ECHO Set UAC = CreateObject^("Shell.Application"^)> "%vbsFile%"
ECHO UAC.ShellExecute "cmd", "/c """"%~s0"" ""%param%""""", "", "runas", ^1>> "%vbsFile%"
CSCRIPT "%vbsFile%" //Nologo
IF EXIST "%vbsFile%" DEL /Q "%vbsFile%" >NUL 2>NUL
EXIT /B
:ENDUAC
>>>;
$batContent .= <crlf 2> . "your mklink stuff here...";
writefile($batFile, $batContent, , "utf8");
run $batFile, "%TEMP%", 0, 1;
This is exactly the context I needed.
Yes it was for the latter. My apologies for not being clear about that.noembryo wrote: ↑09 May 2025 18:04 This is exactly the context I needed.
Do you want to create a symlink, or you want to create a symlink by scripting?
My answer was for the former (it's the way I create symlinks in XYplorer without having administrator rights), but unfortunately you wanted an answer for the latter..
Thankshighend wrote: ↑09 May 2025 11:01 Write out a .bat script (and run it afterwards) that self-elevates and executes the mklink command?
Code: Select all
$batFile = "%TEMP%\~xyplorer_mklink.bat"; $batContent = <<<>>> @ECHO OFF REG QUERY "HKU\S-1-5-19" >NUL 2>NUL && GOTO :ENDUAC SET "vbsFile=%TEMP%\~getAdmin.vbs" IF "%1" NEQ "" (FOR /F "tokens=*" %%I IN ('ECHO %*') DO SET "param=%%~I") ECHO Set UAC = CreateObject^("Shell.Application"^)> "%vbsFile%" ECHO UAC.ShellExecute "cmd", "/c """"%~s0"" ""%param%""""", "", "runas", ^1>> "%vbsFile%" CSCRIPT "%vbsFile%" //Nologo IF EXIST "%vbsFile%" DEL /Q "%vbsFile%" >NUL 2>NUL EXIT /B :ENDUAC >>>; $batContent .= <crlf 2> . "your mklink stuff here..."; writefile($batFile, $batContent, , "utf8"); run $batFile, "%TEMP%", 0, 1;
Thanks @highend, you saved me a lot of head scratching as I'm getting into symlinks
mklink appropriately.Code: Select all
// Generate symlinks for each File/Folder currently selected.
// Elevates cmd to admin
$outputPrefix = 'link-';
// ================================ CODE ================================
$batFile = "<xydata>\Temp\symlinkGenerator.bat";
$batContents = <<<STRING
@ECHO OFF
REG QUERY "HKU\S-1-5-19" >NUL 2>NUL && GOTO :ENDUAC
SET "vbsFile=<xydata>\Temp\~getAdmin.vbs"
IF "%1" NEQ "" (FOR /F "tokens=*" %%I IN ('ECHO %*') DO SET "param=%%~I")
ECHO Set UAC = CreateObject^("Shell.Application"^)> "%vbsFile%"
ECHO UAC.ShellExecute "cmd", "/c """"%~s0"" ""%param%""""", "", "runas", ^1>> "%vbsFile%"
CSCRIPT "%vbsFile%" //Nologo
IF EXIST "%vbsFile%" DEL /Q "%vbsFile%" >NUL 2>NUL
EXIT /B
:ENDUAC
STRING;
foreach($item, <selitems :::>, ':::') {
// Format 'mklink' depending on $item type (file|folder)
$itemDirectory = getpathcomponent($item, 'path');
$itemFilename = getpathcomponent($item, 'name');
if (exists($item) == '1') {
// $item is file
$command = lax(mklink "$itemDirectory\$outputPrefix$itemFilename" "$item");
$batContents .= <crlf> . $command;
} elseif (exists($item) == '2') {
// $item is folder
$command = lax(mklink /D "$itemDirectory\$outputPrefix$itemFilename" "$item");
$batContents .= <crlf> . $command;
}
}
writefile($batFile, $batContents, , "utf8");
run($batFile, , 0, 0);
Thanks for that but am I missing something? Do I need to do anything other than select a folder and run the script? I tried that and the symlink wasn't created. The bat file created by the script seems to have the correct information.WirlyWirly wrote: ↑20 May 2025 23:50 I took highend's script and adjusted it slightly so that it will generate a symlink for every currently selected item. There's enough logic to differentiate between file/folder and formatmklinkappropriately.
Code: Select all
// Generate symlinks for each File/Folder currently selected. // Elevates cmd to admin $outputPrefix = 'link-'; // ================================ CODE ================================ $batFile = "<xydata>\Temp\symlinkGenerator.bat"; $batContents = <<<STRING @ECHO OFF REG QUERY "HKU\S-1-5-19" >NUL 2>NUL && GOTO :ENDUAC SET "vbsFile=<xydata>\Temp\~getAdmin.vbs" IF "%1" NEQ "" (FOR /F "tokens=*" %%I IN ('ECHO %*') DO SET "param=%%~I") ECHO Set UAC = CreateObject^("Shell.Application"^)> "%vbsFile%" ECHO UAC.ShellExecute "cmd", "/c """"%~s0"" ""%param%""""", "", "runas", ^1>> "%vbsFile%" CSCRIPT "%vbsFile%" //Nologo IF EXIST "%vbsFile%" DEL /Q "%vbsFile%" >NUL 2>NUL EXIT /B :ENDUAC STRING; foreach($item, <selitems :::>, ':::') { // Format 'mklink' depending on $item type (file|folder) $itemDirectory = getpathcomponent($item, 'path'); $itemFilename = getpathcomponent($item, 'name'); if (exists($item) == '1') { // $item is file $command = lax(mklink "$itemDirectory\$outputPrefix$itemFilename" "$item"); $batContents .= <crlf> . $command; } elseif (exists($item) == '2') { // $item is folder $command = lax(mklink /D "$itemDirectory\$outputPrefix$itemFilename" "$item"); $batContents .= <crlf> . $command; } } writefile($batFile, $batContents, , "utf8"); run($batFile, , 0, 0);
Code: Select all
e|open """<xy>"" /fresh /win=min /script=|::". report('new("link-{Name}", "symlink", "{Fullname}"); ', 1) ."exit n;| ""<curpath>""", e;