Function as process

I am trying to get a program to work that starts robocopy.exe as a process, the problem I am running into is with the username used in the operation.  it seems that I cannot use this program on more then one computer.

With trial and error, I have gotten the process to work in a command line runas command with the /netonly flag.  but I am unsure how to do something similar with the function i have in my code.

Here is my code:

Imports System.Security

Module Module1

    Sub Main()

        Dim conConnection As New ADODB.Connection
        Dim cmdCommand As New ADODB.Command
        Dim rstRecordSet As New ADODB.Recordset

        conConnection.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
                "Data Source=\\SERVER\DATABASE.mdb;Mode=Read|Write"
        conConnection.CursorLocation = ADODB.CursorLocationEnum.adUseClient
        conConnection.Open()

        With cmdCommand
            .ActiveConnection = conConnection
            .CommandText = "SELECT * FROM TABLE;"
            .CommandType = ADODB.CommandTypeEnum.adCmdText
        End With

        With rstRecordSet
            .CursorType = ADODB.CursorTypeEnum.adOpenStatic
            .CursorLocation = ADODB.CursorLocationEnum.adUseClient
            .LockType = ADODB.LockTypeEnum.adLockOptimistic
            .Open(cmdCommand)
        End With

        If rstRecordSet.RecordCount <> 0 Then
            rstRecordSet.MoveFirst()

            Dim file As String
            file = "C:\robocopy.exe"

            Dim args As String
            args = "\\mje-imtmifile02\500div\Job_Files\5XXXXXXX-Template-New-Folders " & rstRecordSet.Fields(0).Value & " *.* /copyall /mir"
            Stop
            Dim username As String
            username = "USER"

            Dim pass As SecureString
            pass = Secure()

            Dim Dom As String
            Dom = "DOMAIN"

            Process.Start(file, args, username, pass, Dom)

        Else
            Exit Sub
        End If

    End Sub

    Public Function Start(fileName As String, arguments As String, userName As String, password As SecureString, domain As String) As Process
    End Function

    Public Function Secure() As SecureString
        Dim pass As String
        pass = "PASSWORD"
        Dim str As New SecureString
        For x As Integer = 0 To pass.Length - 1
            str.AppendChar(pass.Substring(x, 1))
        Next

        Return str
    End Function

End Module

Open in new window


The issue seems to be with my Start() function.  It seems to have to do with running a user across multiple computers.

any help would be appreciated.  or an alternative solution.
mjelecAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Bob LearnedCommented:
If this is a Console application, then you should be able to pass in user name and password on the command line.
mjelecAuthor Commented:
I have tried that with:

fileReader = My.Computer.FileSystem.ReadAllText("\\SERVER\test.txt")

testx = "runas /user:DOMAIN\USER " & Chr(34) & "\\SERVER\Template_New_Folders " & fileReader & " *.* /copyall /E" & Chr(34)
Dim objShell As Object
        objShell = CreateObject("Wscript.Shell")
        objShell.Run("cmd.exe")
        Thread.Sleep(1000)
        objShell.sendkeys(testx)
        Thread.Sleep(100)
        objShell.sendkeys("{enter}")
        Thread.Sleep(100)
        Dim pw As String = "Password"
        Dim i, n As Integer
        i = pw.Length
        n = 0
        Do While i > n
            Thread.Sleep(100)
            objShell.sendkeys(Mid(pw, n + 1, 1))
            n = n + 1
        Loop
        Thread.Sleep(100)
        objShell.sendkeys("{enter}")
        Thread.Sleep(100)

Open in new window


the issue with this is that if the command window loses focus then it types into whatever has focus.
Bob LearnedCommented:
May I ask what you are trying to achieve with this application?
Build an E-Commerce Site with Angular 5

Learn how to build an E-Commerce site with Angular 5, a JavaScript framework used by developers to build web, desktop, and mobile applications.

mjelecAuthor Commented:
I am trying to copy a folder structure that has preexisting permissions, in order to keep the permissions in place I need to run the robocopy command as an administrative account.  I am trying to create an application that allows for anyone to run the application while keeping the account details secure.

Now I dont know if robocopy is the best method, but its the only one I have found that will copy the folder permissions.
Bob LearnedCommented:
The Process StartInfo properties let you specify a user name and password when executing an external application, as shown in this example:

How to Launch an external process from a .NET program
http://galratner.com/blogs/net/archive/2009/04/26/how-to-launch-an-external-process-from-a-net-program.aspx

