For Programmers: Free Programming Magazines  


Home > Archive > Visual Basic Syntax > March 2005 > Using Shell to execute cacls in VB









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Using Shell to execute cacls in VB
Capp

2005-03-23, 4:01 am

Hello,
I am writing an app to change a few manage a few file permissions but I am
having some problems with the syntac using CACLS.
This is what I have:

Shell ("cacls c:\progra~1\folder /D Everyone") - this works just fine, but I
want to automate the process because it asks "Are you sure Y/N?"

when done in command prompt I can do this:
echo y| cacls c:\progra~1\folder /D Everyone
and it works just fine, but for some reason I can't do the "Echo" in vb.

Can anybody help me with this one.

Thanks :)
Rick Rothstein

2005-03-23, 4:01 am

> I am writing an app to change a few manage a few file permissions
but I am
> having some problems with the syntac using CACLS.
> This is what I have:
>
> Shell ("cacls c:\progra~1\folder /D Everyone") - this works just fine,

but I
> want to automate the process because it asks "Are you sure Y/N?"
>
> when done in command prompt I can do this:
> echo y| cacls c:\progra~1\folder /D Everyone
> and it works just fine, but for some reason I can't do the "Echo" in

vb.
>
> Can anybody help me with this one.


ECHO is an internal DOS command and, as such, requires the command
processor be specified. The following is a compilation of several posts
I've given in the past regarding the Shell command. The use of the
command processor is covered in the opening paragraph; the remainder is
for your consideration.

Rick -MVP

You can use the Shell command. To execute internal DOS command (Dir,
Copy, etc. as well as redirection of screen output), the command
processor must be specified (using the Environ$ function and "comspec"
as its argument returns the correct command processor path on NT and
non-NT systems) . Specifying the command processor is safe & generic and
will work with non-internal commands also. That syntax, using an XCopy
command as an example is:

