Using Vault when no one is logged in
Moderator: SourceGear
The way the client is written, it looks up the Vault Profiles file based on the user process which created the process. Assuming that whatever is launching the Build script is logging in, and mapping the Special AppData folder to the one stored on disk, the profile should be found and used.
Is it possible there are any other Vault Profiles located on disk have Bruce for user information? I suppose not.
Does the information in your MSSCCPRJ.SCC files on disk match the server and repository id? You'll have to get the repository id from the database table, tblrepositories.?
If so, then I'm pretty much stumped, as the Vault IDE is logging in, and should be connecting to the correct repository, but seems to stop at this point.
Is it possible there are any other Vault Profiles located on disk have Bruce for user information? I suppose not.
Does the information in your MSSCCPRJ.SCC files on disk match the server and repository id? You'll have to get the repository id from the database table, tblrepositories.?
If so, then I'm pretty much stumped, as the Vault IDE is logging in, and should be connecting to the correct repository, but seems to stop at this point.
Jeff Clausius
SourceGear
SourceGear
Following is a small quick and dirty function which exhibits the same behavior as the full build program when run from the task scheduler when no one is logged on. Can you run this and see if you can duplicate my problem? Adjust the fopen and solution name as needed. The solution you use must be a source control-bound solution. When I run this while logged in, I get three lines in the output file. When run from the scheduler while not logged in, I only get the first line.
#include "stdafx.h"
#pragma warning( disable : 4278 )
#import "libid:80cc9f66-e7d8-4ddd-85b6-d9e6cd0e93e2" version("7.0") lcid("0") raw_interfaces_only named_guids
#pragma warning( default : 4278 )
using namespace EnvDTE;
void
Build()
{
CoInitializeEx(NULL, COINIT_MULTITHREADED);
FILE* f = fopen("e:\\log.txt", "w");
{
CComPtr<EnvDTE::_DTE> m_pDTE;
HRESULT hr = m_pDTE.CoCreateInstance(L"VisualStudio.DTE.7.1", 0, CLSCTX_ALL);
CComPtr<EnvDTE::_Solution> pDispSln;
m_pDTE->get_Solution(&pDispSln);
time_t t;
time(&t);
fprintf(f, "Before Open, t = %ld\n", t);
fflush(f);
_bstr_t st = "e:\\mm\\mminstall.sln";
hr = pDispSln->Open(st);
time(&t);
fprintf(f, "After Open, t = %ld\n", t);
fflush(f);
pDispSln->Close(FALSE);
time(&t);
fprintf(f, "After Close, t = %ld\n", t);
fflush(f);
}
fclose(f);
CoUninitialize();
}
#include "stdafx.h"
#pragma warning( disable : 4278 )
#import "libid:80cc9f66-e7d8-4ddd-85b6-d9e6cd0e93e2" version("7.0") lcid("0") raw_interfaces_only named_guids
#pragma warning( default : 4278 )
using namespace EnvDTE;
void
Build()
{
CoInitializeEx(NULL, COINIT_MULTITHREADED);
FILE* f = fopen("e:\\log.txt", "w");
{
CComPtr<EnvDTE::_DTE> m_pDTE;
HRESULT hr = m_pDTE.CoCreateInstance(L"VisualStudio.DTE.7.1", 0, CLSCTX_ALL);
CComPtr<EnvDTE::_Solution> pDispSln;
m_pDTE->get_Solution(&pDispSln);
time_t t;
time(&t);
fprintf(f, "Before Open, t = %ld\n", t);
fflush(f);
_bstr_t st = "e:\\mm\\mminstall.sln";
hr = pDispSln->Open(st);
time(&t);
fprintf(f, "After Open, t = %ld\n", t);
fflush(f);
pDispSln->Close(FALSE);
time(&t);
fprintf(f, "After Close, t = %ld\n", t);
fflush(f);
}
fclose(f);
CoUninitialize();
}
If I don't get to it tonight, I'll do it tomorrow.Jerry R wrote:Following is a small quick and dirty function which exhibits the same behavior as the full build program when run from the task scheduler when no one is logged on. Can you run this and see if you can duplicate my problem?
Jeff Clausius
SourceGear
SourceGear
OK. Here are some initial results from tonight:
1) Configured a auto-login / auto - profile for the Vault Server solution.
2) Opened the Vault Server solution. Set the check to turn off the dialog regarding the Vault IDE client version.
3) Closed and retried to open the solution. This time no dialog.
4) Next launched VaultServer.sln from the Start -> Run -> c:\dev\projects\vault\src\VaultServer.sln. Funny thing... I received the message regarding the Vault IDE client version, etc. Hmmm. Again, I marked this dialog to not to display.
5) Tried Start -> Run again. This time it worked as expected. Weird.
6) Next tried double clicking the Vault Server solution from windows explorer. Success
7) Built an app named testbuild.exe by modifying the code you provided.
8) Ran the app from within the IDE's build. Seemed to work correctly.
9) Launched testbuild.exe from Windows explorer. Again seemed to work correctly.
10) Next tried to schedule testbuild
at 21:45 c:\dev\testbuild\debug\testbuild.exe
tick... tick... tick... testbiuld started, but then hung.
11) removed the task, and rescheduled.
at 21:53 /interactive c:\dev\testbuild\debug\testbuild.exe
tick... tick... tick... Here's where it gets even more strange. The app launched in a console window. It then asked me to accept a certificate. Next it showed the dialog regarding the Vault IDE client's version. Next I started getting invalid user / password over and over again.
Did you try to interactively schedule the launch of the build?
1) Configured a auto-login / auto - profile for the Vault Server solution.
2) Opened the Vault Server solution. Set the check to turn off the dialog regarding the Vault IDE client version.
3) Closed and retried to open the solution. This time no dialog.
4) Next launched VaultServer.sln from the Start -> Run -> c:\dev\projects\vault\src\VaultServer.sln. Funny thing... I received the message regarding the Vault IDE client version, etc. Hmmm. Again, I marked this dialog to not to display.
5) Tried Start -> Run again. This time it worked as expected. Weird.
6) Next tried double clicking the Vault Server solution from windows explorer. Success
7) Built an app named testbuild.exe by modifying the code you provided.
8) Ran the app from within the IDE's build. Seemed to work correctly.
9) Launched testbuild.exe from Windows explorer. Again seemed to work correctly.
10) Next tried to schedule testbuild
at 21:45 c:\dev\testbuild\debug\testbuild.exe
tick... tick... tick... testbiuld started, but then hung.
11) removed the task, and rescheduled.
at 21:53 /interactive c:\dev\testbuild\debug\testbuild.exe
tick... tick... tick... Here's where it gets even more strange. The app launched in a console window. It then asked me to accept a certificate. Next it showed the dialog regarding the Vault IDE client's version. Next I started getting invalid user / password over and over again.
Did you try to interactively schedule the launch of the build?
Jeff Clausius
SourceGear
SourceGear
OK. Remember item #1 in this posting.
I created a little test app:
I then scheduled this :
I logged off my machine, and went to the kitchen for a soda.
Upon returning, I re-logged back into the machine and voila'... This test app was able to open and close the project.
c:\log.txt contained:
Hooray! I believe modification of that code should do the trick.
Now, assuming this does work, I need to issue a word of caution here.
The Vault IDE client is an interactive client. It displays dialogs on warnings and errors, or when it is requesting feedback on project locations / working folders / overwriting files etc.
While it looks as if this solution will enable your build script to run, you may encounter other problems down the road with unexpected dialogs.
For non-interactive use of the Vault server, I strongly recommend using the Vault Command Line client. It was specifically designed for this type of work.
Let me know if there's anything else I can do.
I created a little test app:
Code: Select all
#include <windows.h>
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hToken = NULL;
PSID pLoginSid = NULL;
PVOID pProfileBuffer = NULL;
DWORD dwProfLen = 0;
QUOTA_LIMITS ql;
::ZeroMemory(&ql, sizeof(ql));
int ret = 0;
if ( ::LogonUserEx(_T("jeffclausius"), _T("DOMAIN_OR_MACHINE"), _T("password"),
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
&hToken, &pLoginSid, &pProfileBuffer, &dwProfLen, &ql ) != 0 )
{
STARTUPINFO si;
::GetStartupInfo(&si);
PROCESS_INFORMATION pi;
::ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
if ( ::CreateProcessAsUser( hToken, NULL,
_T("c:\\dev\\Research\\testbuild\\Debug\\testbuild.exe"),
NULL, NULL, TRUE, 0, NULL,
NULL, &si, &pi ) == 0 )
{
_tprintf( _T("CreateProcessAsUser - Error = %d\n"), ::GetLastError() );
ret = 2;
}
}
else
{
_tprintf( _T("LogonUserEx - Error = %d\n"), ::GetLastError() );
ret = 1;
}
return ret;
}
Code: Select all
at 22:57 c:\dev\research\starttestbuild\debug\starttestbuild.exe
Upon returning, I re-logged back into the machine and voila'... This test app was able to open and close the project.
c:\log.txt contained:
Code: Select all
Before Open, t = 1094183822
After Open, t = 1094183874
After Close, t = 1094183875
Now, assuming this does work, I need to issue a word of caution here.
The Vault IDE client is an interactive client. It displays dialogs on warnings and errors, or when it is requesting feedback on project locations / working folders / overwriting files etc.
While it looks as if this solution will enable your build script to run, you may encounter other problems down the road with unexpected dialogs.
For non-interactive use of the Vault server, I strongly recommend using the Vault Command Line client. It was specifically designed for this type of work.
Let me know if there's anything else I can do.
Jeff Clausius
SourceGear
SourceGear
I never tried /interactive - I was unaware of this option. However, nevermind, since you seem to have found a workaround which I will try shortly.
Well, but the problem is that I don't want to run Vault at all (at least at this point) in my build program. I want to use Visual Studio to compile a solution that happens to have source control bindings. If it is possible to do this without invoking the Vault IDE Client, that would probably be an even better solution. Is there a way to do this without Studio complaining about missing source control stuff?For non-interactive use of the Vault server, I strongly recommend using the Vault Command Line client. It was specifically designed for this type of work.
Internally, we use a custom build script with perl. However, you could also use make or msbuild. Heck some people even use a batch file.
In any case, you can build w/ out launching vs.net from the command line using something like:
In any case, you can build w/ out launching vs.net from the command line using something like:
Code: Select all
devenv.exe Test.sln /build release /out build.log
Jeff Clausius
SourceGear
SourceGear
I should have said "is there any way to do this without rewriting our build program?" Right now, our build program uses the vs.net interface to get back error information and other stuff. If all we were doing was invoking the compiler, then it would be easy to switch to using devenv.exe or one of the other options you mentioned.
Anyway, I'll try the CreateProcessAsUser solution and hopefully that will work (thanks for the code).
Anyway, I'll try the CreateProcessAsUser solution and hopefully that will work (thanks for the code).
I honestly don't know. I have a suspicion since the COM component seems to launches VS.Net interactively, I believe any SCC IDE client is going to be initialized / started by this action.Jerry R wrote:I should have said "is there any way to do this without rewriting our build program?"
Jeff Clausius
SourceGear
SourceGear
I honestly don't know. I have a suspicion since the COM component seems to launches VS.Net interactively, any SCC IDE client is going to be initialized / started by this action.Jerry R wrote:I should have said "is there any way to do this without rewriting our build program?"
Jeff Clausius
SourceGear
SourceGear
Hmm, I'm getting an ERROR_PRIVILEGE_NOT_HELD on the CreateProcessAsUser call. I think I may have to wait until Tuesday to test this out, when the guy who knows more about security stuff is back in the office. Ah ha, this just became irrelevant - see next paragraph.
I played around with the AT command a little. It runs successfully both interactively and non-interactively when I'm logged in, but it seems to use a different vault profile than the task scheduler with vault starts up. So then I tried it while not logged in, and, holy crap!, the test program completed! So my first question was "how are the tasks scheduled by AT different from those scheduled inside the task manager?" Answer: under Run As, instead of my user name, it had "NT Authority\SYSTEM". So in my non-working scheduled task I changed Run As to NT..., and now the test program runs when not logged in, hooray!
Now I just have to try out the full build program, but I'm hopeful this should now work. I think we still don't know exactly why Vault hangs up when Run As is my user name and I'm not logged in, correct? But I'll leave that for you guys to worry about.
Btw, in re Vault IDE being interactive, there is a SuppressUI property of the DTE object, which we set to TRUE, but it seems like the Vault IDE client does not respect this (not that it would have helped in this case anyway).
I played around with the AT command a little. It runs successfully both interactively and non-interactively when I'm logged in, but it seems to use a different vault profile than the task scheduler with vault starts up. So then I tried it while not logged in, and, holy crap!, the test program completed! So my first question was "how are the tasks scheduled by AT different from those scheduled inside the task manager?" Answer: under Run As, instead of my user name, it had "NT Authority\SYSTEM". So in my non-working scheduled task I changed Run As to NT..., and now the test program runs when not logged in, hooray!
Now I just have to try out the full build program, but I'm hopeful this should now work. I think we still don't know exactly why Vault hangs up when Run As is my user name and I'm not logged in, correct? But I'll leave that for you guys to worry about.
Btw, in re Vault IDE being interactive, there is a SuppressUI property of the DTE object, which we set to TRUE, but it seems like the Vault IDE client does not respect this (not that it would have helped in this case anyway).