admin管理员组

文章数量:1122832

I am very new to using Visual Studio 2022 Community and coding in C# and trying to develop a Windows Form Application to mount and unmount symlinks based on their status of being mounted\unmounted. I have added the "System.IO" namespace. What I am trying to do would look like this in batch:

    set dest=\\path\to\share\pub
    set dest="%dest%"
    for %%i in (%dest%) do (set "fold=%%~ni")
    if exist "c:\VOLUMES\%fold%" (goto:unmount) else (goto:mount)
    
    :unmount
    RD "c:\VOLUMES\%fold%"
    net use %dest% /delete
    pause
    goto:eof 

    :mount
    if not exist "C:\Volumes" MD "C:\Volumes"
    mklink /d "c:\VOLUMES\%fold%" "%dest%"
    net use %dest%
    pause
    goto:eof

So far, I've not got much. When trying to isolate the folder name I run into issues

private void ChangeLinkListBox(object sender, EventArgs e)
{
    //Take path as string works
    SymLinkSelect.Text = SymLinkList.SelectedItem.ToString();
    //Only take final folder as string
    //SymLinkFolder.Text = SymLinkList.SelectedItem.Path();
    //SymLinkFolder.Text = SymLinkList.SelectedItem.ToPath();
    //SymLinkFolder.Text = SymLinkList.SelectedItem.ToString();
    //SymLinkFolder.Text = new DirectoryInfo(SymLinkList.SelectedItem.ToString()).Name;
}

A lot of what I find online is about creating symboliclinks for visual studio to reference from as a program rather making them from within the program. I've made a button that ideally would mount/unmount the path selected in the list of paths

private void MountShare(object sender, EventArgs e)
//Mount/Unmount symlinks here button change, check for mounts? 
{
    if (btnPos == false)
    {
        if (SymLinkSelect.Text.Length > 0)
        {
            btnPos = true;
            //mounting script in here
            //DoProcess("Net") - does not exist in the current context
            //pass string to batch file? 
            btnMount.Text = "Unmount";
        }
        else
        {
            MessageBox.Show("Select a Link to Mount please", "SymLink Says: ");
        }
    }
    else
    {
        btnMount.Text = "Mount";
        //unmounting script in here
        btnPos = false;
    }
}

I did find this but every time I try to incorporate it into my code it breaks everything, even just adding [DllImport("kernel32.dll")] in the public partial class Form1 : Form section breaks it.

namespace ConsoleApplication
{
    class Program
    {
        [DllImport("kernel32.dll")]
        static extern bool CreateSymbolicLink(string lpSymlinkFileName, string lpTargetFileName, SymbolicLink dwFlags);

        enum SymbolicLink
        {
            File = 0,
            Directory = 1
        }

        static void Main(string[] args)
        {
            string symbolicLink = @"c:\bar.txt";
            string fileName = @"c:\temp\foo.txt";

            using (var writer = File.CreateText(fileName))
            {
                writer.WriteLine("Hello World");
            }

            CreateSymbolicLink(symbolicLink, fileName, SymbolicLink.File);
        }
    }
}

I know I have bitten off more than I can handle so I apologize for not knowing what really to ask for or how to ask but I feel like it could be good to learn this way. This is what the app looks like currently in case that helps with anything

Thank you for any assistance and sorry for all the questions.
Rory

I am very new to using Visual Studio 2022 Community and coding in C# and trying to develop a Windows Form Application to mount and unmount symlinks based on their status of being mounted\unmounted. I have added the "System.IO" namespace. What I am trying to do would look like this in batch:

    set dest=\\path\to\share\pub
    set dest="%dest%"
    for %%i in (%dest%) do (set "fold=%%~ni")
    if exist "c:\VOLUMES\%fold%" (goto:unmount) else (goto:mount)
    
    :unmount
    RD "c:\VOLUMES\%fold%"
    net use %dest% /delete
    pause
    goto:eof 

    :mount
    if not exist "C:\Volumes" MD "C:\Volumes"
    mklink /d "c:\VOLUMES\%fold%" "%dest%"
    net use %dest%
    pause
    goto:eof

So far, I've not got much. When trying to isolate the folder name I run into issues

private void ChangeLinkListBox(object sender, EventArgs e)
{
    //Take path as string works
    SymLinkSelect.Text = SymLinkList.SelectedItem.ToString();
    //Only take final folder as string
    //SymLinkFolder.Text = SymLinkList.SelectedItem.Path();
    //SymLinkFolder.Text = SymLinkList.SelectedItem.ToPath();
    //SymLinkFolder.Text = SymLinkList.SelectedItem.ToString();
    //SymLinkFolder.Text = new DirectoryInfo(SymLinkList.SelectedItem.ToString()).Name;
}

A lot of what I find online is about creating symboliclinks for visual studio to reference from as a program rather making them from within the program. I've made a button that ideally would mount/unmount the path selected in the list of paths

