1. [Windows] Associate file extensions with a program

Hi all,

I wrote two small routines, that allow to associate file extensions with
a program on Windows.
Does anyone see a mistake/bug in the code? The code seems to work fine
on Win 98. Is it also appropriate for other Windows versions? How can I
"uninstall" these associations? Can it be done in a similar simple way,
or will I have to use Windows API functions for that purpose?

-- tested with Eu 2.4
include wildcard.e                         -- for lower()

function escape (sequence fileName)
   sequence ret
   integer char

   ret = ""
   for i = 1 to length(fileName) do
      char = fileName[i]
      if char = '\\' then
         ret &= "\\\\"
      else
         ret &= char
      end if
   end for
   return ret
end function

global function registry_associate (
                                    sequence regFile,
                                    sequence extensionList,
                                    sequence fileType,
                                    sequence description,
                                    sequence iconFile,
                                    integer  iconNo,
                                    sequence progFile
                                   )
   -- Produces the file <regFile>.
   -- When on Windows then <regFile> is double-clicked, files with
   -- an extension contained in <extensionList> will be associated with
   -- the denoted icon and with program <progFile>.

   integer fw

   if not equal(lower(regFile[length(regFile)-3..length(regFile)]), ".reg") then
      regFile &= ".reg"
   end if

   fw = open(regFile, "w")
   if fw = -1 then
      return -1                            -- error
   end if

   puts(fw, "REGEDIT4\n\n")

   for i = 1 to length(extensionList) do
      printf(fw, "[HKEY_CLASSES_ROOT\\.%s]\n", {extensionList[i]})
      printf(fw, "@=\"%s\"\n\n", {fileType})
   end for

   printf(fw, "[HKEY_CLASSES_ROOT\\%s]\n", {fileType})
   printf(fw, "@=\"%s\"\n\n", {description})

   printf(fw, "[HKEY_CLASSES_ROOT\\%s\\DefaultIcon]\n", {fileType})
   printf(fw, "@=\"%s,%d\"\n\n", {escape(iconFile), iconNo})

   printf(fw, "[HKEY_CLASSES_ROOT\\%s\\shell\\open\\command]\n", {fileType})
   printf(fw, "@=\"\\\"%s\\\" \\\"%%1\\\"\"\n\n", {escape(progFile)})

   close(fw)
   return 0                                -- success
end function


-- Demo: Write a REG file, that associates the extension "exw" with
--       "C:\\Programs\\Euphoria\\Bin\\exw.exe"
? registry_associate(
                     "test.reg",
                     {"exw"},
                     "EuWinApp",
                     "Euphoria Windows App",
                     "C:\\Programs\\Euphoria\\Bin\\exw.exe",
                     0,
                     "C:\\Programs\\Euphoria\\Bin\\exw.exe"
                    )


TIA,
   Juergen

-- 
We don't know where to GOTO if we don't know where we've COME FROM.
http://www.fortran.com/fortran/come_from.html

new topic     » topic index » view message » categorize

2. Re: [Windows] Associate file extensions with a program

On Sun, 10 Oct 2004 21:37:40 +0200, Juergen Luethje <j.lue at gmx.de>
wrote:

>How can I "uninstall" these associations?
According to www.wotsit.org/search.asp?page=3&s=windows :
Delete the key & all it's subkeys by beginning it with -, eg
>   printf(fw, "[-HKEY_CLASSES_ROOT\\%s\\DefaultIcon]\n", {fileType})
Delete individual values using a single unquoted minus sign, eg
>      printf(fw, "@=-\n", {})

Regards,
Pete
>   return 0                                -- success
PS: Please do not return False to indicate success.

new topic     » goto parent     » topic index » view message » categorize

3. Re: [Windows] Associate file extensions with a program

Pete Lomax wrote:

> On Sun, 10 Oct 2004 21:37:40 +0200, Juergen Luethje <j.lue at gmx.de>
> wrote:
>
>> How can I "uninstall" these associations?
>
> According to www.wotsit.org/search.asp?page=3&s=windows :
> Delete the key & all it's subkeys by beginning it with -, eg
>
>>   printf(fw, "[-HKEY_CLASSES_ROOT\\%s\\DefaultIcon]\n", {fileType})
>
> Delete individual values using a single unquoted minus sign, eg
>
>>      printf(fw, "@=-\n", {})
>
> Regards,
> Pete

