Stop the installation from a custom action - visual-studio

Is it possible to exit msi installar from a custom action without errors?
I am using visual studio setup project to create the msi and I have added a custom action exe to install. If I return a value other than 0 from exe it terminate the installation. But it shows an error. I need to exit installation without showing errors.
Thanks.

Finally I found a way to do it using a vbscript custom action from http://chensuping.blogspot.com/2013/05/windows-setup-project-vbs-custom-action.html.

Try this code in your installer class. I hope it will resolve your problem.
protected override void OnBeforeInstall(IDictionary savedState)
{
if (LaunchOnBeforeInstall())
{
base.OnBeforeInstall(savedState);
}
else
{
throw new Exception("You cancelled installation");
}
}
public bool LaunchOnBeforeInstall()
{
Form2 frm2 = new Form2();
DialogResult result = frm2.ShowDialog();
if (result == DialogResult.Cancel)
{
return false;
}
else
{
return true;
}
}
And also put "NOTPREVIOUSVERSIONSINSTALLED"

Related

E1740 lambda captured variable of type "..." cannot be copied to closure class field of type "..."

I have recently installed VS 2019 and opened up my project I created in VS 2017. The software works fine but there is a bug in VS with lambda captured variables. MS apparently is aware of said issue, but I was wondering if anyone else had come across this recently and if you have, have you managed to solve it?
Example bit of code from my project, the intellisense has flagged up every line where "[this]" appears. The error / bug reads
lambda captured variable of type "MainPage^*" cannot be copied to closure class field of type "MainPage^"
if (_serialPort1 != nullptr)
{
concurrency::create_task(WriteToSerialDeviceAsync(cancellationTokenSource_serialPort1->get_token(),
Arduino_Device.Outgoing_Bytes, PORT_1)).then([this](concurrency::task<void> previousTask) {
try
{
previousTask.get();
}
catch (Platform::COMException^ ex)
{
this->DataStreamWindow->Text += "\r\n!EXCEPTION CAUGHT! " + ex->Message;
}
});
}
Ok, I managed to stumble upon a somewhat ugly hack to fix this.
Rather than pass [this] into the lambda, I added the line auto _this = this; prior to creating any tasks. This did however mean that any variables which were accessed using this->SomeVariable became _this->SomeVariable.
So my example above now looks like this.
if (_serialPort1 != nullptr)
{
auto _this = this;
concurrency::create_task(WriteToSerialDeviceAsync(cancellationTokenSource_serialPort1->get_token(),
Arduino_Device.Outgoing_Bytes, PORT_1)).then([_this](concurrency::task<void> previousTask) {
try
{
previousTask.get();
}
catch (Platform::COMException^ ex)
{
_this->DataStreamWindow->Text += "\r\n!EXCEPTION CAUGHT! " + ex->Message;
}
});
}
Hope this is of use.
If so then why copying outside the task? You could do
if (_serialPort1 != nullptr)
{ concurrency::create_task(WriteToSerialDeviceAsync(cancellationTokenSource_serialPort1->get_token(),
Arduino_Device.Outgoing_Bytes, PORT_1)).then([_this = this](concurrency::task<void> previousTask) {
try
{
previousTask.get();
}
catch (Platform::COMException^ ex)
{
_this->DataStreamWindow->Text += "\r\n!EXCEPTION CAUGHT! " + ex->Message;
}
});
}
But based on your problem this is not the proper solution. You better find what's wrong with your project migration to VS 2019.

Is it possible to execute some code when visual studio enters break mode?

