A
amdrit
Hello Everyone,
I have a C# component that is referenced by a VB6 standard executable. The
C# component has a method LaunchProcess that subsequently makes an API call
to CreateProcessWithLogonW in the advapi32 library. This is used to shell
open an external application such as Excel or Word with alternate
credentials than the logged in user.
I am encountering an issue where Excel and Word are initialized and show up
as processes for the impersonated user, but I am unable to interact with the
document. This only occurs in my target application, my stripped down test
application behaves as expected.
I am hoping someone has an idea of where to look. The calls are identical,
and only the target application has more bells and whistles on it.
I apologize if this post is rather large; I just wanted you all to have as
much information you needed. Again, this logic all works from a simple VB6
application (Form1, Button1_Click) and is giving me fits in the main
application. The main application has timers and back end processing going
at the same time. I figured having the document opened asynchronously would
be my redemption.
The functionality is new to the old VB6 application and new features are
implemented in .Net until everything is in .Net. I am fairly confident that
..Net is not my issue here. But who knows after spending three days solid on
this, I am not sure that I even have the correct API signature anymore.
In the VB6 code I have
[Reference to C# TLB]
Const DocumentName as string = \\uncpath\document.doc
Dim Executable as string * 255
Dim CleanExecutable as string
Dim i as Long
Dim objLauncher As DonNetCOM.Launcher
Set objLauncher = new DonNetCOM.Launcher
i = FindExecutable(DocumentName, "", Executable)
'Assuming FindExecutable always worked
CleanExecutable = TrimNulls(Executable)
Call objLauncher. CreateProcess("mydomain", "myusername", "mypassword",
CleanExecutable, DocumentName)
In C# code I have
[DllImport("advapi32.dll", SetLastError = true, CharSet =
CharSet.Unicode)]
private static extern bool CreateProcessWithLogonW(
String userName,
String domain,
String password,
UInt32 logonFlags,
String applicationName,
String commandLine,
UInt32 creationFlags,
UInt32 environment,
String currentDirectory,
ref StartupInfo startupInfo,
out ProcessInformation processInformation);
private class ProcessHelper
{
private string _domain; string _username; string _password; string _command;
string _commandLine; string _workDirectory;
public ProcessHelper(string domain; string username; string password; string
command; string commandLine
{
_username = username;
_password = password;
_domain = domain;
_command = command;
_commandLine = commandLine;
_workingDirectory = String.Empty;
}
Public void Launch()
{
StartupInfo startupInfo = new StartupInfo();
startupInfo.reserved = null;
startupInfo.flags &= Startf_UseStdHandles;
startupInfo.stdOutput = (IntPtr)StdOutputHandle;
startupInfo.stdError = (IntPtr)StdErrorHandle;
UInt32 exitCode = -1;
ProcessInformation processInfo = new ProcessInformation();
String paramaters = string.Format(" {0}", _commandLine);
String currentDirectory = this._workingDirectory;
bool epicFailure = false;
try
{
CreateProcessWithLogonW(
_username, _domain, _password, (UInt32)1,
_command, paramaters, (UInt32)0, (UInt32)0,
currentDirectory, ref startupInfo, out processInfo);
}
catch (Exception ex)
{
epicFailure = true;
throw ex;
}
Debug.WriteLine("Running ...");
WaitForSingleObject(processInfo.process, Infinite);
GetExitCodeProcess(processInfo.process, ref exitCode);
Debug.WriteLine("exitCode: " + exitCode.ToString());
CloseHandle(processInfo.process);
CloseHandle(processInfo.thread);
if (epicFailure == true)
{
throw new ApplicationException("Unable to create a new process.");
}
if (exitCode == -1)
{
throw new ApplicationException("Warehouse process didn't fire.
unknown error.");
}
//return true;
}
}
public void CreateProcess(string domain, string username, string password,
string command, string commandLine)
{
ProcessHelper lp = new ProcessHelper
(username,password,domain,command,commandLine);
Threading.ThreadStart ts = new Threading.ThreadStart(lp.Launch);
Threading.Thread t = new Threading.Thread(ts);
t.Start();
}
Thank you in advance
I have a C# component that is referenced by a VB6 standard executable. The
C# component has a method LaunchProcess that subsequently makes an API call
to CreateProcessWithLogonW in the advapi32 library. This is used to shell
open an external application such as Excel or Word with alternate
credentials than the logged in user.
I am encountering an issue where Excel and Word are initialized and show up
as processes for the impersonated user, but I am unable to interact with the
document. This only occurs in my target application, my stripped down test
application behaves as expected.
I am hoping someone has an idea of where to look. The calls are identical,
and only the target application has more bells and whistles on it.
I apologize if this post is rather large; I just wanted you all to have as
much information you needed. Again, this logic all works from a simple VB6
application (Form1, Button1_Click) and is giving me fits in the main
application. The main application has timers and back end processing going
at the same time. I figured having the document opened asynchronously would
be my redemption.
The functionality is new to the old VB6 application and new features are
implemented in .Net until everything is in .Net. I am fairly confident that
..Net is not my issue here. But who knows after spending three days solid on
this, I am not sure that I even have the correct API signature anymore.
In the VB6 code I have
[Reference to C# TLB]
Const DocumentName as string = \\uncpath\document.doc
Dim Executable as string * 255
Dim CleanExecutable as string
Dim i as Long
Dim objLauncher As DonNetCOM.Launcher
Set objLauncher = new DonNetCOM.Launcher
i = FindExecutable(DocumentName, "", Executable)
'Assuming FindExecutable always worked
CleanExecutable = TrimNulls(Executable)
Call objLauncher. CreateProcess("mydomain", "myusername", "mypassword",
CleanExecutable, DocumentName)
In C# code I have
[DllImport("advapi32.dll", SetLastError = true, CharSet =
CharSet.Unicode)]
private static extern bool CreateProcessWithLogonW(
String userName,
String domain,
String password,
UInt32 logonFlags,
String applicationName,
String commandLine,
UInt32 creationFlags,
UInt32 environment,
String currentDirectory,
ref StartupInfo startupInfo,
out ProcessInformation processInformation);
private class ProcessHelper
{
private string _domain; string _username; string _password; string _command;
string _commandLine; string _workDirectory;
public ProcessHelper(string domain; string username; string password; string
command; string commandLine

{
_username = username;
_password = password;
_domain = domain;
_command = command;
_commandLine = commandLine;
_workingDirectory = String.Empty;
}
Public void Launch()
{
StartupInfo startupInfo = new StartupInfo();
startupInfo.reserved = null;
startupInfo.flags &= Startf_UseStdHandles;
startupInfo.stdOutput = (IntPtr)StdOutputHandle;
startupInfo.stdError = (IntPtr)StdErrorHandle;
UInt32 exitCode = -1;
ProcessInformation processInfo = new ProcessInformation();
String paramaters = string.Format(" {0}", _commandLine);
String currentDirectory = this._workingDirectory;
bool epicFailure = false;
try
{
CreateProcessWithLogonW(
_username, _domain, _password, (UInt32)1,
_command, paramaters, (UInt32)0, (UInt32)0,
currentDirectory, ref startupInfo, out processInfo);
}
catch (Exception ex)
{
epicFailure = true;
throw ex;
}
Debug.WriteLine("Running ...");
WaitForSingleObject(processInfo.process, Infinite);
GetExitCodeProcess(processInfo.process, ref exitCode);
Debug.WriteLine("exitCode: " + exitCode.ToString());
CloseHandle(processInfo.process);
CloseHandle(processInfo.thread);
if (epicFailure == true)
{
throw new ApplicationException("Unable to create a new process.");
}
if (exitCode == -1)
{
throw new ApplicationException("Warehouse process didn't fire.
unknown error.");
}
//return true;
}
}
public void CreateProcess(string domain, string username, string password,
string command, string commandLine)
{
ProcessHelper lp = new ProcessHelper
(username,password,domain,command,commandLine);
Threading.ThreadStart ts = new Threading.ThreadStart(lp.Launch);
Threading.Thread t = new Threading.Thread(ts);
t.Start();
}
Thank you in advance