private void MountShare(object sender, EventArgs e)
//Mount/Unmount symlinks here button change, check for mounts? 
{
    if (btnPos == false)
    {
        if (SymLinkSelect.Text.Length > 0)
        {
            btnPos = true;
            //mounting script in here
            //DoProcess("Net") - does not exist in the current context
            //pass string to batch file? 
            btnMount.Text = "Unmount";
        }
        else
        {
            MessageBox.Show("Select a Link to Mount please", "SymLink Says: ");
        }
    }
    else
    {
        btnMount.Text = "Mount";
        //unmounting script in here
        btnPos = false;
    }
}

I did find this but every time I try to incorporate it into my code it breaks everything, even just adding [DllImport("kernel32.dll")] in the public partial class Form1 : Form section breaks it.

namespace ConsoleApplication
{
    class Program
    {
        [DllImport("kernel32.dll")]
        static extern bool CreateSymbolicLink(string lpSymlinkFileName, string lpTargetFileName, SymbolicLink dwFlags);

        enum SymbolicLink
        {
            File = 0,
            Directory = 1
        }

        static void Main(string[] args)
        {
            string symbolicLink = @"c:\bar.txt";
            string fileName = @"c:\temp\foo.txt";

            using (var writer = File.CreateText(fileName))
            {
                writer.WriteLine("Hello World");
            }

            CreateSymbolicLink(symbolicLink, fileName, SymbolicLink.File);
        }
    }
}

I know I have bitten off more than I can handle so I apologize for not knowing what really to ask for or how to ask but I feel like it could be good to learn this way. This is what the app looks like currently in case that helps with anything

Thank you for any assistance and sorry for all the questions.
Rory

Share Improve this question edited Nov 22, 2024 at 17:06 Klaus Gütter 11.9k7 gold badges33 silver badges42 bronze badges asked Nov 22, 2024 at 13:30 roarroar 537 bronze badges 7
  • How does it break everything? – shingo Commented Nov 22, 2024 at 14:01
  • Thanks for the response. When added beneath on the public partial class Form1 : Form line it goes from 0 errors to 21 errors and all of Form1 so I tried to add it before this line. It drops to 1 error "Attribute DLLImport is not valid on this declaration type". I looked up that error but am unsure of what it is telling me. It seems I am not putting the the correct pieces of code in the correct blocks and the more I noodle, the more it breaks it – roar Commented Nov 22, 2024 at 15:06
  • Your question is not related to the development environment Visual Studio itself, so I've removed that tag. Hint: Use the little "i" next to the tag to get information about how to use it. – Klaus Gütter Commented Nov 22, 2024 at 17:06
  • Winforms implies Windows, and while NTFS does support symlinks, it's not something very many people ever actually do or use. Finding a symlinked file in this environment tends to cause more confusion than anything else. – Joel Coehoorn Commented Nov 22, 2024 at 17:32
  • Fair enough, tbh I am happy with the batch file but someone asked me could I make a simple GUI and I landed here. For context, it's specially for DaVinci Resolve on windows as it can read symlinks in Volumes as media drives, then there is no need to remember which letter is which across multiple systems and users. – roar Commented Nov 22, 2024 at 18:26
 |  Show 2 more comments

1 Answer 1

Reset to default 0

According to the documentation for CreateSymbolicLinkA the header file is Winbase.h which can be found in the Windows SDK. After installing the Windows SDK look in %Program Files(x86)%\Windows Kits\10\Include<version>\um\WinBase.h.

According to Winbase.h:

Specify this flag if you want to allow creation of symbolic links when the process is not elevated. As of now enabling DEVELOPER MODE on a system is the only scenario that allow unprivileged symlink creation. There may be future scenarios that this flag will enable in the future. Also be aware that the behavior of this API with this flag set will likely be different between a development environment and an and customers environment so please be careful with the usage of this flag.

#define SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE (0x2)


Option 1:

Add an Application Manifest to your project

Note: This is used to prompt the user to execute the program as Administrator.

  • In VS menu, click Project
  • Select Add New Item...
  • Select Application Manifest File (Windows Only) (name: app.manifest)
  • Click Add

In app.manifest, replace

<requestedExecutionLevel level="asInvoker" uiAccess="false" />

with

<requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />

Option 2:

As stated above, another option is to enable Developer Mode in Windows then use the following code:

[Flags]
enum SymbolicLink: uint
{
    File = 0,
    Directory = 1,
    ALLOW_UNPRIVILEGED_CREATE = 2
}


bool result = CreateSymbolicLink(symbolicLink, fileName, SymbolicLink.File | SymbolicLink.ALLOW_UNPRIVILEGED_CREATE);
System.Diagnostics.Debug.WriteLine($"result: {result}");


Option 3:

A more desirable option may be to use System.Diagnostic.Process to execute the commands you listed in your .bat file. The following should be helpful:

  • post 1
  • post 2

本文标签: cHow to make symbolic links in Visual Studio (Window Forms)Stack Overflow