Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

How to create symlink using Perl?

by reddevil (Initiate)
on Oct 23, 2011 at 08:32 UTC ( [id://933175] : perlquestion . print w/replies, xml ) Need Help??

reddevil has asked for the wisdom of the Perl Monks concerning the following question:

Am trying to run the below code in Perl:  symlink($oldname,$newname) or die print "$!\n"; but I get an error saying:  The symlink function is unimplemented at C:\...\ line 14. If I change the code to:  link($oldname,$newname) or die print "$!\n"; then the hard links are being created without errors.

Using activestate Perl and Windows 7 32-bit. Any ideas why this is happening? I am trying to create symbolic links for a file.

P.S: I am a total newbie to Perl.

Replies are listed 'Best First'.
Re: How to create symlink using Perl?
by eyepopslikeamosquito (Archbishop) on Oct 23, 2011 at 09:02 UTC

    Windows NTFS supports Junctions which are very similar to Unix symlinks (see also Sysinternals Junction).

    I've successfully used the CPAN Win32::Symlink module (in particular, it's symlink function) to write cross-platform code that used "symlinks" on both Unix and Windows. At the top of the program, I used:

    BEGIN { if ($^O eq 'MSWin32') { require Win32::Symlink; Win32::Symlink->import(); } }
    The rest of the code (using the symlink function) was the same for both platforms.

      By the way, that can be written as
      use if $^O eq 'MSWin32', 'Win32::Symlink';

        This module is reported to be broken in current versions of activestate perl:

        Am using activestate Perl version and windows 7 32bit with NTFS. How to shell out to mklink?

      Junctions are symbolic links to directories, not to files. I cannot get Win32::Symlink::symlink to create a symbolic link to a file. It also seems to work only for directories, although I can't find any documentation of this limitation.

Re: How to create symlink using Perl?
by Corion (Patriarch) on Oct 23, 2011 at 08:45 UTC

    What part of

    The symlink function is unimplemented

    do you have problem with?

    Symbolic links are not supported by Perl on Windows, because historically, symlinks were not supported by the operating system itself.

    NTFS Symbolic Link claims that there is some kind of support, if you are certain that the file system is NTFS and the operating system is Windows Vista or later. I would then just shell out to the mklink program mentioned.

Re: How to create symlink using Perl?
by Khen1950fx (Canon) on Oct 23, 2011 at 12:30 UTC
    You could use the GnuWin32 version of ln in CoreUtils.
Re: How to create symlink using Perl?
by bart (Canon) on Oct 23, 2011 at 16:20 UTC
    Windows doesn't (really) support symbolic links. The closest you get to them, is the *.lnk files, also known as shortcuts.

    To create a shortcut, you can use the Win32::Shortcut module. It might be coming with ActivePerl, but otherwise yo ucan use PPM to install it.

      Windows has supported symbolic links on NTFS volumes since Windows 2000. The problem is certain Perl developers who are determined to do to Windows what GOP states did to the ACA. They don't care how many users are hurt in the process, as long as they can put Windows down. That is also why there is no Perl support for Unicode filenames in Windows. See for an example of a Perl devoper's attitude toward Windows.

        See for an example of a Perl devoper's attitude toward Windows.

        I see neither any "attitude" towards Windows nor any indication that "Assaf Gordon" is or was a Perl developer...?

Re: How to create symlink using Perl?
by freonpsandoz (Beadle) on Oct 09, 2016 at 22:40 UTC

    Here is my solution after failing to get any of the existing symlink modules or functions to work. It works for Unicode paths as long as they don't exceed 260 characters.

    package MyUtils::SymLink; use strict; use warnings; require Encode; require Win32::API; use constant CSLW_PROTO => "DWORD CreateSymbolicLinkW(PWSTR link, PWST +R path, DWORD opt)"; my $utf16enc = Encode::find_encoding("utf16-le") or die("Couldn't load + utf16 encoder\n"); my $createsymlink = Win32::API->new("kernel32", CSLW_PROTO) or die("Co +uldn't load CreateSymbolicLinkW"); use Exporter qw(import); our @EXPORT_OK = qw(CreateSymLinkW); sub CreateSymLinkW { my ($symlinkpath, $filepath) = @_; my $symlinkpathW = $utf16enc->encode($symlinkpath) . "\x00"; my $filepathW = $utf16enc->encode($filepath) . "\x00"; return $createsymlink->Call($symlinkpathW, $filepathW, 0); } 1;