if (!string.IsNullOrEmpty(userName))
   processStartInfo.UserName = userName;

if (!string.IsNullOrEmpty(password))
{
      processStartInfo.Password = new System.Security.SecureString();
      char[] passwordChars = password.ToCharArray();
 
      foreach (char c in passwordChars)
          processStartInfo.Password.AppendChar(c);
}

Open in new window

mjelecAuthor Commented:
alright, before i start down another path again, do you know if this will let multiple users use the same credentials?  In my original code it would not allow this.
Bob LearnedCommented:
I need to make sure that I understand what you mean by "same credentials".  I was thinking that you pass in the user name and password to the calling application as command line arguments, but it sounds like that is not exactly what you are looking for.
mjelecAuthor Commented:
I have an account setup with the proper administrative rights, the point is that i need to use that account for the process.

so far it seems like when I start the process it locks up that administrative account to my profile or something.  if i try to run the same process on another person's account it gives me errors.
Bob LearnedCommented:
Can you describe some typical use cases for this application?  If you are trying to hide credentials, then including them in an ASCII text file is not secure.  Passing them in as command line arguments is not secure, since someone would need to know the password.  

Do you really need to hide the credentials, as this is pretty difficult to achieve?
mjelecAuthor Commented:
The process should be like this:

1. User wants to create a job folder structure and enters the folder name and other relevant information.
2. User runs this executable that already contains the credentials of the administrative account.
3. executable runs robocopy as the administrative account to preserve the permissions of the template folders.  reading a database for the information provided by the user.

I am open to changing any of the steps, I just need the administrative account information to be out of the hands of the user.
Bob LearnedCommented:
I am confused.  

If you include the administrative account information in the application, and pass it to the Process.StartInfo.UserName and Process.StartInfo.Password, it should open the process with those credentials.

You would need to use the non-shared (or non-static) form, as in this example:

Dim process As New Process()
process.StartInfo.FileName = fileName
process.StartInfo.UserName = userName
process.Password = New SecureString()

For Each (ch As Char in password.ToCharArray())
    process.StartInfo.Password.AppendChar(ch)
Next

process.Start()
mjelecAuthor Commented:
that works, the whole thing works, but when i try to run it on another computer, it crashes.


An unhandled exception of type 'System.InvalidCastException' occurred in ConsoleApplication3.exe

Additional information: Unable to cast COM object of type 'ADODB.ConnectionClass' to interface type 'ADODB.Connection'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{00001550-0000-0010-8000-00AA006D2EA4}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).


I assumed it had to do with a user credential thing because when i was using the runas command in command prompt i needed to use the /netonly flag to get it to work on another computer.
Bob LearnedCommented:
That is a completely different problem.  That sounds like a mismatch between the ADODB versions installed on each computer.

Look at the file version for msado15.dll.  That file is in the C:\Program Files\Common Files\System\ado folder for me.

I have Windows 7, and the file version is 6.1.7601.17514.
mjelecAuthor Commented:
Alright that has been resolved, but another error is happening:


An unhandled exception of type 'System.ComponentModel.Win32Exception' occurred in System.dll

Additional information: The directory name is invalid


When I break it is on the Process.Start(file, args, username, pass, Dom).

When I have that user put his own credentials in the executable it works.  but when he tries using the credentials of the administrative account it errors out.
Bob LearnedCommented:
The administrative account should have access rights to that folder, but you need to validate that assumption.
mjelecAuthor Commented:
yes, it does.  the problem is that i can run this program with the admin account on my computer, but when it runs on another computer it then errors out, the identical code.  but if we change the credentials in the code for the actual users credentials it works.  but it does not copy the permissions.

So the issue seems to be that the administrative credentials are locked to my credentials or something.

We fixed this issue using the runas command in command prompt with the /netonly flag.  but with this process.start function i cant seem to find a solution.
Bob LearnedCommented:
Where is this application running from on the other computer?  Is it running from a network share, or the local machine?

What is the operating system for the target machine?
mjelecAuthor Commented:
We are both running win 7 64x SP1.  the application is to be run from the users C:.
Bob LearnedCommented:
That sounds like you need to embed a manifest for UAC, since you have Windows 7.

Create and Embed an Application Manifest with Your Application
http://msdn.microsoft.com/en-us/library/bb756929.aspx

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.