Shell Environ$("comspec") & " /c xcopy """ & _
Source & """ """ & Destination & """ " & Option, vbHide

You set the Source and Desination (string variables) to the appropriate
paths and the Option (string variable), if any, which can be found by
opening an MSDOS Prompt window and typing xcopy /?. (Note: You can type
/? after any DOS command at a DOS prompt to list the available options
for that command.) One more example would be to list all the files in a
directory including subdirectories and subdirectories of subdirectories
and all of their files.

CommandLine = "dir """ & FileSpec & _
""" /s/b > """ & RedirectTo & """"
Shell Environ$("comspec") & " /c " & CommandLine, vbHide

Here, the output of a Dir command is redirected to a file-path you
specify in the RedirectTo (string variable). The /s/b are options to the
Dir command that tell it to recurse throught its subdirectories and not
to include header or summary information.

I used a variable for the file name so that I could more easily explain
the benefit of encasing it in quotemarks. If you redirect to a file that
has spaces in its name, or if there are spaces in the path specification
itself, then the filename *must* be quoted to protect the spaces from
DOS's desire to use them as delimiters. (That's what all those
quotemarks in the Shell statement are for.) If the filename doesn't have
spaces in it, the quotes aren't necessary BUT they don't hurt either.
Hence, the above will work with either.

As for your PING question, something like the following should work:

strIP = "4.17.23.1"
Shell Environ$("comspec") & " /c ping " & _
strIP & " > """ & RedirectFile & """", vbHide

Although you didn't specify it in your original post, I assume you want
to use vbHide for the optional 2nd parameter to Shell. This hides the
DOS window so that your user doesn't see it. If you want the DOS window
to remain visible, you would use the vbNormalFocus BUT you must use a /k
instead of a /c for the command processor argument. Basically, the /c
tells the command processor "here comes a command and, when its finished
executing, close the DOS shell it is running in" whereas the /k also
tells the command processor that a command follows, but it instructs it
to leave the DOS session running.

The above assumes you do NOT have to wait for this file to be completely
written before your code continues executing. If you have to work with
this file right after it is created, consider one of these (which makes
your program wait until the DOS process is finished):

MICROSOFT 'S OFFICIAL WAY
========================
See this link

http://support.microsoft.com/suppor...s/Q129/7/96.asp

Note: This method doesn't use Shell -- it uses CreateProcessA.


FAST AND DIRTY METHOD (WORKS ALMOST ALL THE TIME)
========================================
=========
Paste these lines in the (General)(Declarations) section of the form
where the Shell is being called (or remove the Private keywords and put
them in a BAS module if more than one form will use them):

Private Declare Function OpenProcess _
Lib "kernel32" _
(ByVal dwDesiredAccess As Long, _
ByVal bInheritHandle As Long, _
ByVal dwProcessId As Long) As Long
Private Declare Function CloseHandle _
Lib "kernel32" _
(ByVal hObject As Long) As Long
Private Declare Function WaitForSingleObject _
Lib "kernel32" _
(ByVal hHandle As Long, _
ByVal dwMilliseconds As Long) As Long

Call your Shell command in this form with the appropriate Shell
arguments placed in the parentheses:

PID = Shell( <<Put Shell Arguments Here>> )

And finally, paste the following IMMEDIATELY after the PID=Shell
statement above (making sure to handle the possible error where
indicated; i.e. stop the code from falling through to your other
commands if the Shell failed):

If PID = 0 Then
'
'Handle Error, Shell Didn't Work
'
Else
hProcess = OpenProcess(&H100000, True, PID)
WaitForSingleObject hProcess, -1
CloseHandle hProcess
End If

Capp

2005-03-24, 3:59 am

So would I use it like this?:
Shell Environ$("comspec") & "echo y| cacls c:\Progra~1\Folder /D
Everyone"
I have tried it and does not work.

I tried without the "echo y|" and it did not work either
This is very new to me for I am used to doing database work, so bear with me
:)

Thanks



"Rick Rothstein" wrote:

> but I am
> but I
> vb.
>
> ECHO is an internal DOS command and, as such, requires the command
> processor be specified. The following is a compilation of several posts
> I've given in the past regarding the Shell command. The use of the
> command processor is covered in the opening paragraph; the remainder is
> for your consideration.
>
> Rick -MVP
>
> You can use the Shell command. To execute internal DOS command (Dir,
> Copy, etc. as well as redirection of screen output), the command
> processor must be specified (using the Environ$ function and "comspec"
> as its argument returns the correct command processor path on NT and
> non-NT systems) . Specifying the command processor is safe & generic and
> will work with non-internal commands also. That syntax, using an XCopy
> command as an example is:
>
> Shell Environ$("comspec") & " /c xcopy """ & _
> Source & """ """ & Destination & """ " & Option, vbHide
>
> You set the Source and Desination (string variables) to the appropriate
> paths and the Option (string variable), if any, which can be found by
> opening an MSDOS Prompt window and typing xcopy /?. (Note: You can type
> /? after any DOS command at a DOS prompt to list the available options
> for that command.) One more example would be to list all the files in a
> directory including subdirectories and subdirectories of subdirectories
> and all of their files.
>
> CommandLine = "dir """ & FileSpec & _
> """ /s/b > """ & RedirectTo & """"
> Shell Environ$("comspec") & " /c " & CommandLine, vbHide
>
> Here, the output of a Dir command is redirected to a file-path you
> specify in the RedirectTo (string variable). The /s/b are options to the
> Dir command that tell it to recurse throught its subdirectories and not
> to include header or summary information.
>
> I used a variable for the file name so that I could more easily explain
> the benefit of encasing it in quotemarks. If you redirect to a file that
> has spaces in its name, or if there are spaces in the path specification
> itself, then the filename *must* be quoted to protect the spaces from
> DOS's desire to use them as delimiters. (That's what all those
> quotemarks in the Shell statement are for.) If the filename doesn't have
> spaces in it, the quotes aren't necessary BUT they don't hurt either.
> Hence, the above will work with either.
>
> As for your PING question, something like the following should work:
>
> strIP = "4.17.23.1"
> Shell Environ$("comspec") & " /c ping " & _
> strIP & " > """ & RedirectFile & """", vbHide
>
> Although you didn't specify it in your original post, I assume you want
> to use vbHide for the optional 2nd parameter to Shell. This hides the
> DOS window so that your user doesn't see it. If you want the DOS window
> to remain visible, you would use the vbNormalFocus BUT you must use a /k
> instead of a /c for the command processor argument. Basically, the /c
> tells the command processor "here comes a command and, when its finished
> executing, close the DOS shell it is running in" whereas the /k also
> tells the command processor that a command follows, but it instructs it
> to leave the DOS session running.
>
> The above assumes you do NOT have to wait for this file to be completely
> written before your code continues executing. If you have to work with
> this file right after it is created, consider one of these (which makes
> your program wait until the DOS process is finished):
>
> MICROSOFT 'S OFFICIAL WAY
> ========================
> See this link
>
> http://support.microsoft.com/suppor...s/Q129/7/96.asp
>
> Note: This method doesn't use Shell -- it uses CreateProcessA.
>
>
> FAST AND DIRTY METHOD (WORKS ALMOST ALL THE TIME)
> ========================================
=========
> Paste these lines in the (General)(Declarations) section of the form
> where the Shell is being called (or remove the Private keywords and put
> them in a BAS module if more than one form will use them):
>
> Private Declare Function OpenProcess _
> Lib "kernel32" _
> (ByVal dwDesiredAccess As Long, _
> ByVal bInheritHandle As Long, _
> ByVal dwProcessId As Long) As Long
> Private Declare Function CloseHandle _
> Lib "kernel32" _
> (ByVal hObject As Long) As Long
> Private Declare Function WaitForSingleObject _
> Lib "kernel32" _
> (ByVal hHandle As Long, _
> ByVal dwMilliseconds As Long) As Long
>
> Call your Shell command in this form with the appropriate Shell
> arguments placed in the parentheses:
>
> PID = Shell( <<Put Shell Arguments Here>> )
>
> And finally, paste the following IMMEDIATELY after the PID=Shell
> statement above (making sure to handle the possible error where
> indicated; i.e. stop the code from falling through to your other
> commands if the Shell failed):
>
> If PID = 0 Then
> '
> 'Handle Error, Shell Didn't Work
> '
> Else
> hProcess = OpenProcess(&H100000, True, PID)
> WaitForSingleObject hProcess, -1
> CloseHandle hProcess
> End If
>
>

Rick Rothstein

2005-03-24, 3:59 am

> So would I use it like this?:
> Shell Environ$("comspec") & "echo y| cacls c:\Progra~1\Folder

/D
> Everyone"
> I have tried it and does not work.


You did not leave a separating blank space in front of the command word
"echo". Also, I always put the /c or /k command directive for the
command processor. So, assuming you want your users to see what is in
the Command window, this is what I try.

Shell Environ$("comspec") & " /k echo y | cacls c:\Progra~1\Folder /D
Everyone"

Note that there is a space in front of the /k. By the way, whenever you
are having trouble getting a string argument to a function to work
properly, you can always trying using Debug.Print in place of the
function call to see what the string argument really looks like. Do this
would for your original attempt would have printed out this

C:\WINDOWS\system32\cmd.exeecho y| cacls c:\Progra~1\Folder /D Everyone

(on my WinXP system, your command processor executable name might be
different depending on what Windows version you are running) and you
would have noticed the extension for the command processor program was
screwed up. This wouldn't have caught the missing /k, but it would ruled
out the main problem for you.

Rick - MVP

Capp

2005-03-24, 4:02 pm

Hey Rick
Still having some problems. This is what I have now:

Shell Environ$("comspec") & " /c echo y| cacls c:\Progra~1\Yahoo!\Messenger
/D Everyone """

