GoToAssistant Remote Launcher - Build from sample c++ code

Completado Publicado Sep 30, 2008 Pagado a la entrega
Completado Pagado a la entrega

We are using GoToAssist for a support product. It is a window sharing application made by Citrix where we can remotely access a customers computer. When an end user wants support from us, we email them a generated url. They open this url in a web browser and the GoToAssist application is downloaded and run. There is the ability to launch a support session without having to open a web browser. This is done by building a c++ application where the webrequest and download is done automatically. The sample code is already made and available. We do not have the expertise to build it.

We will pay you for creating the exe application which will take in as parameter the question (which is the access code). All other hardcoded strings will be provided.

In the end, we will need a fully working exe. We prefer to have it built in Microsoft Visual Studio. We will also need documentation on how you got it setup and running in Microsoft Visual Studio.

Here is the sample code:

/* ******************************************************************

/* This app uses the strings defined to build a single URL and

/* launches it, then handles the HTML response, then finally

/* downloads the [url removed, login to view] and launches it. This is meant only

/* as an example of how you might implement an automated, browserless

/* launch of a GoToAssist session.

/*

/* This sample assumes that you are using the default SmartBox,

/* where the only required field is the Question.

/*

/* Note that the values will need to be encoded for use in a URL

/* more information about this can be found at the following URL.

/*

/* [url removed, login to view]

/*

/* And the RFC 1738 Standard for URL's

/*

/* [url removed, login to view]

/* *************************************************************** */

/*

/* Modification History

/* Date | Who | Reason

/* ---------------------------------------------------------------------------------

/* 5/10/05 Ryan G. Creation

/* 11/22/05 Bob D. Modified to display the End Page request URL

/* 2/8/06 Bob D. Removed the previous example of parsing the HTTP

/* responses and added the parsing of the comment tag

/* CUSTOMER_SURVEY_URL from the HTML.

*/

#include <iostream>

#include <fstream>

#include <string>

#include <shlwapi.h>

#include <iphlpapi.h> //For getHost

#include <wininet.h> //For getHost

using namespace std;

//Defining a BAILOUT macro for use in the app.

#define BAILOUT if(iNetSess) InternetCloseHandle(iNetSess);

if(httpConnection) InternetCloseHandle(httpConnection);

if(httpFile) InternetCloseHandle(httpFile);

return -1;

//Function declarations for later.

string getHost(void);

string getUser(void);

//This is the hostname of the broker.

//It will preceed the rest of the url string

string host = "broker.gotoassist.com";

//This is the form action, or the url to which your app should post.

//This shouldn't ever change, except for special circumstances.

//It can be found in the HTML of your SmartBox as the form action.

string action = "/servlet/dispatch/ds/queryPost.flow";

//This is the name of your Portal.

//It can be found in the HTML of your SmartBox in a hidden HTML

//form element named "Portal".

string portal = "";//Enter your portal name here.

//This is the name of your Template.

//It can be found in the HTML of your SmartBox in a hidden HTML

//form element named "Template".

string templ = "";//Enter your template name here.

//This is the name of your Form.

//It can be found in the HTML of your SmartBox in a hidden HTML

//form element named "Form".

string form = "";//Enter your form name here.

//This is the string you to enter into the SmartBox field "Question"

//You could use one of the functions below "getHost" or "getUser"

//this demonstrates how you might acquire data from the computer, or

//your application, and inject it into the generated URL.

string question = getUser();//Enter your question here.

/*****************************************************************

Note: Depending on how your portal is configured there could be

several other "required" fields which would be setup

by your account manager. An example of this might be the

Name_First, Name_Last, etc. fields. Make sure the required

fields have data in order for this automated process to work.

*****************************************************************/

//This function gets the hostname for this computer, and returns it

//as a string. It is intended to be used as the "question" value

//in the URL string.

string getHost(void)

