title: Silent Dropbox removal
body: <p>I use the following script in <a href="http://code.google.com/p/windows-package-manager/" rel="nofollow">Npackd</a> to uninstall Dropbox. It works on XP and Vista, but fails on Windows 7/64. Instead of showing the taskbar (the one that is normally at the bottom of the screen) it shows a Windows Explorer window with the content of C:/. This is not Dropbox related as removing other packages with DLL based shell extensions also shows the same effect.</p>
  
  <pre><code>Uninstall.exe /S _?=%CD%
  taskkill /f /fi "IMAGENAME eq explorer.exe"
  del DropboxExt.13.dll
  del DropboxExt64.13.dll
  rem start explorer from the root directory so it does not lock this one
  start "" /D\ explorer.exe
  </code></pre>
  
  <p>What is wrong with the script? How can it be modified to work correctly on Windows 7 too?</p>
  
  <p>Thanks</p>
  
  <p>EDIT: I am really tired of this problem. The following batch file works either started as a normal user or "As Administrator":</p>
  
  <pre><code>taskkill /f /fi "IMAGENAME eq explorer.exe"
  ping -n 5 127.0.0.1
  pushd \
  rem runas /trustlevel:0x20000 
  start "" /D\ explorer.exe
  popd
  </code></pre>
  
  <p>Here is the code that starts the .bat from my program (path="Uninstall.bat", only 2 new environment variables are defined):</p>
  
  <pre><code>QDir d = this-&gt;getDirectory();
  QProcess p(0);
  p.setProcessChannelMode(QProcess::MergedChannels);
  QStringList params;
  p.setWorkingDirectory(d.absolutePath());
  QString exe = d.absolutePath() + "\\" + path;
  for (int i = 0; i &lt; env.count(); i += 2) {
      p.processEnvironment().insert(env.at(i), env.at(i + 1));
  }
  p.start(exe, params);
  </code></pre>
  
  <p>The corresponding code in Qt/qprocess_win.cpp:</p>
  
  <pre><code>DWORD dwCreationFlags = CREATE_NO_WINDOW;
  dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
  STARTUPINFOW startupInfo = { sizeof( STARTUPINFO ), 0, 0, 0,
                               (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT,
                               (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT,
                               0, 0, 0,
                               STARTF_USESTDHANDLES,
                               0, 0, 0,
                               stdinChannel.pipe[0], stdoutChannel.pipe[1], stderrChannel.pipe[1]
  };
  success = CreateProcess(0, (wchar_t*)args.utf16(),
                          0, 0, TRUE, dwCreationFlags,
                          environment.isEmpty() ? 0 : envlist.data(),
                          workingDirectory.isEmpty() ? 0 : (wchar_t*)QDir::toNativeSeparators(workingDirectory).utf16(),
                          &amp;startupInfo, pid);
  </code></pre>
  
  <p>Why does the Explorer think there is already a taskbar?</p>
  
  <p>EDIT2: I know what is wrong now. After the Explorer is killed a new is automatically started by an svchost.exe process with the following parameters: /factory,{682159d9-c321-47ca-b3f1-30e36b2ec8b9}. The GUID is for DesktopExplorerFactory. This is probably a crash-protection for a COM service. My calls to explorer.exe do not start a new Explorer as there is already one. After a minute or two this process will be automatically closed if no windows are opened. So I think Ben Voigt is right and "There's really no good way to unload the shell completely without logging off all users."</p>