Thanks, Pete!

>>   return 0                                -- success
>
> PS: Please do not return False to indicate success.

It's a habit of mine. I can't remember when/why I started to do so,
maybe I borrowed it from Euphoria's seek().
What do you suggest? True to indicate success, 0 and negative integers
for errors (if possible)?

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

4. Re: [Windows] Associate file extensions with a program

Pete Lomax wrote:

[snip]
> >   return 0                                -- success
> PS: Please do not return False to indicate success.

He didn't. He returned *zero*. I'm sure you are not saying that every
0 is also a 'false', just as every 1 is not a 'true'. Just because
RDS chose to represent a falsehood with integer zero, doesn't mean that
every use of zero implies a falsehood, nor every use of a one implies a 
truth.

Truth and Falsehood are not numbers. RDS represents these concepts by
using numbers, but that is a mere convenience. 

In Juergen's routine, 0 *represents* a success not a falsehood. 

One might argue that using zero for success makes reading code a problem
if you write code thus ...

    if not SomeFunc() then
       -- Success!
       DoSuccess()
    else
       -- Failure
       DoFailed()
    end if

I maintain that a 'better' way to write such code is more like ...

   constant SUCCESS = 0
   if SomeFunc() = SUCCESS then
     DoSuccess()
   else
     Do Failed()
   end if

-- 
Derek Parnell
Melbourne, Australia

new topic     » goto parent     » topic index » view message » categorize

5. Re: [Windows] Associate file extensions with a program

I totally agree with Derek - I stopped using 0 and 1 as success indicators
after I spent an entire weekend debugging some code. I now use:

global constant Good = #FFFF, Bad = -#FFFF
if my_function(blah)= Good then <code goes here> Endif

It may look funny, but trust me; in the long run you'll save much debugging
time (and hair pulling).

Yours, OtterDad

Don't sweat it -- it's not real life. It's only ones and zeroes. Gene Spafford

new topic     » goto parent     » topic index » view message » categorize

6. Re: [Windows] Associate file extensions with a program

On Mon, 11 Oct 2004 12:43:40 +0200, Juergen Luethje <j.lue at gmx.de>
wrote:

>Pete Lomax wrote:
>> PS: Please do not return False to indicate success.
>
>It's a habit of mine.
OK, if it's a habit, then I withdraw my request. I guess it is only a
habit of mine to return 1, since I rarely bother to return specific
error conditions.

Regards,
Pete

new topic     » goto parent     » topic index » view message » categorize

7. Re: [Windows] Associate file extensions with a program

Pete Lomax wrote:

> On Mon, 11 Oct 2004 12:43:40 +0200, Juergen Luethje <j.lue at gmx.de>
> wrote:
>
>> Pete Lomax wrote:
>>> PS: Please do not return False to indicate success.
>>
>> It's a habit of mine.
> OK, if it's a habit, then I withdraw my request. I guess it is only a
> habit of mine to return 1, since I rarely bother to return specific
> error conditions.

Unfortunately, it's not possible anyhow, to consistently return errors
as function values. E.g. in many math functions, we can't return a
number such as -1, 0 or 1 as error values, because these values might be
normal results of that function.
We could return e.g. {} to inicate an error, or even {1}, {2} to
indicate specific errors. But there are also functions, that legally can
return arbitrary objects.
I'll think about my habits in this regard. Maybe it's cleaner to use a
global error variable.

Regards,
   Juergen

-- 
We don't know where to GOTO if we don't know where we've COME FROM.
http://www.fortran.com/fortran/come_from.html

new topic     » goto parent     » topic index » view message » categorize

8. Re: [Windows] Associate file extensions with a program