When I copy and past everything between quotes into cmd prompt..it works
just fine. I don't get any errors when run in VB, just does not do anything.

Thank you for all your help.

"Rick Rothstein" wrote:

> /D
>
> You did not leave a separating blank space in front of the command word
> "echo". Also, I always put the /c or /k command directive for the
> command processor. So, assuming you want your users to see what is in
> the Command window, this is what I try.
>
> Shell Environ$("comspec") & " /k echo y | cacls c:\Progra~1\Folder /D
> Everyone"
>
> Note that there is a space in front of the /k. By the way, whenever you
> are having trouble getting a string argument to a function to work
> properly, you can always trying using Debug.Print in place of the
> function call to see what the string argument really looks like. Do this
> would for your original attempt would have printed out this
>
> C:\WINDOWS\system32\cmd.exeecho y| cacls c:\Progra~1\Folder /D Everyone
>
> (on my WinXP system, your command processor executable name might be
> different depending on what Windows version you are running) and you
> would have noticed the extension for the command processor program was
> screwed up. This wouldn't have caught the missing /k, but it would ruled
> out the main problem for you.
>
> Rick - MVP
>
>

Rick Rothstein

2005-03-24, 4:02 pm

What happens if your change the /c to a /k ?

And are there really 3 quote marks after the space after the word
"Everyone"... there should only be one.