I have a large proces that I need to debug and the proces could stop at anytime. I have configured Visual Studio 2017, to stop at any thrown exception, as in, even if it is handled, because I want to see what caused the exception. What I need is some sort of alarm when this happens, so that I can leave the program to run and then alert me if anything comes up. The only thing I have found is an alarm sound when a break point is hit, but it might not be a break point and I need more than a sound, I need to be able to execute some code, so that I can make my Phone go nuts or whatever. Is there any way I can trigger code when the debugger enters break mode?
Thanks in advance.
It is, using a VS package. You'll need to add this attribute on top of the class in order for code to run on package startup:
[ProvideAutoLoad(Microsoft.VisualStudio.Shell.Interop.UIContextGuids80.SolutionExists)] ///Able to run code on solution startup
Add these class values variables:
private DTE2 applicationObject;
private BuildEvents buildEvents;
private DebuggerEvents debugEvents;
then the following code can run:
protected override void Initialize()
{
base.Initialize();
applicationObject = (DTE2)GetService(typeof(DTE));
buildEvents = applicationObject.Events.BuildEvents;
debugEvents = applicationObject.Events.DebuggerEvents;
SetupEventHandlers();
}
And finally the code we have "all" being waiting for:
private void SetupEventHandlers()
{
//buildEvents.OnBuildDone += (scope, action) =>
//{
//};
debugEvents.OnEnterBreakMode += delegate (dbgEventReason reason, ref dbgExecutionAction action)
{
};
//var componentModel =
// GetGlobalService(typeof(SComponentModel)) as IComponentModel;
//if (componentModel == null)
//{
// Debug.WriteLine("componentModel is null");
// return;
//}
//var operationState = componentModel.GetService<IOperationState>();
//operationState.StateChanged += OperationStateOnStateChanged;
}

Requesting Android permissions in a class (Xamarin)

