Author Topic: Go To Link Target v2  (Read 26232 times)

pncdaspropagandas

  • Contributor
  • Active Member
  • *****
  • Posts: 93
    • View Profile
Go To Link Target v2
« on: August 02, 2017, 03:38:05 »
Hi,

As Mathias added new functions to MultiScript, I updated my script. Now it is much mor concise.

For the hardlink detection I use FindLinks from SysInternals on https://docs.microsoft.com/en-us/sysinternals/downloads/findlinks and put it on mcinstallpath\Tools\Links\Hardlinks

MultiScript:
// Junction, Symlink, MountPoint & Windows Shrtcut -> get link target with MultiComander - reliable
// Hardlink -> get link target with findlinks64.exe - communication via text file

@var $source_focus_path = GetSourceFocusPath();
@var $link_target;
@var $link_targets[];
@var $target_count;
@var $link_found;
@var $link_target_temp_file;
@var $temp_file_content;
@var $link_target_file_size;
@var $findlinks_path;
@var $aux[];
@var $aux2;
@var $n;
@var $mcinstallpath = GetTagValue("${mcinstallpath}");

//0 - Not a link (maybe a hardlink)
//1 - Junction
//2 - Symlink
//3 - MountPoint
@var $link_type = GetFSLinkType($source_focus_path);
if( $link_type == 0 )
{
   $link_target = GetWinShortcutTarget($source_focus_path);
   //LogAppInfo('shortcut to ' + $link_target);
   if( !($link_target == '') )
   {
      $link_found = 1;
      SetClipboardText($link_target);
   }
   else
   {
      // Hardlink
      $link_target_temp_file = $mcinstallpath ^ 'Tools\Links\Hardlink\link_target.txt';
      $findlinks_path = $mcinstallpath ^ 'Tools\Links\Hardlink\FindLinks.exe';
      
      if (FileExists($link_target_temp_file) == 1)
      {
         $aux = {"NOPROGRESS", "NODIALOG", "SILENT"};
         DeleteFile($link_target_temp_file, $aux);
      }
      
      LogAppInfo('C:\Windows\System32\wscript.exe "' + $mcinstallpath ^ 'Tools\run_invisible\run_invisible_bat_2_args.vbs" "' + $mcinstallpath ^ '\Tools\Links\Hardlink\bat_findlinks.bat" "' + $source_focus_path + '" "' + $link_target_temp_file + '"');
      MC.Run CMD={'C:\Windows\System32\wscript.exe'} ARG={'"' + $mcinstallpath ^ 'Tools\run_invisible\run_invisible_bat_2_args.vbs" "' + $mcinstallpath ^ '\Tools\Links\Hardlink\bat_findlinks.bat" "' + $source_focus_path + '" "' + $link_target_temp_file + '"'} STARTIN={$mcinstallpath ^ '\Tools\Links\Hardlink'} WAIT
      
      
      // Work on FindLinks' return
      if (FileExists($link_target_temp_file) == 1)
      {
         //Sleep(100);
         
         $link_target_file_size = GetFileSize($link_target_temp_file);
         if ($link_target_file_size > 0)
         {
            $temp_file_content = LoadStringFromFile($link_target_temp_file);
            //LogAppInfo($temp_file_content);
            
            // Delete temp file
            $aux = {"NOPROGRESS", "NODIALOG", "SILENT"};
            DeleteFile($link_target_temp_file, $aux);
            
            // Check/Parse link_target_temp_file content
            @var $temp_file_lines[] = StrLines2Array($temp_file_content);
            if( StrIsWildMatch($temp_file_lines[0], 'Error*') )
            {
               MessageBox('Resolve Link', 'Error logged by FindLinks.', 0);
               break;
            }
            else
            {
               $target_count = arrayCount($temp_file_lines);
               // 4 lines -> no links
               // 7 lines -> 1 link
               // 8 lines -> 2 links
               // etc
               if( $target_count >= 6 )
               {
                  $link_found = 1;
                  $link_target = $temp_file_lines[5];
                  
                  // More than 1 hardlink found
                  if( $target_count > 6 )
                  {
                     // Mount an array with all hardlinks targets, so the user can choose
                     for( $n=5; $n<$target_count; $n++ )
                     {
                        arrayAdd($link_targets, $temp_file_lines[$n]);
                     }
                     
                     // Ask user
                     @var $link_targets_answer = AskOption('Select target', $link_targets, 0);
                     if ($link_targets_answer == -1)
                     {
                        // User cancelled
                        break;
                     }
                     
                     $link_target = $link_targets[$link_targets_answer];
                  }
               }
            }
            
         }
         else
         {
            LogAppInfo('Error');
         }
   
      }
      else
      {
         MessageBox('Resolve Link', 'Operation timeout', 0);
         break;
      }
   }
}
else
{
   // Junction, Symlink or MountPoint
   $link_found = 1;
   $link_target = GetFSLinkTarget($source_focus_path);
}


// Go to target
if( $link_found )
{
   // Clear selected files in the case of the link target being on the same folder
   arrayAdd($aux, '');
   SetSourceSelected($aux, 1);
   
   SetClipboardText($link_target);
   
   // As Mathias said here http://forum.multicommander.com/forum/index.php/topic,1929.0.html
   // "the UI can't be updated until the script is finished since the script is running in the same thread"
   // So there's no way to break going to the folder, then selecting the file in 2 operations
   // We can do it in 1 go using MC.RunCmd ID="Core.1312" that is CTRL+V with the target path on the clipboard
   
   // Go To Link Target
   MC.RunCmd ID="Core.1312"
   
}
else
{
   MessageBox('Resolve Link', 'Not a link.', 0);
}


bat_findlinks.bat file:
FindLinks.exe %1 > %2