Getting/setting a global variable in InstallShield - installshield

I have InstallScript code that executes a particular task. The task will either work or will not work. If the task works, I want to set a global variable to 1. If it does not work, I want to set a global variable to 0.
Somewhere down the line, I have another InstallScript code that executes. What I want is to check the global variable to see if it's 1. If it is, fire off that code.
I know that I can modify the Install Exec Condition, but what I do not know how to do is to check for a global variable. How I can accomplish this?

In an InstallScript project, merely create and set a global variable, and code against it as you please.
If instead you are asking in the context of an MSI with custom actions that run InstallScript, you have to use MSI Properties as your global variables. Call MsiSetProperty to set it, and write your custom action's condition against that property. Or call MsiGetProperty to retrieve it in your code and do the conditional execution there. Note that if the first action is in the UI sequence and the second is in the Execute sequence, you should add any properties you use to the SecureCustomProperties property.
To make this more concrete, your code might look like:
// Note: hInstall is the first parameter to your custom action
MsiSetProperty(hInstall, "RUN_SECOND_ACTION", "1");
and your condition in the custom action might be simply:
RUN_SECOND_ACTION

You can just declare a variable outside the function in .rul file, and the variable would be a global variable.
If you want to use the global variable in another .rul file, you have to include the rul file which declares the global variable.
ex.
/* featureevents.rul */
STRING globalVar; // declare a global variable
export prototype xxx_installed();
function xxx_installed()
STRING localVar; // declare a local variable
begin
end;
--
/* Setup.rul */
#include "featureevents.rul"
function OnFirstUIBefore()
begin
// use a global variable
globalVar="This is a global variable.";
MessageBox(globalVar, INFORMATION);
end;
I suggest you that add one or more resource header files, and put all the constants, global variables and function declaration in them.
/* featureevents.rul */
#include "CusRes.h"
...
--
/* Setup.rul */
#include "CusRes.h"
...
--
/* CusRes.h */
#ifndef _CUSRES_H_
#define _CUSRES_H_
// move the code to resource header file
STRING globalVar;
export prototype xxx_installed();
#endif //_CUSRES_H_
However, as Urman said, using property is a better way.
I miss the step of SecureCustomProperties, so I cannot get the value by MsiGetProperty() and use global variable instead.
But now I have got the information, and I'll also rewrite my code to use property instead.

Related

Does bc not limit a variable's scope?

Define the function in basic calculator bc as
define void f () { test=42; print "all done\n"; }
I'd have thought the value of test would be limited to the scope of the function f, but no, test equals 42 globally. Is there no way to limit the scope of variables in bc functions? I.e. is there are way to define local variables in bc?
You need to specify an AUTO_LIST in your function definition. From the bc manual,
`define' NAME `(' PARAMETERS `)' `{' NEWLINE
AUTO_LIST STATEMENT_LIST `}'
[...]
The AUTO_LIST is an optional list of variables that are for "local"
use. The syntax of the auto list (if present) is "`auto' NAME, ... ;".
(The semicolon is optional.) Each NAME is the name of an auto
variable. Arrays may be specified by using the same notation as used
in parameters. These variables have their values pushed onto a stack
at the start of the function. The variables are then initialized to
zero and used throughout the execution of the function. At function
exit, these variables are popped so that the original value (at the
time of the function call) of these variables are restored. The
parameters are really auto variables that are initialized to a value
provided in the function call. Auto variables are different than
traditional local variables because if function A calls function B, B
may access function A's auto variables by just using the same name,
unless function B has called them auto variables. Due to the fact that
auto variables and parameters are pushed onto a stack, `bc' supports
recursive functions.
So to keep the test variable "local" in your function, you'd use
define void f () { auto test; test=42; print "all done\n"; }

duktape, modify variable argument in native C code

I'm trying to modify a variable passed in an argument in a native function like this:
var MyVar = 'foo';
myNativeFunc(MyVar);
and inside my native, I can read the content of MyVar, with :
std::string(duk_to_string(ctx, 0));
but, I need to modify the value of this variable inside native function.
what is the best way for does it? (I can't use the return statement) thanks.
That's not possible as it would implement pass-by-reference (which is not supported in JS). Read also the answer to the question Pass Variables by Reference in Javascript
So, either pass in an object reference and change the object properties or use a return value.

How can i change property in InstallScript

I want to change property value to selected text in a dialog.
this is my sample source.
#include "ifx.h"
STRING outPath;
export prototype MyFunction(HWND);
function OnFirstUIBefore()
NUMBER nResult, nSetupType, nvSize, nUser;
STRING szTitle, szMsg, szQuestion, svName, svCompany, szFile, szDir;
STRING szLicenseFile;
BOOL bCustom, bIgnore1, bIgnore2;
begin
Dlg_SdAskDestPath:
nResult = SdAskDestPath(szTitle, szMsg, INSTALLDIR, 0);
if (nResult = BACK) goto Dlg_SdAskDestPath;
Dlg_AskOutPath:
nResult = AskDestPath(szTitle, szmsg, szDir, 0);
if (nResult = BACK) goto Dlg_SdAskDestPath;
outPath = szDir;
MyFunction(ISMSI_HANDLE);
return 0;
end;
function MyFunction(hMSI)
STRING value;
begin
MsiSetProperty(hMSI, "OutPutPath", outPath);
end;
OutPutPath used in custom action after finish install.
But OutPutPath was not changed when read in custom action.
I think I must not use ISMSI_HANDLE. But i don't know what i have to use instead.
I tried to make custom action which load Install scripts's method MyFunction after finish install.
It worked well, But the global variable outPath was nul..
Please teach me how can i do this if you know.
Thank you.
At a minimum, you must use a public property, that is one with a name that does not contain any lowercase letters. You may also have to list it in SecureCustomProperties in order to allow users to modify it, if you support installation in restricted environments.
However I'm not certain the exact scenario described by your comment:
I tried to make custom action which load Install scripts's method MyFunction after finish install.
If this scenario is truly after the end of the Windows Installer portion of the installation (an InstallScript MSI runs code both before and after), properties as a whole may not survive to do what you need. To support reading the value at that time you will have to consider other approaches, such as writing the value in the registry, or into a file (e.g. in SUPPORTDIR).

Pass String Variable to different forms within Access Database

I have a string variable assigned a value in Form1, but wish to use this variable (and the same value) in another form within the database (e.g. Form2).
How can this be achieved?
You could create a global variable.
Declare it outside any procedures at the top of Form1, like this:
Public strYourVariable as String
Now, once you have assigned a value to strYourVariable, it will be available in other modules and forms.
The global variables will be reset if you:
Use "End"
Get an unhandled error
Edit your VBA code
Close Access

I need to assign a value to a variable in some method as beforeRender, as I do?

I need to assign a value to a variable in some method as beforeRender, as I do?
(Sails.js v0.11.0)
Example CakePHP:
public function beforeRender(){
...
}
Example Rails:
before_render : ....
You can set locals in many places. It depends on your use case.
If the variable is different for each action, then you can place it inside the action calling the view.
If the variable is different for each request, then you can place it in a policy to set locals.
If the variable is static for a single route, you can put it in your routes.
If the variable is static for an application, then you can place in many places.
You can use Locals or Globals in your rendered view, which means any services you creates (even static objects) can be used inside your renderedViews
http://sailsjs.org/#!/documentation/concepts/Views/Locals.html
http://sailsjs.org/#!/documentation/concepts/Globals

Resources