{

FIXED_INFO * fixedInfo;

DWORD dwSize = NULL;

fixedInfo = (FIXED_INFO*)malloc(sizeof(FIXED_INFO) );

string retVal("");

if( GetNetworkParams( fixedInfo, &dwSize ) == ERROR_BUFFER_OVERFLOW )

{

if( fixedInfo )

{

delete fixedInfo;

fixedInfo = NULL;

}

fixedInfo = (FIXED_INFO*)malloc(dwSize);

}

if( GetNetworkParams( fixedInfo, &dwSize ) == NO_ERROR )

{

char buf[128];

DWORD dwOutputSize = 128;

if(!InternetCanonicalizeUrl( fixedInfo->HostName, buf, &dwOutputSize, NULL ))

{

MessageBox(NULL, "Unable to format URL. Quitting", "G2AQuickLaunch", MB_OK | MB_ICONERROR );

return "Error";

}

retVal = buf;

}

if( fixedInfo )

{

delete fixedInfo;

fixedInfo = NULL;

}

return retVal;

}

//This function gets the name of the currently logged on user and

//returns it as a string. It is intended to be used as the "question"

//value in the URL string.

string getUser(void)

{

char buf[128];

char retBuf[128];

string retVal("");

DWORD dwOutputSize = 128;

DWORD dwBufSize = 128;

if(!GetUserName(buf, &dwBufSize))

{

MessageBox(NULL, "Unable to determine Username.", "Error", MB_OK | MB_ICONERROR);

return "Error";

}

InternetCanonicalizeUrl( buf, retBuf, &dwOutputSize, NULL);

retVal = retBuf;

return retVal;

}

//The main loop

int main()

{

//Define Session ID and query key strings

string sessID, qKey;

string response; // Used to capture response

//Create the request URL using the variables defined above.

string URL = action;

URL += "?Portal=";

URL += portal;

URL += "&Template=";

URL += templ;

URL += "&Form=";

URL += form;

URL += "&Question=";

URL += question;

string URLsav = URL; // Save for use later

//Declare some variables to be used througout the file.

HINTERNET iNetSess = NULL;

HINTERNET httpConnection = NULL;

HINTERNET httpFile = NULL;

//Start an internet session and bail out if it fails.

iNetSess = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );

if(!iNetSess)

{

cout << "Unable to open an internet connection. Goodbye." << endl;

BAILOUT;

}

//Connect to the broker and bail out if it fails.

httpConnection = InternetConnect(iNetSess, host.c_str(), INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, NULL );

if(!httpConnection)

{

cout << "Unable to connect to requested host. Goodbye." << endl;

BAILOUT;

}

//Setup the types of http data we'll accept

LPCTSTR acceptTypes[2];

acceptTypes[0] = "*/*";

acceptTypes[1] = NULL;

//This loop makes the request, and refreshes it every 15 seconds, just like the automatic download flow.

while (true)