Rick


"Capp" <Capp@discussions.microsoft.com> wrote in message
news:2E7AA9A0-0DF0-48E9-9D53-43C6AF59C042@microsoft.com...
> Hey Rick
> Still having some problems. This is what I have now:
>
> Shell Environ$("comspec") & " /c echo y| cacls

c:\Progra~1\Yahoo!\Messenger
> /D Everyone """
>
> When I copy and past everything between quotes into cmd prompt..it

works
> just fine. I don't get any errors when run in VB, just does not do

anything.[color=darkred]
>
> Thank you for all your help.
>
> "Rick Rothstein" wrote:
>
c:\Progra~1\Folder[color=darkred]
word[color=darkred]
in[color=darkred]
/D[color=darkred]
you[color=darkred]
this[color=darkred]
Everyone[color=darkred]
was[color=darkred]
ruled[color=darkred]

Capp

2005-03-24, 8:59 pm

It works!!, but the only problem is...it leaves the command prompt window open.
What can I do to make sure it closes it. I really don't want the users to
even see that the command prompt window was ever opened.

Thank you so much for your help



"Rick Rothstein" wrote:

> What happens if your change the /c to a /k ?
>
> And are there really 3 quote marks after the space after the word
> "Everyone"... there should only be one.
>
> Rick
>
>
> "Capp" <Capp@discussions.microsoft.com> wrote in message
> news:2E7AA9A0-0DF0-48E9-9D53-43C6AF59C042@microsoft.com...
> c:\Progra~1\Yahoo!\Messenger
> works
> anything.
> c:\Progra~1\Folder
> word
> in
> /D
> you
> this
> Everyone
> was
> ruled
>
>

Rick Rothstein

2005-03-24, 8:59 pm

Hmm! That was what the /c should have done for you. Maybe the extra
quote marks screwed it up. Now that you have a working line, try
changing the /k back to a /c and see what happens.

Rick - MVP


"Capp" <Capp@discussions.microsoft.com> wrote in message
news:E9364AE0-8067-4098-BD70-2BA8FCC60D0B@microsoft.com...
> It works!!, but the only problem is...it leaves the command prompt

window open.
> What can I do to make sure it closes it. I really don't want the users

to[color=darkred]
> even see that the command prompt window was ever opened.
>
> Thank you so much for your help
>
>
>
> "Rick Rothstein" wrote:
>
command[color=darkred]
the[color=darkred]
is[color=darkred]
c:\Progra~1\Folder[color=darkred]
whenever[color=darkred]
work[color=darkred]
the[color=darkred]
Do[color=darkred]
might be[color=darkred]
you[color=darkred]
program[color=darkred]
would[color=darkred]

Capp

2005-03-24, 8:59 pm

It Works!!

Thank You. It does exactly what I want it to.
Thank you again for all the help :)




"Rick Rothstein" wrote:

> Hmm! That was what the /c should have done for you. Maybe the extra
> quote marks screwed it up. Now that you have a working line, try
> changing the /k back to a /c and see what happens.
>
> Rick - MVP
>
>
> "Capp" <Capp@discussions.microsoft.com> wrote in message
> news:E9364AE0-8067-4098-BD70-2BA8FCC60D0B@microsoft.com...
> window open.
> to
> command
> the
> is
> c:\Progra~1\Folder
> whenever
> work
> the
> Do
> might be
> you
> program
> would
>
>

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com