I'm trying to request a permission at runtime for my app. I use a service provider to talk between the portable class and Android.
I start by calling this code on button press in the PCL:
using (new Busy(this))
{
var locationHelper = scope.Resolve<ILocationHelper>();
locationHelper.GetLocation(this);
}
This calls my Android level service:
public class AndroidLocationHelper : ILocationHelper, ILocationListener
{
readonly string[] PermissionsLocation =
{
Manifest.Permission.AccessCoarseLocation
};
const int RequestLocationId = 0;
public void GetLocation(SearchViewModel viewModel)
{
try
{
const string permission = Manifest.Permission.AccessCoarseLocation;
if (((int)Build.VERSION.SdkInt < 23) || (CheckSelfPermission(permission) == Permission.Granted))
{
}
else
RequestPermissions(PermissionsLocation, RequestLocationId);
}
catch (Exception ex)
{
Debug.WriteLine("Error while getting Location service");
Debug.WriteLine(ex.Message);
Messaging.AlertUser("There was an error with determining your location");
}
}
However, I get two errors on CheckSelfPermission and RequestPermissions. These two methods are only available to activities. The code works fine in MainActivity; however, I want to ask for permissions when the user hits a button, not in OnCreate or OnResume, etc.
Thanks for any help.
In your Android project, You can use this and use the Dependency Service to call it in Xamarin.Forms PCL project later:
var thisActivity = Forms.Context as Activity;
ActivityCompat.RequestPermissions(thisActivity, new string[] {
Manifest.Permission.AccessFineLocation }, 1);
ActivityCompat.RequestPermissions(thisActivity,
new String[] { Manifest.Permission.AccessFineLocation },
1);
You can try with ContextCompat.CheckSelfPermission, passing the application context, like this:
ContextCompat.CheckSelfPermission(Android.App.Application.Context, permission)
Update
In case of ActivityCompat.RequestPermissions, which requires an activity reference, you can keep track of the current activity. There is a very handy lib for that, called "CurrentActivityPlugin". You can find at https://github.com/jamesmontemagno/CurrentActivityPlugin
Rafael came up with a solution but I found another option that is a lot less effort just using MessagingCenter. In the MainActivity's OnCreate add a receiver that runs all the location code, that way you have access to all of the activities methods (and there are a bunch of tutorials on doing location services in MainActivity). Then add the Send inside of your service (the class).
To expound Rafael Steil's answer, I tried the suggested CurrentActivityPlugin and it worked on me. In my case I am trying to execute a voice call which needs CALL_PHONE permission. Here is the code snippet in your case: I used the ContextCompat & ActivityCompat so that I don't need to check the VERSION.SdkInt
using Plugin.CurrentActivity;
public void GetLocation(SearchViewModel viewModel){
var context = CrossCurrentActivity.Current.AppContext;
var activity = CrossCurrentActivity.Current.Activity;
int YOUR_ASSIGNED_REQUEST_CODE = 9;
if (ContextCompat.CheckSelfPermission(context, Manifest.Permission.AccessCoarseLocation) == (int)Android.Content.PM.Permission.Granted)
{
//Permission is granted, execute stuff
}
else
{
ActivityCompat.RequestPermissions(activity, new string[] { Manifest.Permission.AccessCoarseLocation }, YOUR_ASSIGNED_REQUEST_CODE);
}
}
It's dead simple
public bool CheckPermission()
{
const string permission = Manifest.Permission.ReceiveSms;
return ContextCompat.CheckSelfPermission(Forms.Context, permission) == (int) Permission.Granted;
}

visual studio installer does not delete all file in uninstall

I am using visual studio installer.
but when uninstalling - from add remove program it does not delete all files but leaves the folder with some files, how can I cause the uninstall delete all files?
The installer only removes the files it installed. The files created the post installation are not removed. You must create a custom action to perform the cleanup.
To clean up after your software (delete some custom or user generated files), you should create a Custom Action and add it to the Uninstall section of your installer.
A custom action can be a Class Library that inherits from the System.Configuration.Install.Installer class.
Here's a sample implementation of the Uninstaller Custom Action:
[RunInstaller(true)]
public partial class CustomUninstaller : System.Configuration.Install.Installer
{
public CustomUninstaller()
{
InitializeComponent();
}
public override void Uninstall(IDictionary savedState)
{
if (savedState != null)
{
base.Uninstall(savedState);
}
string targetDir = #"C:\Your\Installation\Path";
string tempDir = Path.Combine(targetDir, "temp");
try
{
// delete temp files (you can as well delete all files: "*.*")
foreach (FileInfo f in new DirectoryInfo(targetDir).GetFiles("*.tmp"))
{
f.Delete();
}
// delete entire temp folder
if (Directory.Exists(tempDir))
{
Directory.Delete(tempDir, true);
}
}
catch (Exception ex)
{
// TODO: Handle exceptions here
}
}
}

File being used by another process in a Windows Service with a StreamReader

I have searched numerous articles and tried several different ways of solving this issue.
Note that this process works fine in a Console app or a Windows app with the exact same code. So, there's nothing wrong with the logic. It's the way the Windows Service is processing these files that is somehow not letting subsequent files get through.
I tried reading a simple article to actually debug the service, but I don't have the "Attach To Process" selection under my Debug menu using Visual Studio 2010.
http://msdn.microsoft.com/en-us/library/7a50syb3(v=vs.100).aspx
I really need some help here, because my options have really run out.
Here is the simple scenario:
I have a FileSystemWatcher in the OnStart method that kicks off another method to process a file on my local machine. These are just simple txt files. When the first file is processed, everything is normal and I get the following in my Event log:
Data successfully inserted for file 20121212_AZM_Journey_MIS.txt
When I try and process subsequent files (exact same format, but a different name --- with the date), I get the following in my Event log:
The process cannot access the file 'C:\Projects\Data\VendingStats\20121213_AZM_Journey_MIS.txt' because it is being used by another process.
Note that the files are watched for in this same directory when created.
Here is my code in my Windows Service. Can someone please let me know how I can solve this issue? Note that e.FullPath evaluates to "C:\Projects\Data\VendingStats" on my local machine.
public partial class VendingStatsService : ServiceBase
{
public VendingStatsService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
FileSystemWatcher Watcher = new FileSystemWatcher(#"C:\Projects\Data\VendingStats");
Watcher.EnableRaisingEvents = true;
Watcher.Created += new FileSystemEventHandler(**Watcher_Created**);
Watcher.Filter = "*.txt";
Watcher.IncludeSubdirectories = false;
}
private void Watcher_Created(object sender, FileSystemEventArgs e)
{
try
{
using (TextReader tr = new StreamReader(e.FullPath))
{
// code here to insert data from file into a DB
}
Dispose();
}
catch (Exception ex)
{
EventLog.WriteEntry("VendorStats", "Error in the Main:" + "\r\n\r\n" + ex.Message + "\r\n\r\n" + ex.InnerException);
return;
}
}
public void Dispose()
{
GC.Collect();
}

Resources