{

// Un-comment output line to see actual request

//cout << "HTTP Req: " << URL.c_str() << "n" << endl;

//Prepare the request and bail out if it fails.

httpFile = HttpOpenRequest(httpConnection, NULL, URL.c_str(), NULL, NULL, acceptTypes, INTERNET_FLAG_RELOAD |

INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_IGNORE_CERT_CN_INVALID |

INTERNET_FLAG_IGNORE_CERT_DATE_INVALID | INTERNET_FLAG_SECURE, 0);

if(!httpFile)

{

cout << "Unable to process document request. Goodbye." << endl;

BAILOUT;

}

//Send the request to the broker, and bail out if it fails.

if(!HttpSendRequest(httpFile, NULL, 0, NULL, 0 ))

{

cout << "Unable to send document request. Goodbye." << endl;

BAILOUT;

}

//Check the type of response we got and bail out if it fails.

TCHAR contentType[128];

DWORD dwContentTypeSize = 128;

if( !HttpQueryInfo(httpFile, HTTP_QUERY_CONTENT_TYPE, contentType, &dwContentTypeSize, 0 ) )

{

cout << "Unable to determine content type. Goodbye." << endl;

BAILOUT;

}

char readBuf[1024];

DWORD dwReadBufSize = 1024;

DWORD dwBytesRead = 0;

//If the response is a file, save it as chatlink

//This will happen when the CHATLINK_URL has been captured, which happens below

if( strcmp(contentType, "application/octet-stream") == 0 )

{

ofstream outFile;

[url removed, login to view]("chatlink.exe", ios::trunc | ios::binary);

if(!outFile)

{

cout << "Unable to write internet data to disk file. Goodbye." << endl;

BAILOUT;

}

do

{

//Read a 1024 byte chunk and bail out if it fails.

if(!InternetReadFile(httpFile, readBuf, dwReadBufSize, &dwBytesRead))

{

cout << "Unable to read internet file. Goodbye." << endl;

BAILOUT;

}

//Write the 1024 byte chunk to the file

[url removed, login to view](readBuf, dwBytesRead);

if(!outFile)

{

cout << "Unable to write internet data to disk file. Goodbye." << endl;

BAILOUT;

}

} while (dwBytesRead);

//Close the file

[url removed, login to view]();

if(!outFile)

{

cout << "Unable to write internet data to disk file. Goodbye." << endl;

BAILOUT;

}

break;

} else {

//If the response is anything else, we're going to assume it's an HTML document

//and we want to parse it to determine if chatlink is ready to download.

// Response variable is used to capture the reply here. - RFD

do

{

//Read a 1024 byte chunk and bail out if it fails.

if(!InternetReadFile(httpFile, readBuf, dwReadBufSize, &dwBytesRead))

{

cout << "Unable to read internet file. Goodbye." << endl;

BAILOUT;

}

//Add the 1024 byte chunk to a string that we'll parse later.

response += readBuf;

} while (dwBytesRead);

//Check to see if the post failed, if so, bail out

if( [url removed, login to view]("QUERY_STATUS="NOT POSTED"") != string::npos )

{

cout << "Query not posted. May not be an agent logged in. Goodbye." << endl;

BAILOUT;

}

//Check to see if chatlink is ready for download. If so, change the URL for the

//next iteration of this loop to download the [url removed, login to view]

if( [url removed, login to view]("CHATLINK_URL=") != string::npos )

{

string::size_type foundChar = 0;

string::size_type urlBegin = 0;

string::size_type urlEnd = 0;

foundChar = [url removed, login to view]("CHATLINK_URL");

urlBegin = [url removed, login to view]('"', foundChar);

urlBegin++;

urlEnd = [url removed, login to view]('"', urlBegin);

URL = [url removed, login to view](urlBegin, (urlEnd-urlBegin));

// Un-comment to see the URL string value

//cout << "The URL is: " << endl << URL.c_str() << "n" << endl; //-RFD

continue;

}

}

//Wait 15 seconds till the next iteration

Sleep(15000);

}

//If the the chatlink exists, launch it.

if( PathFileExists("chatlink.exe") )

ShellExecute(NULL, "open", "chatlink.exe", NULL, NULL, SW_SHOWNA);

//Wait 5 seconds then issue request to broker

Sleep(5000);

// Use the original URL to obtain the CUSTOMER_SURVEY_URL

URL = URLsav;

// This loop refreshes it every 5 seconds

while (true)

{

//Prepare the request and bail out if it fails.

httpFile = HttpOpenRequest(httpConnection, NULL, URL.c_str(), NULL, NULL, acceptTypes, INTERNET_FLAG_RELOAD |

INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_IGNORE_CERT_CN_INVALID |

INTERNET_FLAG_IGNORE_CERT_DATE_INVALID | INTERNET_FLAG_SECURE, 0);

if(!httpFile)

{

cout << "Unable to process document request. Goodbye." << endl;

BAILOUT;

}

//Send the request to the broker, and bail out if it fails.

if(!HttpSendRequest(httpFile, NULL, 0, NULL, 0 ))

{

cout << "Unable to send document request. Goodbye." << endl;

BAILOUT;

}

//Check the type of response we got and bail out if it fails.

TCHAR contentType[128];

DWORD dwContentTypeSize = 128;

if( !HttpQueryInfo(httpFile, HTTP_QUERY_CONTENT_TYPE, contentType, &dwContentTypeSize, 0 ) )

{

cout << "Unable to determine content type. Goodbye." << endl;

BAILOUT;

}

char readBuf[1024];

DWORD dwReadBufSize = 1024;

DWORD dwBytesRead = 0;

// Response variable is used to capture the reply here. - RFD

response = "";

do

{

//Read a 1024 byte chunk and bail out if it fails.

if(!InternetReadFile(httpFile, readBuf, dwReadBufSize, &dwBytesRead))

{

cout << "Unable to read internet file. Goodbye." << endl;

BAILOUT;

}

//Add the 1024 byte chunk to a string that we'll parse later.

response += readBuf;

} while (dwBytesRead);

//Check to see if the post failed, if so, bail out

if( [url removed, login to view]("QUERY_STATUS="NOT POSTED"") != string::npos )

{

cout << "Query not posted. May not be an agent logged in. Goodbye." << endl;

BAILOUT;

}

// Look for the CUSTOMER_SURVEY_URL and extract the URL

if( [url removed, login to view]("CUSTOMER_SURVEY_URL=") != string::npos )

{

string::size_type foundChar = 0;

string::size_type urlBegin = 0;

string::size_type urlEnd = 0;

foundChar = [url removed, login to view]("CUSTOMER_SURVEY_URL");

urlBegin = [url removed, login to view]('"', foundChar);

urlBegin++;

urlEnd = [url removed, login to view]('"', urlBegin);

URL = [url removed, login to view](urlBegin, (urlEnd-urlBegin));

// Display the End Page URL string value

cout << "The End Page URL is:" << endl << "https://broker.gotoassist.com" << URL.c_str() << "n" << endl; //-RFD

break;

}

//Wait 5 seconds till the next iteration

Sleep(5000);

}

cout << endl << "Enter a character and press return to continue:" << endl;

char buf[4];

memset(&buf,0,sizeof(char)*4);

cin >> buf;

return 0;

}

Programación en C

Nº del proyecto: #322598

Sobre el proyecto

9 propuestas Proyecto remoto Activo Oct 2, 2008

Adjudicado a:

smason1000

Please see PMB for details

$400 USD en 3 días
(1 comentario)
3.2

9 freelancers están ofertando un promedio de $383 por este trabajo

Shot

Experience of programming on various versions of C 20+ years. Wide experience of development of client-server systems.

$750 USD en 20 días
(8 comentarios)
5.8
usamacpp

Hi I tried to compile it under MS VC++ ver 6.0. it doesn't compile correctly. Here what i can do, I can rebuild it from scratch with help from your current code. Best. Usama.

$500 USD en 10 días
(14 comentarios)
5.2
maurya19

Pls check PM

$400 USD en 2 días
(7 comentarios)
4.1
Belxjander

I will be using the Visual Studio Express edition, as available for free from MS and I can provide documentation of setup with the Vista Platform DevKit Thanks in advance for your consideration. Jeremy

$420 USD en 4 días
(3 comentarios)
2.0
sigutis

Let me help.I am using visual c++ 2008 express edition.

$400 USD en 7 días
(6 comentarios)
1.6
AlexKiev

I can build Your application using C++Builder. I have experience with builder since 1999.

$480 USD en 6 días
(0 comentarios)
0.0
robace

I have Microsoft Visual Studio Professional edition, which has more functionality than Express or Builder. I also have experience creating instructional user documentation. See profile for level of experience.

$250 USD en 3 días
(0 comentarios)
0.0
letgodan

Hi! We ca do this project. Plase see PM

$300 USD en 3 días
(0 comentarios)
0.0