Juergen Luethje wrote:
> 
> Pete Lomax wrote:
> 
> > On Mon, 11 Oct 2004 12:43:40 +0200, Juergen Luethje <j.lue at gmx.de>
> > wrote:
> >
> >> Pete Lomax wrote:
> >>> PS: Please do not return False to indicate success.
> >>
> >> It's a habit of mine.
> > OK, if it's a habit, then I withdraw my request. I guess it is only a
> > habit of mine to return 1, since I rarely bother to return specific
> > error conditions.
> 
> Unfortunately, it's not possible anyhow, to consistently return errors
> as function values. E.g. in many math functions, we can't return a
> number such as -1, 0 or 1 as error values, because these values might be
> normal results of that function.
> We could return e.g. {} to inicate an error, or even {1}, {2} to
> indicate specific errors. But there are also functions, that legally can
> return arbitrary objects.

I've been using the method of always returning a sequence; the first
element is the return code and the second is the function value.

> I'll think about my habits in this regard. Maybe it's cleaner to use a
> global error variable.

A simple global error variable is a *bad* idea. It can lead to subtle
bugs if you cannot guarentee that the function you called is the *only*
function that sets the single shared error variable. 

-- 
Derek Parnell
Melbourne, Australia

new topic     » goto parent     » topic index » view message » categorize

9. Re: [Windows] Associate file extensions with a program

Derek Parnell wrote:

> Juergen Luethje wrote:

<snip>

>> Unfortunately, it's not possible anyhow, to consistently return errors
>> as function values. E.g. in many math functions, we can't return a
>> number such as -1, 0 or 1 as error values, because these values might be
>> normal results of that function.
>> We could return e.g. {} to inicate an error, or even {1}, {2} to
>> indicate specific errors. But there are also functions, that legally can
>> return arbitrary objects.
>
> I've been using the method of always returning a sequence; the first
> element is the return code and the second is the function value.

Ah, yes.. I couldn't see the wood for the trees. blink

>> I'll think about my habits in this regard. Maybe it's cleaner to use a
>> global error variable.
>
> A simple global error variable is a *bad* idea. It can lead to subtle
> bugs if you cannot guarentee that the function you called is the *only*
> function that sets the single shared error variable.

I'd be interested in your opinion about the following two
implementations.

-- Implementation #1
integer ErrNo
ErrNo = 0                -- no error at the beginning

procedure proc1()
   if <some error> then
      ErrNo = 27
   elsif <another error> then
      ErrNo = 5
   else
      ErrNo = 0
   end if
end procedure

procedure proc2()
   if <some error> then
      ErrNo = 3
   elsif <another error> then
      ErrNo = 22
   else
      ErrNo = 0
   end if
end procedure

proc1()
proc2()


I think here is a problem, when there is an error in proc1(), and no
error in proc2(). proc2() then will clear the variable 'ErrNo', and the
information about the error in proc1() is lost.

-- Implementation #2
integer ErrNo
ErrNo = 0                -- no error at the beginning

procedure proc1()
   if <some error> then
      ErrNo = 27
   elsif <another error> then
      ErrNo = 5
   end if
end procedure

procedure proc2()
   if <some error> then
      ErrNo = 3
   elsif <another error> then
      ErrNo = 22
   end if
end procedure

proc1()
proc2()


The same as above, but without
   else ErrNo = 0.
In this case, 'ErrNo' never will be cleared, and it always holds the
number of the last error that occured.

I can see that implementation #1 is not a good idea, but what about
implementation #2?

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

10. Re: [Windows] Associate file extensions with a program

On Tue, 12 Oct 2004 20:32:38 +0200, Juergen Luethje <j.lue at gmx.de>
wrote:

>I can see that implementation #1 is not a good idea, but what about
>implementation #2?
If there is an error in proc1, such as FileDoesNotExist, then it would
not help matters to replace this with ErrorWritingToFile in proc2.

In fact, wouldn't most error conditions tend to daisy-chain?

Regards,
Pete

new topic     » goto parent     » topic index » view message » categorize

11. Re: [Windows] Associate file extensions with a program

Juergen Luethje wrote:

[snip]
> 
> I'd be interested in your opinion about the following two
> implementations.
> 
> }}}
<eucode>
> -- Implementation #1
> integer ErrNo
> ErrNo = 0                -- no error at the beginning
> 
> procedure proc1()
>    if <some error> then
>       ErrNo = 27
>    elsif <another error> then
>       ErrNo = 5
>    else
>       ErrNo = 0
>    end if
> end procedure
> 
> procedure proc2()
>    if <some error> then
>       ErrNo = 3
>    elsif <another error> then
>       ErrNo = 22
>    else
>       ErrNo = 0
>    end if
> end procedure
> 
> proc1()
> proc2()
> </eucode>
{{{

> 
> I think here is a problem, when there is an error in proc1(), and no
> error in proc2(). proc2() then will clear the variable 'ErrNo', and the
> information about the error in proc1() is lost.
> 
> }}}
<eucode>
> -- Implementation #2
> integer ErrNo
> ErrNo = 0                -- no error at the beginning
> 
> procedure proc1()
>    if <some error> then
>       ErrNo = 27
>    elsif <another error> then
>       ErrNo = 5
>    end if
> end procedure
> 
> procedure proc2()
>    if <some error> then
>       ErrNo = 3
>    elsif <another error> then
>       ErrNo = 22
>    end if
> end procedure
> 
> proc1()
> proc2()
> </eucode>
{{{

> 
> The same as above, but without
>    else ErrNo = 0.
> In this case, 'ErrNo' never will be cleared, and it always holds the
> number of the last error that occured.
> 
> I can see that implementation #1 is not a good idea, but what about
> implementation #2?

Well we are using Euphoria so why not take advantage of that?

sequence ErrNo
 ErrNo = {}                -- no error at the beginning
 
 procedure proc3()
    if <some error> then
       ErrNo &= {{"proc3",7}}
    elsif <another error> then
       ErrNo &= {{"proc3",8}}
    end if
 end procedure
 
 procedure proc1()
    if <some error> then
       ErrNo &= {{"proc1",27}}
    elsif <another error> then
       ErrNo &= {{"proc1",5}}
    end if
 end procedure
 
 procedure proc2()
    proc3()
    if <some error> then
       ErrNo &= {{"proc2",3}}
    elsif <another error> then
       ErrNo &= {{"proc2",22}}
    end if
 end procedure

 ErrNo = {} 
 proc1()
 proc2()
 for i = 1 to length(ErrNo) do
    if equal("proc1", ErrNo[i][1]) then
          . . . 
    elsif equal("proc2", ErrNo[i][1]) then
        . . .
    elsif equal("proc3", ErrNo[i][1]) then
        . . .
    end if
 end for


-- 
Derek Parnell
Melbourne, Australia

new topic     » goto parent     » topic index » view message » categorize

12. Re: [Windows] Associate file extensions with a program

Pete Lomax wrote:

> On Tue, 12 Oct 2004 20:32:38 +0200, Juergen Luethje <j.lue at gmx.de>
> wrote:
>
>> I can see that implementation #1 is not a good idea, but what about
>> implementation #2?
>
> If there is an error in proc1, such as FileDoesNotExist, then it would
> not help matters to replace this with ErrorWritingToFile in proc2.
>
> In fact, wouldn't most error conditions tend to daisy-chain?

Probably yes.

But it's up to the author of the main program (maybe myself) anyway, to
check early and often for errors, regardless wether errors are returned
as results of functions, or in a local/global variable.

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

13. Re: [Windows] Associate file extensions with a program

Derek Parnell wrote:

> Juergen Luethje wrote:
>
> [snip]
>>
>> I'd be interested in your opinion about the following two
>> implementations.

<snip>

> Well we are using Euphoria so why not take advantage of that?

<snip>

Cool smile
Thanks, Derek!

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

14. Re: [Windows] Associate file extensions with a program

Juergen Luethje wrote:
> 
> Derek Parnell wrote:
> 
> > Juergen Luethje wrote:
> 
> 

-- Implementation #another
 integer error
 sequence ErrNo
 ErrNo &= {}                -- no error at the beginning
 
 procedure proc1()
    if <some error> then
       ErrNo &= 27
    elsif <another error> then
       ErrNo &= 5
    end if
 end procedure
 
 procedure proc2()
    if <some error> then
       ErrNo &= 3
    elsif <another error> then
       ErrNo &= 22
    end if
 end procedure
 
 proc1()
 proc2()
 
 error = not find(0,ErrNo)

 if error then
   puts(1,ErrNo[error]&"\n" end if
 end if 


Bernie

My files in archive:

http://www.rapideuphoria.com/w32engin.zip
http://www.rapideuphoria.com/mixedlib.zip
http://www.rapideuphoria.com/eu_engin.zip
http://www.rapideuphoria.com/win32eru.zip

new topic     » goto parent     » topic index » view message » categorize

15. Re: [Windows] Associate file extensions with a program

> [snip]
> > >   return 0                                -- success
> > PS: Please do not return False to indicate success.
> 
> He didn't. He returned *zero*. I'm sure you are not saying that every
> 0 is also a 'false', just as every 1 is not a 'true'. Just because
> RDS chose to represent a falsehood with integer zero, doesn't mean that
> every use of zero implies a falsehood, nor every use of a one implies a 
> truth.
> 
> Truth and Falsehood are not numbers. RDS represents these concepts by
> using numbers, but that is a mere convenience. 

almost every commandline tool I use returns an error level of zero 
to indicate success. It seems broadly adopted.

new topic     » goto parent     » topic index » view message » categorize

16. Re: [Windows] Associate file extensions with a program

Michael Raley wrote:
> 
> > [snip]
> > > >   return 0                                -- success
> > > PS: Please do not return False to indicate success.
> > 
> > He didn't. He returned *zero*. I'm sure you are not saying that every
> > 0 is also a 'false', just as every 1 is not a 'true'. Just because
> > RDS chose to represent a falsehood with integer zero, doesn't mean that
> > every use of zero implies a falsehood, nor every use of a one implies a 
> > truth.
> > 
> > Truth and Falsehood are not numbers. RDS represents these concepts by
> > using numbers, but that is a mere convenience. 
> 
> almost every commandline tool I use returns an error level of zero 
> to indicate success. It seems broadly adopted.
> 

Including the Eu interpreter itself.*

* see abort(i)  ;)

new topic     » goto parent     » topic index » view message » categorize

17. Re: [Windows] Associate file extensions with a program

Bernard Ryan wrote:

> Juergen Luethje wrote:
>>
>> Derek Parnell wrote:
>>
>>> Juergen Luethje wrote:
>>
>
>  }}}
<eucode>
>  -- Implementation #another
>  integer error
>  sequence ErrNo
>  ErrNo &= {}                -- no error at the beginning
>
>  procedure proc1()
>     if <some error> then
>        ErrNo &= 27
>     elsif <another error> then
>        ErrNo &= 5
>     end if
>  end procedure
>
>  procedure proc2()
>     if <some error> then
>        ErrNo &= 3
>     elsif <another error> then
>        ErrNo &= 22
>     end if
>  end procedure
>
>  proc1()
>  proc2()
>
>  error = not find(0,ErrNo)

