Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Win32 CSIDL_LOCAL_APPDATA

by jkeenan1 (Deacon)
on Aug 23, 2005 at 13:39 UTC ( #485902=perlquestion: print w/ replies, xml ) Need Help??
jkeenan1 has asked for the wisdom of the Perl Monks concerning the following question:

In our discussion last week Re^6: Installing a config file during module operation of how to install a config file during module operation, xdg provided this solution:

> perl -MWin32=CSIDL_LOCAL_APPDATA -le "print Win32::GetFolderPath(CSI +DL_LOCAL_APPDATA)" C:\Documents and Settings\DGolden\Local Settings\Application Data

This works on my system as well, but I'm having trouble translating that to code inside a program. Consider this:

my $realhome; if ($^O eq 'MSWin32') { use Win32 ('CSIDL_LOCAL_APPDATA'); $realhome = Win32::GetFolderPath('CSIDL_LOCAL_APPDATA'); } (defined $realhome) ? print "realhome: $realhome\n" : print "\$realho +me not defined\n";

This is generating a warning, then producing an answer suggesting that the CSIDL_LOCAL_APPDATA constant was not, in reality, imported:

Argument "CSIDL_LOCAL_APPDATA" isn't numeric in subroutine entry at im +port.pl line 9. realhome: C:\Documents and Settings\kbuser\Desktop

I'm puzzled about the "isn't numeric" warning: As I understand it, it's not supposed to be numeric because it'a a path (and I double-check Microsoft's information http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/enums/csidl.asp on this).

What am I not getting? Thanks.

Jim Keenan

Update:Corrected typo in title.

Comment on Win32 CSIDL_LOCAL_APPDATA
Select or Download Code
Re: Win32 CSIDL_LOCAL_APPDATA
by holli (Monsignor) on Aug 23, 2005 at 13:50 UTC
    The good new first:
    The program runs fine on my system (XP, AS Perl 5.8.6)

    I'm puzzled about the "isn't numeric" warning: As I understand it, it's not supposed to be numeric because it'a a path
    No. The return value of GetFolderPath is a path. The CSIDL_LOCAL_APPDATA is a numeric constant that tells the function which path to return.

    Note that code in the style of
    if ($something) { use Some::Module; }
    does not DWYM. use is a compile time statement. There are some nodes about conditionally loading modules at runtime here. Go Super Search.

    Also you show poor style in your use of the ternary operator. Better write that as
    print defined $realhome ? "realhome: $realhome\n" : "\$realhome not d +efined\n";


    holli, /regexed monk/
      holli wrote:

      The good new first: The program runs fine on my system (XP, AS Perl 5.8.6)

      I'm using Win2000 Pro, Active Perl 5.8.7. I don't think that should be the source of the problem.

      The return value of GetFolderPath is a path. The CSIDL_LOCAL_APPDATA is a numeric constant that tells the function which path to return.

      Okay, but that doesn't solve the mystery as to why it's not returning the same path that the command-line invocation did.

      Note that code in the style of if ($something) {use Some::Module;} does not DWYM. use is a compile time statement. There are some nodes about conditionally loading modules at runtime here.

      Correct, but I got the same results using require:

      use strict; use warnings; use Exporter qw(import); my $realhome; if ($^O eq 'MSWin32') { require Win32; import ('CSIDL_LOCAL_APPDATA'); $realhome = Win32::GetFolderPath('CSIDL_LOCAL_APPDATA'); }

      jimk

        I'm sticking some *n*x bias in this question, but are you sure your CLI execution is from the same point on the path as your scripted execution?
Re: Win32 CSIDL_LOCAL_APPDATA
by xdg (Monsignor) on Aug 23, 2005 at 15:02 UTC

    CSIDL_LOCAL_APPDATA is a subroutine. So you've got to call it to return the right numeric flag for GetFolderPath.

    $realhome = Win32::GetFolderPath( CSIDL_LOCAL_APPDATA() );

    -xdg

    Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

      xdg wrote:

      CSIDL_LOCAL_APPDATA is a subroutine. So you've got to call it to return the right numeric flag for GetFolderPath.

      $realhome = Win32::GetFolderPath( CSIDL_LOCAL_APPDATA() );

      Revising the relevant code per your suggestion ...

      if ($^O eq 'MSWin32') { require Win32; import qw(CSIDL_LOCAL_APPDATA); $realhome = Win32::GetFolderPath( CSIDL_LOCAL_APPDATA() ); }

      ... I now get this error:

      Undefined subroutine &main::CSIDL_LOCAL_APPDATA called at import.pl li +ne 11.

      jimk

      Update:Or, from the command-prompt:

      F:\AAAother\data>perl -MExporter -e "require Win32; Exporter::import ' +CSIDL_LOCAL_APPDATA'; print Win32::GetFolderPath( CSIDL_LOCAL_APPDATA +() );" Undefined subroutine &main::CSIDL_LOCAL_APPDATA called at -e line 1.

      Further update:I just consulted the MS documentation, which provides 0x001c as the hex numerical value for CSIDL_LOCAL_APPDATA (). Substituting that into the previous code (and simplifying a bit), I get:

      if ($^O eq 'MSWin32') { require Win32; print Win32::GetFolderPath( 0x001c ), "\n"; }

      ... which DWIMs on my system as:

      C:\Documents and Settings\kbuser\Local Settings\Application Data

      (Big sigh of relief!) Now, let's see if it works in the application from which all of the foregoing is excerpted. Thanks for your help.

      jimk

      Yet another update:Although the path listed immediately above is the return value generated by GetFolderPath (both in my implementation and in that suggested later by xdg), no such path could be found on my system, at least not through Windows Explorer/My Computer. That's because the directory level 'Local Settings' is absent. In order to get my application to work, I had to do the following (done from memory, so I don't guarantee it):

      $realhome = Win32::GetFolderPath( CSIDL_LOCAL_APPDATA() ); $realhome =~ s|(.*?)\\Local Settings(.*)|$1$2|;

        I suspect you've been through too many iterations trying to get it to work to see the code clearly. Stepping back, you need to specify the package to import (ah, the irony of import):

        if ($^O eq 'MSWin32') { require Win32; Win32->import( qw(CSIDL_LOCAL_APPDATA) ); $realhome = Win32::GetFolderPath( CSIDL_LOCAL_APPDATA() ); }

        -xdg

        Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

        what happens when you put a
        print CSIDL_LOCAL_APPDATA . "\n";
        into your both versions? Does that show the same value? Also, are you sure the perl in your path is the same perl that is associated with the .pl extension?
        That may sound dumb but i encountered that once. A guy in the office called me to assist in a perl error message.
        Can't locate Something.pm in @INC ...
        Me: Easy. You don't have Something.pm installed.
        He: (sighs) I know but I have written Something.pm It is there. Look. (and showed me the file c:\perl\site\lib\Something.pm
        Me: Mmh.

        I spend 2 hours searching for the reason. It turned out that this colleague had installed a "raw" perl (without installer or other such luxury). And because c:\perl was already used by AS Perl, he, in his wisdom, decided to install the second perl in c:\per1 and altered the path accordingly. So, when you typed
        perl somescript.pl
        the second perl executed the script. And when you typed
        somescript.pl
        or doubleclicked the script cia Explorer the AS Perl was in charge.


        holli, /regexed monk/

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://485902]
Approved by muntfish
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (10)
As of 2014-10-23 07:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (125 votes), past polls