Sign in to follow this  
Followers 0
RulerOf

_SymLink(), for creating Symbolic Links in AutoIt

13 posts in this topic

Hello Folks,

Posting just to share ;)

I was wracking my brain yesterday trying to figure out why my script to generate a Symlink wouldn't work, and among other things, invoking @Comspec wasn't helping things any! A little googling and I stumbled across the method to create them programatically using the Windows API, which works pretty well.

Here's the function if anyone would like to use it!

;=======================================================================================
; Function Name:    _SymLink
; Description:      Creates an NTFS Symbolic Link at the specified location
;                   to another specified location.
;
; Parameter(s):     $qLink              = The file or directory you want to create.
;                   $qTarget            = The location $qLink should link to.
;                   $qIsDirectoryLink   = 0 for a FILE symlink (default).
;                                         1 for a DIRECTORY symlink.
;
; Syntax:           _SymLink( $qLink, $qTarget, [$qIsDirectoryLink = 0] )
;
; Return Value(s):  On Success: Returns the path to the created SymLink.
;                   
;                   On Failure: 0 and set @Error:
;                               
;                               1 = DLLCall failed, @extended for more info                                     
;                               2 = $qLink already exists!
;
; Notes:            To remove a Symbolic link, just delete it as you would any
;                   file or directory.
;
; Author(s):        Andrew Bobulsky (RulerOf@{Google's-infamous-mail-service}.com)
;
; Other info:       http://www.informit.com/guides/content.aspx?g=dotnet&seqNum=762
; MSDN:             http://msdn.microsoft.com/en-us/library/aa363866(VS.85).aspx
;=======================================================================================
Func _SymLink( $qLink, $qTarget, $qIsDirectoryLink = 0 )

    If FileExists($qLink) Then
        SetError(2)
        Return 0
    EndIf

    DllCall("kernel32.dll", "BOOLEAN", "CreateSymbolicLink", "str", $qLink, "str", $qTarget, "DWORD", Hex($qIsDirectoryLink))
    If @error Then
        SetError(1, @extended, 0)
        Return
    EndIf

    Return $qLink

EndFunc

Enjoy! =)

-RulerOf

Share this post


Link to post
Share on other sites



Oh good lord this is obnoxious... NT AUTHORITY\SYSTEM doesn't have the privilege to create Symlinks.

I wanna shoot myself right now ;)

At least the code works :)

Share this post


Link to post
Share on other sites

Nice ;), but seems restricted to Vista+ ;)...

Yessir. Symlinks are only supported on NT6+

You could junction or hard link them, but I wasn't interested in those because I need to symlink a network folder :)

Share this post


Link to post
Share on other sites

Oh good lord this is obnoxious... NT AUTHORITY\SYSTEM doesn't have the privilege to create Symlinks.

I wanna shoot myself right now ;)

At least the code works :)

Wow. It gets even more obnoxious than I thought.

There's a policy setting in Windows to allow the creation of Symlinks by non-admin users, specifically the "SeCreateSymbolicLinkPrivilege" privilege. Every single attempt I've made to modify the privilege both through local/group policy, and using the security.au3 UDF, turns back successful but it doesn't f***ing do anything!

Turns out that this is an issue with Windows that's apparently never been fixed, but I don't know how deep this bug goes. I'm whipping out some C++ today (groan) to see if I can dig at this privilege and get the damn thing working.... I just find it extremely stupid that I can't create symlinks programmatically with the SYSTEM account.

FWIW, I'm digging into this (and I've wasted DAYS of work on this, thanks Microsoft!) because Symlinking is the only method I've been able to come up with (and if I had known about this, I would have tried anything else) to address a compatibility issue with a line of business app (hell, for my company it is the line of business app). If I'm successful, I'll post any methods/code/whatever that I come up with here, as well as other places. We'll see where this goes I suppose.

Share this post


Link to post
Share on other sites

I'll assume you're using a service if you need to do this from the SYSTEM account. Maybe you'd be better off working on getting your app to run mklink or Sysinternal's junction utility as another admin account which would have those rights.

Share this post


Link to post
Share on other sites

I'll assume you're using a service if you need to do this from the SYSTEM account. Maybe you'd be better off working on getting your app to run mklink or Sysinternal's junction utility as another admin account which would have those rights.

No, Group Policy startup scripts. Startup scripts run in the SYSTEM context and are transparent (and oh so easy to implement :)), and usually give me a secure method for running administrative tasks that are local to a given machine.

I wrapped the AutoIt3 executable and includes into an MSI with WIX such that admins and SYSTEM are allowed to run scripts and deployed that through group policy. That way I can stuff an .au3 file into the policies I'm using to get work done rather than using compiled scripts or resorting to javascript/vbs/whatever inferior language ;)

Share this post


Link to post
Share on other sites

Are you able to do any sort of impersonation or RunAs with your AutoIt script? If you can RunAs the mklink or junction utilities as a local admin, you should be able to create your symlinks without issues.

Share this post


Link to post
Share on other sites

Or take a look at my service script here - http://www.autoitscript.com/forum/index.php?showtopic=104735

and extract and use the relevant impersonation tidbits. IIRC though, you'll have to have a local admin currently logged on to use user impersonation.

Share this post


Link to post
Share on other sites

Are you able to do any sort of impersonation or RunAs with your AutoIt script? If you can RunAs the mklink or junction utilities as a local admin, you should be able to create your symlinks without issues.

Clever idea, and while I could do that, the local administrator accounts are disabled. As an aside though, I'm not a fan of embedding passwords :)

I appreciate the thought though! ;)

Share this post


Link to post
Share on other sites

Or take a look at my service script here - http://www.autoitscript.com/forum/index.php?showtopic=104735

and extract and use the relevant impersonation tidbits. IIRC though, you'll have to have a local admin currently logged on to use user impersonation.

Oh hot damn that is one sexy script!

Won't work here cause our users aren't admins... then again my biggest problem there is that SYSTEM doesn't have the symlink creation privilege, so it likely wouldn't work anyway. If you want to test for yourself, try calling mklink from a SYSTEM cmd prompt. It's kinda stupid.

Share this post


Link to post
Share on other sites

Many thanks for the function.

It work like a charm.

Share this post


Link to post
Share on other sites

Just what I was looking for.

Works great under 7.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0