As implemented above, ErrNo never will contain a 0, so 'find(0,ErrNo)'
always will be 0, and 'error = not 0' will result in 'error = 1'.

>  if error then
>    puts(1,ErrNo[error]&"\n" end if
>  end if
> </eucode>
{{{


if length(ErrNo) then
   print(ErrNo)
end if

works for me. smile

Thanks,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

18. Re: [Windows] Associate file extensions with a program

Brian Broker wrote:

> Michael Raley wrote:

<snip>

>> almost every commandline tool I use returns an error level of zero
>> to indicate success. It seems broadly adopted.
>>
>
> Including the Eu interpreter itself.*
>
> * see abort(i)  ;)

Yep. smile

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

19. Re: [Windows] Associate file extensions with a program

Pete Lomax wrote:
> 
> Juergen Luethje wrote:
> 
> > I can see that implementation #1 is not a good idea, but what about
> > implementation #2?
>
> If there is an error in proc1, such as FileDoesNotExist, then it would
> not help matters to replace this with ErrorWritingToFile in proc2.
> 
> In fact, wouldn't most error conditions tend to daisy-chain?

Yes.  It's important to allow for errors to propagate back up through
the call chain.  I've done this a couple of different ways in EuSQL and
in matheval.  In EuSQL, all functions return a sequence on success, and 
an integer on failure.  After pretty much every call from a library 
routine to another, I check this condition, and simply return the error
code.  There is also an extended error message that can be set, and that
an application can request.

In matheval, I defined a separate type, called INVALID.  Each matheval
type is smart enough to only operate on other types that it understands,
so the INVALID type is simply passed back.  Part of the INVALID type is
an error message.

Matt Lewis

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu