InstallShield: How to create logs?

  • How to create logs for InstallShield executable?
  1. Open command-line
  2. Goto to your InstallShield executable folder (executable created in InstallShield)
  3. Run this line (i.e. to create logs in c:\temp folder):
    “<Your-InstallShield-Executable>.exe” /debuglog”C:\temp\setupexe.log” /V”/L*v c:\temp\SetupMSI.log”

console

Good luck 🙂

InstallShield: How to separate string by token

  • How to separate string by token? (for example doing so in myMethod)
function myMethod(hMSI)
   LIST versionList;
   STRING res1, nvItem;
   STRING firstVersionNUmber, secondVersionNumber, thirdItem;
   NUMBER n, nResult;
begin
   versionList = ListCreate(STRINGLIST);

   firstVersionNUmber = "";
   secondVersionNumber = "";
   thirdItem = "";

   StrGetTokens(versionList, "2.18.149", ".");
   n = ListCount(versionList);

   if (n == 3) then
      MessageBox("3 items", INFORMATION);
   else
      MessageBox("not 3 items", INFORMATION);
   endif;

   // Get the first number from the list.
   nResult = ListGetFirstString (versionList, firstVersionNUmber);

   // Get the second number from the list.
   if (nResult != END_OF_LIST) then
      nResult = ListGetNextString (versionList, secondVersionNumber);
   endif;

   // Get the third number from the list.
   if (nResult != END_OF_LIST) then
      nResult = ListGetNextString (versionList, thirdItem);
   endif;
   MessageBox("First item = " + firstVersionNUmber, INFORMATION);
   MessageBox("Second item = " + secondVersionNumber, INFORMATION);
   MessageBox("Third item = " + thirdItem, INFORMATION);

   if (firstVersionNUmber == "2" && secondVersionNumber == "18" 
        && thirdItem == "149") then
      MessageBox("Version is 2.18.149", INFORMATION);
   endif;

end;

InstallShield: How to read write delete registry key?

InstallShield: How to read write delete registry key?

Read from registry  (key value of  company_name):
function readFromRegistry(hMSI)
STRING isMajor;
STRING isMinor;
STRING netBios;
STRING szUninstallKey;
STRING szKey, szName, svValue, szMsg, strOurVersion;
STRING szNumName, szNumValue, svNumValue, TITLE, svTargetVer, szPropertyValue;
INT nvType, nvSize, nType, nSize, numSize, nResult;
begin
nvSize= 256;
REGDB_OPTIONS = REGDB_OPTIONS | REGDB_OPTION_WOW64_64KEY;
RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE) ;
RegDBGetKeyValueEx(szKey, szName, nvType, svValue, nvSize);
if (RegDBGetKeyValueEx "SOFTWARE\\COMPANYNAME\\PRODUCTNAME",   "company_name", nvType, svNumValue,
nvSize) < 0) then
//Failed
else
//Success;
endif;
end;

Write to registry (i.e. only write during upgrade I_Am_Upgrading key with value “True”):
function WriteUpgradeRegistry(hMSI)
STRING isMajor;
STRING isMinor;
STRING netBios;
STRING szUninstallKey;
STRING szKey, szName, svValue, szMsg, strOurVersion;
STRING szNumName, szNumValue, svNumValue, TITLE, svTargetVer, szPropertyValue;
INT nvType, nvSize, nType, nSize, numSize, nResult;
begin
nvSize= 256;
MsiGetProperty(hMSI, "IS_MAJOR_UPGRADE", isMajor, nvSize);
MsiGetProperty(hMSI, "IS_MINOR_UPGRADE", isMinor, nvSize);
REGDB_OPTIONS = REGDB_OPTIONS | REGDB_OPTION_WOW64_64KEY;
RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE) ;
RegDBGetKeyValueEx(szKey, szName, nvType, svValue, nvSize);
if(isMajor == "1" || isMinor == "1") then
if (RegDBSetKeyValueEx ("SOFTWARE\\COMPANYNAME\\PRODUCTNAME",   "I_Am_Upgrading",
REGDB_STRING, "True",-1) < 0) then
//Failed
else
//Success
endif;
endif;
end;

Remove Key from registry:
function RemoveRegistryKey(hMSI)
STRING isMajor;
STRING isMinor;
STRING netBios;
STRING szUninstallKey;
STRING szKey, szName, svValue, szMsg, strOurVersion;
STRING szNumName, szNumValue, svNumValue, TITLE, svTargetVer, szPropertyValue;
INT nvType, nvSize, nType, nSize, numSize, nResult;
begin
nvSize= 256;
REGDB_OPTIONS = REGDB_OPTIONS | REGDB_OPTION_WOW64_64KEY;
RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE) ;
RegDBGetKeyValueEx(szKey, szName, nvType, svValue, nvSize);

if (RegDBDeleteValue (“SOFTWARE\\COMPANYNAME\\PRODUCTNAME”,   “I_Am_Upgrading”) < 0) then
//Failed
else
//Success
endif;
end;

 

Android: Add Date-picker and Time-picker to your app

 

  • How to add Date-picker and Time-picker to your app? 

MainActivity:

<Your package name>

import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.TimePickerDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.TextView;
import android.widget.TimePicker;

import java.util.Calendar;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

final int DATE_PIC_DIALOG = 999;
final int TIME_PIC_DIALOG = 998;
Button modifyDateBtn, modifyTimeBtn;
TextView dateLbl, timeLbl;
int year, month, day;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

modifyDateBtn = (Button)findViewById(R.id.datePickBtn);
modifyDateBtn.setOnClickListener(this);
dateLbl = (TextView)findViewById(R.id.dateLbl);

Calendar calendar = Calendar.getInstance();
year = calendar.get(Calendar.YEAR);
month = calendar.get(Calendar.MONTH);
day = calendar.get(Calendar.DAY_OF_MONTH);

modifyTimeBtn = (Button)findViewById(R.id.timePickBtn);
modifyTimeBtn.setOnClickListener(this);
timeLbl = (TextView)findViewById(R.id.timeLbl);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}

@Override
public void onClick(View v)
{
if (v.getId() == R.id.datePickBtn)
{
showDialog(DATE_PIC_DIALOG);
}
else if (v.getId() == R.id.timePickBtn)
{
showDialog(TIME_PIC_DIALOG);
}
}

private DatePickerDialog.OnDateSetListener myDateListener = new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker arg0, int arg1, int arg2, int arg3) {
dateLbl.setText(new StringBuilder().append(arg3).append(“/”)
.append(arg2+1).append(“/”).append(arg1));
day = arg3;
month = arg2 + 1;
year = arg1;
}
};

private TimePickerDialog.OnTimeSetListener myTimeListener = new TimePickerDialog.OnTimeSetListener() {

@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
timeLbl.setText(new StringBuilder().append(String.format(“%02d”, hourOfDay)).append(“:”)
.append(String.format(“%02d”, minute)));
}
};

@Override
protected Dialog onCreateDialog(int id) {
if (id == DATE_PIC_DIALOG) {
return new DatePickerDialog(this, myDateListener, year, month, day);
}
else if (id == TIME_PIC_DIALOG) {
return new TimePickerDialog(this, myTimeListener, 21, 30, true);
}

return null;
}
}

activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

<LinearLayout
android:id=”@+id/dateLayout”
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”>
<TextView
android:id=”@+id/dateLbl”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”The Date”
/>

<Button
android:id=”@+id/datePickBtn”
android:layout_marginLeft=”100dp”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”Select Date”
/>
</LinearLayout>

<LinearLayout
android:id=”@+id/timeLayout”
android:layout_width=”fill_parent”
android:layout_below=”@id/dateLayout”
android:layout_marginTop=”20dp”
android:layout_height=”wrap_content”>
<TextView
android:id=”@+id/timeLbl”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”The Time”
/>

<Button
android:id=”@+id/timePickBtn”
android:layout_marginLeft=”100dp”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”Select Time”
/>
</LinearLayout>

</RelativeLayout>

InstallShield tips

  • Read\Write registry from script

Read:

export prototype MyMethod(HWND);

function MyMethod(hMSI)
STRING szUninstallKey;
STRING szKey, szName, svValue, szMsg, strOurVersion;
STRING szNumName, szNumValue, svNumValue, TITLE, svTargetVer, szPropertyValue;
INT nvType, nvSize, nType, nSize, numSize, nResult;
begin

REGDB_OPTIONS = REGDB_OPTIONS | REGDB_OPTION_WOW64_64KEY;
RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE) ;
RegDBGetKeyValueEx(szKey, szName, nvType, svValue, nvSize);

// Retrieve key value information.
if (RegDBGetKeyValueEx (“SOFTWARE\\MyCompany\\App”, “ProductVersion”, nvType, svNumValue,
nvSize) < 0) then
MessageBox(“Cannot read from registry”, SEVERE);
abort;
elseif (svNumValue != “2.18.509”) then
MessageBox(“Only support 2.18.509.”, SEVERE);
abort;
endif;
end;

Write:

REGDB_OPTIONS = REGDB_OPTIONS | REGDB_OPTION_WOW64_64KEY;
RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE) ;
RegDBCreateKeyEx( “SOFTWARE\\CRYPTOCard\\OWA”, “AllowXFrame” );
RegDBSetKeyValueEx( “SOFTWARE\\CRYPTOCard\\OWA”, “AllowXFrame”, REGDB_STRING, “1”, -1);

  • Stopping upgrade flag
  1. Go to Media > Upgrades
  2. Right window > Upgrade windows installer setup
  3. Most right window choose Disable
  4. This does not stop all upgrades!!! therefor see next section
  • Running custom action only on upgrade
  1. Create a custom command
  2. Install UI sequence = After find related products.
    Install UI condition = IS_MAJOR_UPGRADE OR IS_MINOR_UPGRADE
  3. In the function name enter MyMethod (see above)

if your custom action should block the upgrade choose Error custrom action and without script command only conditions

  • Changing files permission
  1. In General Information do not change the lock-down permissions to Custom!!! this makes tons of errors!!! stay with Traditional
  2. On Files and Folders right click your destination folder
  3. Choose permissions
  4. Give Administrators full permissions
  5. Give [USERSGROUP_AUTHENTICATED_USERS] limited permissions
  6. Give [USERGROUP_NETWORK_SERVICE] limited permissions
  • Adding checkbox for readme  at the end of a successfull installation
  1. Goto dialog SetupCompleteSuccess
  2. Create checkbox named CheckLaunchReadme
  3. Call its property LAUNCHREADME
  4. in the install-script add:
    • export prototype ShowReadme(HWND);
      function ShowReadme(hMSI)
      begin
      LaunchApplication( INSTALLDIR ^ “Configuration.html”, “”, “”, SW_SHOWDEFAULT, 0, LAAW_OPTION_NOWAIT | LAAW_OPTION_USE_SHELLEXECUTE );
      end;
  5. Add custom action : ShowReadme