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

Good day Bros. I have been working on some automation to extract data from an old Visual Source Safe database. Based on advice I got in this thread I got it working by executing the SS.exe command line interface for VSS, using the backtick method to capture results.

For reasons I need not go into, I upgraded from VSS 6.0 to VSS 2005, which the installer put in a different location. The UI works fine but it broke my script. When I try to run it now, for example (simplified):

#!/usr/bin/perl -w use strict; chdir('C:\Program Files (x86)\Microsoft Visual SourceSafe'); my $result = `SS Dir \"$/\" -Yadmin`; print $result;
I get the error No VSS database (srcsafe.ini) found.  Set the SSDIR environment variable to the path of srcsafe.ini for your VSS database.

I have set that environment variable and it still doesn't work, but that's not a Perl issue. The Perl issue is that when I open a command window, cd to the directory above, and execute the same command as above, it works fine and gives the expected output (with no complaints about the environment variable). So why would the script fail?

No cerveza, no trabajo.

Replies are listed 'Best First'.
Re: VSS automation strange problem
by huck (Prior) on Jan 03, 2017 at 23:26 UTC

    My first thought is that when running the perl script you are not the same user with the same permissions and environment variable that you are when you run the commands by hand. Is the perl script running under some service, Daemon or task scheduler?

      I think you are right. I have been running the script via Komodo IDE so I can debug it. I did not configure it as a separate user, but when I run
      #!/usr/bin/perl -w use strict; my $foo = `echo %SSDIR%`; print $foo;
      from it, it shows that the ENV variable is not set, whereas it is from the command line.

      But there is only one user on this (Windows 10) machine. Any idea how to track down what user Komodo is running under?

      "I think computers have complicated lives very bigly. The whole age of, you know, computer has made it where nobody knows exactly what's going on." --D. Trump

        one end user maybe, but many other "users" too. SYSTEM, NETWORK SERVICE, LOCAL SERVICE are but a few others. Maybe this will help, i use it to identify who runs my code from a console

        use Win32; my $user = Win32::LoginName();
        If you can put your process into sleep for a bit and can identify it from this list this may help
        use strict; use warnings; use DBI; use DBD::WMI qw/connect prepare execute fetchrow/; use Win32::OLE qw/in/; # needs DBD::WMI # http://search.cpan.org/~corion/DBD-WMI-0.07/lib/DBD/WMI.pm # corion@cpan.org http://www.perlmonks.org/?node_id=5348 # http://www.perlmonks.org/?node_id=565819 #clues from # http://www.perlmonks.org/?node_id=821593 # https://gist.github.com/aero/1260973/6efbe8684aa54c8aecb73f601e511a5 +3bfb5c6b1 # https://msdn.microsoft.com/en-us/library/aa394388(v=vs.85).aspx # https://msdn.microsoft.com/en-us/library/aa394084(v=vs.85).aspx my $dbh = DBI->connect('dbi:WMI:'); sub do_table{ my @tables=@_; table: for my $table (@tables){ my $sth = $dbh->prepare('SELECT * FROM '.$table); unless ($sth->execute()) { print 'Unable to select from:'.$table." +\n"; next table;} print 'Table:'.$table."\n"; my $rowct=0; while (my( $row ) = $sth->fetchrow) { print ' row:'.$rowct++."\n"; foreach my $object ( in($row->{Properties_}) ) { my $outline=" $object->{Name} = "; if ( ref($object->{Value}) eq "ARRAY") { $outline.="{ "; foreach my $value ( in($object->{Value}) ) {$outline.="$va +lue ";} $outline.="}"; } else { $outline.=($object->{Value} // ""); } print $outline."\n"; } # $object } # thing } # table } # do_table do_table("Win32_Process");

        Answering your question is one thing, but this may solve your initial problem better. add this to your code before my $result=...

        $ENV{SSDIR}='c:\\some\\path\\to\\some.ini';
        And if you didnt restart your IDE after setting SSDIR outside it by hand that may be what the problem is. And if you set it via a more permanent method you may need to logoff/login again.

Re: VSS automation strange problem
by Lotus1 (Vicar) on Jan 04, 2017 at 15:52 UTC
    my $result = `SS Dir \"$/\" -Yadmin`;

    Have a look at Corion's node where it is pointed out that you didn't do a character escape for the $ in the backticked command. This is likely to take care of the issues you are having. You might notice in my original suggestion I had the command held in a variable ($cmd) which I print out to verify it looks like I want.

    my $cmd = "\"$sspath\\ss.exe\" Checkout \"\$/DMS MW/SCADA/Substati +on Editor +Files/$filename\" -C- -I- -GL\"$checkout_path \""; #print "\n********************\n\$cmd=$cmd\n"; # if the file is already there it doesn't download it again. # BUT, it won't overwrite a file unless the read-only bit is set. system $cmd;
      Alas, no help. This
      #!/usr/bin/perl -w use strict; use Cwd; chdir('C:\Program Files (x86)\Microsoft Visual SourceSafe'); print cwd()."\n\n"; $ENV{SSDIR} = 'C:\Program Files (x86)\Microsoft Visual SourceSafe'; my $env = `echo %SSDIR%`; print "\n$env\n"; my $cmd = "ss.exe Dir \"\$/\" -Yadmin"; print "$cmd\n\n"; my $result = `$cmd`; print $result;
      yields output
      C:/Program Files (x86)/Microsoft Visual SourceSafe C:\Program Files (x86)\Microsoft Visual SourceSafe ss.exe Dir "$/" -Yadmin No VSS database (srcsafe.ini) found. Set the SSDIR environment variab +le to the path of srcsafe.ini for your VSS database.
      "I think computers have complicated lives very bigly. The whole age of, you know, computer has made it where nobody knows exactly what's going on." --D. Trump

        I just tried the code below and it worked. One thing to check is to be sure you're setting SSDIR to where your srcsafe.ini file is located. From the SS GUI you can click the File pulldown menu and in VSS 6.0 anyway it will show you the path to the srcsafe.ini file just above the 'Exit' command.

        #!/usr/bin/perl use warnings; use strict; my $sspath= 'C:\Program Files (x86)\Microsoft Visual Studio\VSS\win32' +; $ENV{SSDIR}="\\\\server\\path-to-ini"; #or local path #my $cmd = "\"$sspath\\ss.exe\" Dir "; # listed files in defaul +t project my $cmd = "\"$sspath\\ss.exe\" Dir \"\$/\""; # listed subproject fold +ers print "\n********************\n\$cmd=$cmd\n"; system $cmd;

        Update: Although you might be providing the path to an ini file already, since you have installed a new version you might have multiple srcsafe.ini files. By checking the path in the GUI you can verify you are using the correct one.

        At least according to the internet, setting the environment variable doesn't always work.

        Have you compared the environment variables that are set when you manually run the command from the command prompt and what %ENV contains?